]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' into experimental
authorAlex Chapman <chapman.alex@gmail.com>
Tue, 14 Apr 2009 00:42:41 +0000 (10:42 +1000)
committerAlex Chapman <chapman.alex@gmail.com>
Tue, 14 Apr 2009 00:42:41 +0000 (10:42 +1000)
Conflicts:
basis/http/client/client.factor

1103 files changed:
Factor.app/Contents/Frameworks/libfreetype.6.dylib [deleted file]
Makefile
README.txt
basis/alien/c-types/c-types-docs.factor
basis/alien/c-types/c-types-tests.factor
basis/alien/c-types/c-types.factor
basis/alien/destructors/destructors-docs.factor [new file with mode: 0644]
basis/alien/destructors/destructors.factor [changed mode: 0644->0755]
basis/alien/fortran/fortran-docs.factor
basis/alien/fortran/fortran.factor
basis/alien/libraries/authors.txt [new file with mode: 0644]
basis/alien/libraries/libraries-docs.factor [new file with mode: 0644]
basis/alien/libraries/libraries.factor [new file with mode: 0644]
basis/alien/structs/fields/fields.factor
basis/alien/structs/structs-tests.factor
basis/alien/structs/structs.factor
basis/alien/syntax/syntax.factor
basis/alien/syntax/tags.txt [new file with mode: 0644]
basis/assoc-heaps/assoc-heaps-docs.factor [deleted file]
basis/assoc-heaps/assoc-heaps-tests.factor [deleted file]
basis/assoc-heaps/assoc-heaps.factor [deleted file]
basis/assoc-heaps/authors.txt [deleted file]
basis/assoc-heaps/summary.txt [deleted file]
basis/base64/base64-tests.factor
basis/base64/base64.factor
basis/binary-search/binary-search-docs.factor
basis/binary-search/binary-search.factor
basis/bit-arrays/bit-arrays.factor
basis/bit-vectors/bit-vectors-tests.factor
basis/bit-vectors/bit-vectors.factor
basis/bootstrap/help/help.factor
basis/bootstrap/image/image.factor
basis/bootstrap/stage2.factor
basis/bootstrap/tools/tools.factor
basis/bootstrap/ui/ui.factor
basis/byte-vectors/byte-vectors-tests.factor
basis/byte-vectors/byte-vectors.factor
basis/cairo/ffi/ffi.factor
basis/calendar/calendar-docs.factor
basis/calendar/calendar-tests.factor
basis/calendar/calendar.factor
basis/calendar/format/format.factor
basis/call/call-docs.factor [deleted file]
basis/call/call-tests.factor [deleted file]
basis/call/call.factor [deleted file]
basis/call/summary.txt [deleted file]
basis/cocoa/application/application.factor
basis/cocoa/cocoa-tests.factor
basis/cocoa/cocoa.factor
basis/cocoa/messages/messages.factor
basis/cocoa/subclassing/subclassing.factor
basis/cocoa/views/views.factor
basis/colors/colors-docs.factor
basis/colors/constants/constants.factor
basis/combinators/short-circuit/smart/tags.txt [new file with mode: 0644]
basis/combinators/short-circuit/tags.txt [new file with mode: 0644]
basis/combinators/smart/smart-docs.factor
basis/combinators/smart/smart.factor
basis/combinators/smart/tags.txt [new file with mode: 0644]
basis/command-line/command-line.factor
basis/compiler/cfg/instructions/syntax/syntax.factor
basis/compiler/cfg/linear-scan/allocation/allocation.factor
basis/compiler/cfg/registers/registers.factor
basis/compiler/codegen/codegen.factor
basis/compiler/codegen/fixup/fixup.factor
basis/compiler/compiler-docs.factor
basis/compiler/compiler.factor
basis/compiler/constants/constants.factor
basis/compiler/tests/alien.factor [changed mode: 0644->0755]
basis/compiler/tests/intrinsics.factor
basis/compiler/tests/optimizer.factor
basis/compiler/tests/redefine15.factor [new file with mode: 0644]
basis/compiler/tests/redefine2.factor
basis/compiler/tests/stack-trace.factor
basis/compiler/tree/cleanup/cleanup-tests.factor
basis/compiler/tree/debugger/debugger-tests.factor
basis/compiler/tree/debugger/debugger.factor
basis/compiler/tree/propagation/info/info.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/tree/propagation/known-words/known-words.factor
basis/compression/zlib/ffi/ffi.factor
basis/concurrency/conditions/conditions.factor
basis/concurrency/mailboxes/mailboxes-tests.factor
basis/concurrency/mailboxes/mailboxes.factor
basis/constructors/constructors.factor
basis/core-foundation/fsevents/fsevents.factor
basis/core-foundation/strings/strings.factor
basis/core-graphics/core-graphics-docs.factor [deleted file]
basis/core-text/utilities/utilities.factor
basis/cpu/ppc/assembler/backend/backend.factor
basis/cpu/ppc/bootstrap.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/32/32.factor
basis/cpu/x86/assembler/syntax/syntax.factor
basis/cpu/x86/bootstrap.factor
basis/db/db-docs.factor
basis/db/db.factor
basis/db/errors/sqlite/sqlite.factor
basis/db/postgresql/ffi/ffi.factor
basis/db/queries/queries.factor
basis/db/sqlite/ffi/ffi.factor
basis/db/tuples/tuples-tests.factor
basis/debugger/debugger-docs.factor
basis/debugger/debugger.factor
basis/definitions/icons/icons-docs.factor [new file with mode: 0644]
basis/definitions/icons/icons.factor
basis/delegate/delegate-tests.factor
basis/delegate/delegate.factor
basis/delegate/protocols/protocols.factor
basis/documents/elements/elements-tests.factor
basis/documents/elements/elements.factor
basis/editors/editors-docs.factor
basis/editors/editors.factor
basis/editors/notepad/tags.txt [new file with mode: 0644]
basis/environment/environment-docs.factor
basis/eval/eval.factor
basis/farkup/authors.txt
basis/farkup/farkup-docs.factor
basis/farkup/farkup-tests.factor
basis/farkup/farkup.factor [changed mode: 0755->0644]
basis/fry/fry-tests.factor
basis/fry/fry.factor
basis/functors/functors-tests.factor
basis/functors/functors.factor
basis/furnace/actions/actions-docs.factor
basis/furnace/actions/actions-tests.factor
basis/furnace/actions/actions.factor
basis/furnace/auth/login/login.factor
basis/furnace/boilerplate/boilerplate.factor
basis/furnace/furnace-tests.factor
basis/furnace/furnace.factor
basis/furnace/redirection/redirection.factor
basis/furnace/referrer/referrer.factor
basis/furnace/sessions/sessions-tests.factor
basis/furnace/utilities/utilities.factor
basis/generalizations/generalizations-docs.factor
basis/glib/glib.factor
basis/globs/authors.txt
basis/grouping/grouping-docs.factor
basis/hash2/hash2-tests.factor
basis/help/apropos/apropos-docs.factor [new file with mode: 0644]
basis/help/apropos/apropos-tests.factor [new file with mode: 0644]
basis/help/apropos/apropos.factor [new file with mode: 0644]
basis/help/cookbook/cookbook.factor
basis/help/crossref/crossref-docs.factor
basis/help/crossref/crossref-tests.factor
basis/help/definitions/definitions-tests.factor
basis/help/handbook/handbook.factor
basis/help/help-docs.factor
basis/help/help.factor
basis/help/home/authors.txt [new file with mode: 0644]
basis/help/home/home-docs.factor [new file with mode: 0644]
basis/help/home/home.factor [new file with mode: 0644]
basis/help/html/html.factor
basis/help/lint/lint.factor
basis/help/markup/markup-tests.factor
basis/help/markup/markup.factor
basis/help/syntax/syntax.factor
basis/help/syntax/tags.txt [new file with mode: 0644]
basis/help/tips/authors.txt [new file with mode: 0644]
basis/help/tips/tips-docs.factor [new file with mode: 0644]
basis/help/tips/tips.factor [new file with mode: 0644]
basis/help/topics/topics.factor
basis/help/tutorial/tutorial.factor
basis/help/vocabs/authors.txt [new file with mode: 0755]
basis/help/vocabs/summary.txt [new file with mode: 0644]
basis/help/vocabs/tags.txt [new file with mode: 0644]
basis/help/vocabs/vocabs-docs.factor [new file with mode: 0644]
basis/help/vocabs/vocabs-tests.factor [new file with mode: 0644]
basis/help/vocabs/vocabs.factor [new file with mode: 0644]
basis/hints/hints.factor
basis/html/components/components-tests.factor
basis/html/forms/forms.factor
basis/html/streams/streams-tests.factor
basis/html/templates/chloe/chloe-tests.factor
basis/html/templates/chloe/chloe.factor
basis/html/templates/chloe/compiler/compiler.factor
basis/html/templates/chloe/components/components.factor
basis/html/templates/chloe/syntax/syntax.factor
basis/html/templates/fhtml/fhtml.factor
basis/html/templates/templates.factor
basis/http/client/client.factor
basis/http/http-tests.factor
basis/http/http.factor
basis/http/server/server.factor
basis/http/server/static/static-docs.factor
basis/http/server/static/static.factor
basis/images/bitmap/bitmap-tests.factor
basis/images/bitmap/bitmap.factor
basis/images/images.factor [changed mode: 0644->0755]
basis/images/loader/loader.factor
basis/images/png/png.factor
basis/images/tesselation/authors.txt [new file with mode: 0644]
basis/images/tesselation/tesselation-tests.factor [new file with mode: 0644]
basis/images/tesselation/tesselation.factor [new file with mode: 0644]
basis/images/test-images/40red24bit.bmp [new file with mode: 0644]
basis/images/test-images/41red24bit.bmp [new file with mode: 0644]
basis/images/test-images/42red24bit.bmp [new file with mode: 0644]
basis/images/test-images/43red24bit.bmp [new file with mode: 0644]
basis/images/test-images/elephants.tiff [new file with mode: 0644]
basis/images/tiff/tiff.factor
basis/interpolate/interpolate.factor
basis/interpolate/tags.txt [new file with mode: 0644]
basis/interval-maps/interval-maps-docs.factor
basis/interval-maps/interval-maps.factor
basis/inverse/inverse.factor
basis/io/backend/unix/unix-tests.factor
basis/io/directories/search/search-tests.factor
basis/io/directories/search/search.factor
basis/io/encodings/ascii/ascii.factor
basis/io/encodings/euc/euc.factor
basis/io/encodings/iana/iana-docs.factor
basis/io/encodings/iana/iana-tests.factor
basis/io/encodings/iana/iana.factor
basis/io/encodings/iso2022/201.txt [new file with mode: 0644]
basis/io/encodings/iso2022/208.txt [new file with mode: 0644]
basis/io/encodings/iso2022/212.txt [new file with mode: 0644]
basis/io/encodings/iso2022/authors.txt [new file with mode: 0644]
basis/io/encodings/iso2022/iso2022-docs.factor [new file with mode: 0644]
basis/io/encodings/iso2022/iso2022-tests.factor [new file with mode: 0644]
basis/io/encodings/iso2022/iso2022.factor [new file with mode: 0644]
basis/io/encodings/iso2022/summary.txt [new file with mode: 0644]
basis/io/encodings/strict/strict-docs.factor
basis/io/encodings/utf16n/utf16n-tests.factor
basis/io/files/unique/unique-docs.factor
basis/io/files/unique/unique.factor
basis/io/pipes/pipes.factor
basis/io/ports/ports.factor
basis/io/servers/connection/connection.factor
basis/io/sockets/secure/unix/debug/debug.factor
basis/io/streams/byte-array/byte-array-tests.factor
basis/io/streams/byte-array/byte-array.factor
basis/io/streams/duplex/duplex-tests.factor
basis/io/streams/duplex/duplex.factor
basis/io/streams/limited/limited-docs.factor
basis/io/streams/limited/limited-tests.factor
basis/io/streams/limited/limited.factor
basis/io/streams/memory/memory.factor
basis/io/streams/string/string.factor
basis/io/styles/styles.factor
basis/listener/listener-tests.factor
basis/listener/listener.factor
basis/lists/lazy/lazy-docs.factor
basis/lists/lazy/lazy.factor
basis/lists/lists-docs.factor
basis/locals/locals-docs.factor
basis/locals/locals-tests.factor
basis/locals/locals.factor
basis/locals/macros/macros.factor
basis/locals/parser/parser.factor
basis/logging/analysis/analysis.factor
basis/logging/logging.factor
basis/macros/expander/expander.factor
basis/macros/macros-tests.factor
basis/macros/macros.factor
basis/match/match.factor
basis/math/bitwise/bitwise-docs.factor
basis/math/bitwise/bitwise.factor
basis/math/blas/config/config-docs.factor [new file with mode: 0644]
basis/math/blas/config/config.factor [new file with mode: 0644]
basis/math/blas/ffi/ffi.factor
basis/math/blas/matrices/matrices-docs.factor
basis/math/blas/matrices/matrices.factor
basis/math/blas/vectors/vectors.factor
basis/math/complex/complex.factor
basis/math/functions/functions-docs.factor
basis/math/functions/functions-tests.factor
basis/math/functions/functions.factor
basis/math/partial-dispatch/partial-dispatch-tests.factor
basis/math/partial-dispatch/partial-dispatch.factor
basis/math/primes/factors/factors.factor
basis/math/ranges/ranges-docs.factor
basis/memoize/memoize-docs.factor
basis/memoize/memoize.factor
basis/models/arrow/arrow.factor
basis/models/arrow/smart/smart-docs.factor [new file with mode: 0644]
basis/models/history/history-docs.factor [deleted file]
basis/models/history/history-tests.factor [deleted file]
basis/models/history/history.factor [deleted file]
basis/models/history/summary.txt [deleted file]
basis/models/models-docs.factor
basis/models/models-tests.factor
basis/models/range/range-tests.factor
basis/multiline/multiline.factor
basis/nibble-arrays/nibble-arrays.factor
basis/opengl/authors.txt
basis/opengl/capabilities/capabilities.factor
basis/opengl/gl/authors.txt
basis/opengl/gl/extensions/extensions.factor
basis/opengl/gl/macosx/macosx.factor
basis/opengl/glu/authors.txt [deleted file]
basis/opengl/glu/glu.factor [deleted file]
basis/opengl/glu/summary.txt [deleted file]
basis/opengl/glu/tags.txt [deleted file]
basis/opengl/opengl-docs.factor
basis/opengl/opengl.factor
basis/opengl/textures/textures-tests.factor
basis/opengl/textures/textures.factor [changed mode: 0644->0755]
basis/openssl/libcrypto/libcrypto.factor
basis/openssl/libssl/libssl.factor
basis/pack/pack.factor
basis/pango/cairo/cairo.factor
basis/pango/pango.factor
basis/peg/ebnf/ebnf-tests.factor
basis/peg/ebnf/ebnf.factor
basis/peg/ebnf/tags.txt
basis/peg/parsers/parsers.factor
basis/peg/peg-tests.factor
basis/peg/peg.factor
basis/peg/search/search-tests.factor
basis/persistent/hashtables/hashtables.factor
basis/persistent/heaps/heaps-tests.factor
basis/persistent/vectors/vectors.factor
basis/prettyprint/backend/backend.factor
basis/prettyprint/prettyprint-docs.factor
basis/prettyprint/prettyprint-tests.factor
basis/prettyprint/prettyprint.factor
basis/promises/authors.txt [new file with mode: 0644]
basis/promises/promises-docs.factor [new file with mode: 0755]
basis/promises/promises-tests.factor [new file with mode: 0644]
basis/promises/promises.factor [new file with mode: 0755]
basis/promises/summary.txt [new file with mode: 0644]
basis/promises/tags.txt [new file with mode: 0644]
basis/quoting/quoting-docs.factor [deleted file]
basis/quoting/quoting-tests.factor
basis/quoting/quoting.factor
basis/refs/refs-docs.factor
basis/refs/refs.factor
basis/regexp/ast/ast.factor
basis/regexp/authors.txt
basis/regexp/classes/classes.factor
basis/regexp/combinators/combinators-docs.factor
basis/regexp/combinators/combinators.factor
basis/regexp/compiler/compiler.factor
basis/regexp/dfa/dfa.factor
basis/regexp/disambiguate/disambiguate.factor
basis/regexp/nfa/nfa.factor
basis/regexp/parser/parser-tests.factor
basis/regexp/parser/parser.factor
basis/regexp/prettyprint/authors.txt [new file with mode: 0644]
basis/regexp/prettyprint/prettyprint.factor [new file with mode: 0644]
basis/regexp/regexp-docs.factor
basis/regexp/regexp-tests.factor
basis/regexp/regexp.factor
basis/regexp/transition-tables/transition-tables.factor
basis/roman/roman-docs.factor
basis/roman/roman-tests.factor
basis/roman/roman.factor
basis/see/see-docs.factor
basis/see/see-tests.factor [new file with mode: 0644]
basis/see/see.factor
basis/serialize/serialize-tests.factor
basis/shuffle/shuffle.factor
basis/simple-flat-file/simple-flat-file-docs.factor
basis/simple-flat-file/simple-flat-file.factor
basis/smtp/smtp-docs.factor
basis/sorting/functor/authors.txt [new file with mode: 0644]
basis/sorting/functor/functor.factor [new file with mode: 0644]
basis/sorting/human/human-docs.factor
basis/sorting/human/human-tests.factor
basis/sorting/human/human.factor
basis/sorting/slots/slots-docs.factor
basis/sorting/slots/slots-tests.factor
basis/sorting/slots/slots.factor
basis/sorting/title/authors.txt [new file with mode: 0644]
basis/sorting/title/title-tests.factor [new file with mode: 0644]
basis/sorting/title/title.factor [new file with mode: 0644]
basis/specialized-arrays/functor/functor.factor
basis/specialized-vectors/functor/functor.factor
basis/specialized-vectors/specialized-vectors-tests.factor
basis/stack-checker/alien/alien.factor
basis/stack-checker/call-effect/authors.txt [new file with mode: 0644]
basis/stack-checker/call-effect/call-effect-tests.factor [new file with mode: 0644]
basis/stack-checker/call-effect/call-effect.factor [new file with mode: 0644]
basis/stack-checker/errors/errors.factor
basis/stack-checker/known-words/known-words.factor
basis/stack-checker/stack-checker-docs.factor
basis/stack-checker/stack-checker-tests.factor
basis/stack-checker/stack-checker.factor
basis/stack-checker/transforms/authors.txt
basis/stack-checker/transforms/transforms-tests.factor
basis/stack-checker/transforms/transforms.factor
basis/suffix-arrays/suffix-arrays.factor
basis/syndication/syndication-docs.factor
basis/syndication/syndication-tests.factor
basis/syndication/syndication.factor
basis/threads/threads.factor
basis/tools/annotations/annotations-tests.factor
basis/tools/annotations/annotations.factor
basis/tools/apropos/apropos-docs.factor [deleted file]
basis/tools/apropos/apropos-tests.factor [deleted file]
basis/tools/apropos/apropos.factor [deleted file]
basis/tools/crossref/crossref-tests.factor
basis/tools/deploy/backend/backend.factor
basis/tools/deploy/deploy-docs.factor
basis/tools/deploy/deploy-tests.factor
basis/tools/deploy/macosx/macosx.factor
basis/tools/deploy/shaker/shaker.factor
basis/tools/deploy/shaker/strip-call.factor [new file with mode: 0644]
basis/tools/deploy/test/12/12.factor [new file with mode: 0644]
basis/tools/deploy/test/12/authors.txt [new file with mode: 0644]
basis/tools/deploy/test/12/deploy.factor [new file with mode: 0644]
basis/tools/deploy/test/13/13.factor [new file with mode: 0644]
basis/tools/deploy/test/13/authors.txt [new file with mode: 0644]
basis/tools/deploy/test/13/deploy.factor [new file with mode: 0644]
basis/tools/deploy/windows/windows.factor
basis/tools/disassembler/disassembler-tests.factor
basis/tools/disassembler/disassembler.factor [changed mode: 0644->0755]
basis/tools/disassembler/udis/udis.factor [changed mode: 0644->0755]
basis/tools/hexdump/hexdump.factor
basis/tools/profiler/profiler-tests.factor
basis/tools/scaffold/scaffold-docs.factor
basis/tools/scaffold/scaffold-tests.factor [new file with mode: 0644]
basis/tools/scaffold/scaffold.factor
basis/tools/test/test.factor
basis/tools/test/ui/authors.txt [deleted file]
basis/tools/test/ui/ui.factor [deleted file]
basis/tools/vocabs/browser/authors.txt [deleted file]
basis/tools/vocabs/browser/browser-docs.factor [deleted file]
basis/tools/vocabs/browser/browser-tests.factor [deleted file]
basis/tools/vocabs/browser/browser.factor [deleted file]
basis/tools/vocabs/browser/summary.txt [deleted file]
basis/tools/vocabs/browser/tags.txt [deleted file]
basis/tools/walker/walker-tests.factor
basis/tools/walker/walker.factor
basis/tr/tr.factor
basis/ui/backend/backend.factor
basis/ui/backend/cocoa/cocoa.factor
basis/ui/backend/cocoa/views/views.factor
basis/ui/backend/windows/windows.factor
basis/ui/backend/x11/x11.factor
basis/ui/commands/commands-docs.factor
basis/ui/commands/commands.factor
basis/ui/gadgets/buttons/buttons-docs.factor
basis/ui/gadgets/buttons/buttons-tests.factor
basis/ui/gadgets/buttons/buttons.factor
basis/ui/gadgets/corners/authors.txt [new file with mode: 0644]
basis/ui/gadgets/corners/corners.factor [new file with mode: 0644]
basis/ui/gadgets/debug/debug.factor
basis/ui/gadgets/editors/editors-docs.factor
basis/ui/gadgets/editors/editors-tests.factor
basis/ui/gadgets/editors/editors.factor
basis/ui/gadgets/gadgets-tests.factor
basis/ui/gadgets/gadgets.factor
basis/ui/gadgets/glass/glass.factor
basis/ui/gadgets/grids/grids-tests.factor
basis/ui/gadgets/grids/grids.factor
basis/ui/gadgets/labeled/labeled-tests.factor [new file with mode: 0644]
basis/ui/gadgets/labeled/labeled.factor
basis/ui/gadgets/line-support/line-support.factor
basis/ui/gadgets/menus/menus.factor
basis/ui/gadgets/panes/panes-tests.factor
basis/ui/gadgets/panes/panes.factor
basis/ui/gadgets/scrollers/scrollers-docs.factor
basis/ui/gadgets/scrollers/scrollers-tests.factor
basis/ui/gadgets/scrollers/scrollers.factor
basis/ui/gadgets/search-tables/search-tables-tests.factor [new file with mode: 0644]
basis/ui/gadgets/search-tables/search-tables.factor
basis/ui/gadgets/tables/tables.factor
basis/ui/gadgets/theme/menu-background-bottom-left.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-bottom-middle.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-bottom-right.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-left-edge.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-right-edge.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-top-left.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-top-middle.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/menu-background-top-right.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-bottom-left.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-bottom-middle.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-bottom-right.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-left-edge.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-right-edge.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-top-left.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-top-middle.tiff [new file with mode: 0644]
basis/ui/gadgets/theme/selected-menu-item-background-top-right.tiff [new file with mode: 0644]
basis/ui/gadgets/viewports/viewports.factor
basis/ui/gadgets/worlds/worlds.factor
basis/ui/gestures/gestures.factor
basis/ui/images/images.factor [changed mode: 0644->0755]
basis/ui/operations/operations-tests.factor
basis/ui/operations/operations.factor
basis/ui/pens/solid/solid.factor
basis/ui/render/render.factor
basis/ui/text/core-text/core-text.factor [changed mode: 0644->0755]
basis/ui/text/pango/pango.factor
basis/ui/text/pango/summary.txt [new file with mode: 0755]
basis/ui/text/text-tests.factor [changed mode: 0644->0755]
basis/ui/text/text.factor [changed mode: 0644->0755]
basis/ui/text/uniscribe/authors.txt [new file with mode: 0755]
basis/ui/text/uniscribe/summary.txt [new file with mode: 0755]
basis/ui/text/uniscribe/tags.txt [new file with mode: 0755]
basis/ui/text/uniscribe/uniscribe.factor [new file with mode: 0755]
basis/ui/tools/browser/browser-docs.factor
basis/ui/tools/browser/browser-tests.factor
basis/ui/tools/browser/browser.factor
basis/ui/tools/browser/history/authors.txt [new file with mode: 0644]
basis/ui/tools/browser/history/history-tests.factor [new file with mode: 0644]
basis/ui/tools/browser/history/history.factor [new file with mode: 0644]
basis/ui/tools/deploy/deploy-docs.factor
basis/ui/tools/listener/completion/completion.factor
basis/ui/tools/listener/listener-docs.factor
basis/ui/tools/listener/listener-tests.factor
basis/ui/tools/listener/listener.factor
basis/ui/tools/operations/operations-docs.factor [new file with mode: 0644]
basis/ui/tools/operations/operations.factor
basis/ui/tools/profiler/profiler-docs.factor [new file with mode: 0644]
basis/ui/tools/profiler/profiler.factor
basis/ui/tools/tools-docs.factor
basis/ui/tools/walker/walker.factor
basis/ui/traverse/traverse-docs.factor [new file with mode: 0644]
basis/ui/traverse/traverse-tests.factor
basis/ui/traverse/traverse.factor
basis/ui/ui.factor
basis/unicode/breaks/breaks-tests.factor
basis/unicode/breaks/breaks.factor
basis/unicode/case/case-tests.factor
basis/unicode/case/case.factor
basis/unicode/categories/categories-docs.factor
basis/unicode/categories/categories-tests.factor
basis/unicode/categories/categories.factor
basis/unicode/categories/syntax/authors.txt [new file with mode: 0755]
basis/unicode/categories/syntax/summary.txt [new file with mode: 0644]
basis/unicode/categories/syntax/syntax-docs.factor [new file with mode: 0644]
basis/unicode/categories/syntax/syntax-tests.factor [new file with mode: 0644]
basis/unicode/categories/syntax/syntax.factor [new file with mode: 0644]
basis/unicode/categories/syntax/tags.txt [new file with mode: 0755]
basis/unicode/collation/collation.factor
basis/unicode/data/data-docs.factor
basis/unicode/data/data.factor
basis/unicode/normalize/normalize-tests.factor
basis/unicode/normalize/normalize.factor
basis/unicode/script/script-docs.factor
basis/unicode/script/script.factor
basis/unicode/syntax/authors.txt [deleted file]
basis/unicode/syntax/summary.txt [deleted file]
basis/unicode/syntax/syntax.factor [deleted file]
basis/unicode/syntax/tags.txt [deleted file]
basis/unicode/unicode-docs.factor
basis/urls/encoding/encoding-tests.factor
basis/urls/encoding/encoding.factor
basis/urls/prettyprint/prettyprint.factor
basis/urls/urls-docs.factor
basis/urls/urls-tests.factor
basis/urls/urls.factor
basis/values/values-docs.factor
basis/values/values.factor
basis/vlists/vlists.factor
basis/windows/ce/ce.factor
basis/windows/com/syntax/syntax.factor
basis/windows/dinput/constants/constants.factor
basis/windows/dinput/dinput.factor
basis/windows/fonts/fonts.factor [new file with mode: 0755]
basis/windows/gdi32/gdi32.factor
basis/windows/nt/nt.factor
basis/windows/offscreen/authors.txt [new file with mode: 0644]
basis/windows/offscreen/offscreen-tests.factor [new file with mode: 0755]
basis/windows/offscreen/offscreen.factor [new file with mode: 0755]
basis/windows/offscreen/summary.txt [new file with mode: 0755]
basis/windows/offscreen/tags.txt [new file with mode: 0755]
basis/windows/types/types.factor
basis/windows/uniscribe/authors.txt [new file with mode: 0644]
basis/windows/uniscribe/summary.txt [new file with mode: 0755]
basis/windows/uniscribe/tags.txt [new file with mode: 0755]
basis/windows/uniscribe/uniscribe.factor [new file with mode: 0755]
basis/windows/usp10/authors.txt [new file with mode: 0755]
basis/windows/usp10/usp10.factor [new file with mode: 0755]
basis/windows/windows.factor [changed mode: 0644->0755]
basis/wrap/wrap.factor
basis/x11/clipboard/clipboard.factor
basis/x11/windows/windows.factor
basis/xml/autoencoding/autoencoding.factor
basis/xml/char-classes/char-classes.factor
basis/xml/errors/errors-tests.factor
basis/xml/errors/errors.factor
basis/xml/syntax/syntax.factor
basis/xml/syntax/tags.txt
basis/xml/tests/templating.factor
basis/xml/tests/test.factor
basis/xml/tests/xmltest.factor
basis/xml/traversal/traversal-docs.factor
basis/xml/writer/writer-tests.factor
basis/xml/xml-docs.factor
basis/xml/xml.factor
basis/xmode/code2html/code2html-tests.factor
basis/xmode/loader/syntax/syntax.factor
basis/xmode/marker/marker.factor
build-support/dlls.txt [deleted file]
build-support/factor.sh
core/alien/alien-docs.factor
core/alien/alien-tests.factor
core/alien/alien.factor
core/bootstrap/primitives.factor
core/bootstrap/syntax.factor
core/classes/builtin/builtin.factor
core/classes/classes.factor
core/classes/mixin/mixin-tests.factor
core/classes/mixin/mixin.factor
core/classes/predicate/predicate-tests.factor
core/classes/predicate/predicate.factor
core/classes/singleton/singleton-tests.factor
core/classes/tuple/parser/parser.factor
core/classes/tuple/tuple-docs.factor
core/classes/tuple/tuple-tests.factor
core/classes/tuple/tuple.factor
core/classes/union/union-tests.factor
core/combinators/authors.txt
core/combinators/combinators-docs.factor
core/combinators/combinators-tests.factor
core/combinators/combinators.factor
core/compiler/units/units-docs.factor
core/compiler/units/units-tests.factor
core/compiler/units/units.factor
core/continuations/continuations-docs.factor
core/continuations/continuations-tests.factor
core/continuations/continuations.factor
core/definitions/definitions-docs.factor
core/definitions/definitions-tests.factor
core/definitions/definitions.factor
core/destructors/destructors-tests.factor
core/effects/effects-docs.factor
core/effects/effects.factor
core/effects/parser/parser.factor
core/generic/generic-docs.factor
core/generic/generic-tests.factor
core/generic/generic.factor
core/generic/math/math-docs.factor
core/generic/math/math.factor
core/generic/parser/parser.factor
core/generic/standard/standard-docs.factor
core/generic/standard/standard-tests.factor
core/generic/standard/standard.factor
core/hashtables/hashtables.factor
core/init/init.factor
core/io/backend/backend.factor
core/io/encodings/encodings-docs.factor
core/io/encodings/encodings.factor
core/io/encodings/utf8/utf8-tests.factor
core/io/encodings/utf8/utf8.factor
core/io/io-docs.factor
core/io/io.factor
core/io/streams/c/c.factor
core/io/streams/null/null.factor
core/io/streams/sequence/sequence.factor
core/io/test/no-trailing-eol.factor
core/kernel/kernel-docs.factor
core/kernel/kernel-tests.factor
core/kernel/kernel.factor
core/math/math-docs.factor
core/math/order/order-docs.factor
core/memory/memory-tests.factor
core/namespaces/namespaces-docs.factor
core/namespaces/namespaces.factor
core/parser/parser-docs.factor
core/parser/parser-tests.factor
core/parser/parser.factor
core/quotations/quotations-docs.factor
core/sequences/sequences-docs.factor
core/sequences/sequences-tests.factor
core/sequences/sequences.factor
core/slots/slots-docs.factor
core/slots/slots.factor
core/strings/parser/parser.factor
core/strings/strings-docs.factor
core/strings/strings.factor
core/syntax/syntax-docs.factor
core/syntax/syntax.factor
core/vocabs/loader/loader-docs.factor
core/vocabs/loader/loader-tests.factor
core/vocabs/loader/loader.factor
core/vocabs/loader/test/d/d.factor
core/vocabs/parser/parser.factor
core/vocabs/vocabs-docs.factor
core/vocabs/vocabs.factor
core/words/alias/alias-tests.factor [new file with mode: 0644]
core/words/alias/alias.factor
core/words/constant/constant-tests.factor [new file with mode: 0644]
core/words/constant/constant.factor
core/words/symbol/symbol.factor
core/words/words-docs.factor
core/words/words-tests.factor
core/words/words.factor
extra/24-game/24-game.factor
extra/4DNav/4DNav.factor
extra/4DNav/camera/camera.factor
extra/4DNav/summary.txt
extra/adsoda/adsoda.factor
extra/advice/advice-tests.factor
extra/advice/advice.factor
extra/animations/animations-docs.factor
extra/animations/animations.factor
extra/annotations/annotations.factor
extra/assoc-heaps/assoc-heaps-docs.factor [new file with mode: 0644]
extra/assoc-heaps/assoc-heaps-tests.factor [new file with mode: 0644]
extra/assoc-heaps/assoc-heaps.factor [new file with mode: 0644]
extra/assoc-heaps/authors.txt [new file with mode: 0644]
extra/assoc-heaps/summary.txt [new file with mode: 0644]
extra/bank/bank.factor
extra/benchmark/benchmark.factor
extra/benchmark/fib6/deploy.factor [new file with mode: 0644]
extra/benchmark/regex-dna/deploy.factor [new file with mode: 0644]
extra/benchmark/regex-dna/regex-dna.factor
extra/benchmark/spectral-norm/spectral-norm.factor
extra/c/preprocessor/authors.txt [new file with mode: 0644]
extra/c/preprocessor/preprocessor-tests.factor [new file with mode: 0644]
extra/c/preprocessor/preprocessor.factor [new file with mode: 0644]
extra/c/tests/test1/README [new file with mode: 0644]
extra/c/tests/test1/hi.h [new file with mode: 0644]
extra/c/tests/test1/lo.h [new file with mode: 0644]
extra/c/tests/test1/test1.c [new file with mode: 0644]
extra/c/tests/test10/test10.c [new file with mode: 0644]
extra/c/tests/test11/foo.h [new file with mode: 0644]
extra/c/tests/test11/test11.c [new file with mode: 0644]
extra/c/tests/test12/test12.c [new file with mode: 0644]
extra/c/tests/test13/test13.c [new file with mode: 0644]
extra/c/tests/test14/test14.c [new file with mode: 0644]
extra/c/tests/test2/README [new file with mode: 0644]
extra/c/tests/test2/test2.c [new file with mode: 0644]
extra/c/tests/test3/README [new file with mode: 0644]
extra/c/tests/test3/test3.c [new file with mode: 0644]
extra/c/tests/test4/test4.c [new file with mode: 0644]
extra/c/tests/test5/test5.c [new file with mode: 0644]
extra/c/tests/test6/test6.c [new file with mode: 0644]
extra/c/tests/test7/test7.c [new file with mode: 0644]
extra/c/tests/test8/test8.c [new file with mode: 0644]
extra/c/tests/test9/test9.c [new file with mode: 0644]
extra/cap/cap.factor
extra/chess960/chess960.factor [new file with mode: 0644]
extra/chicago-talk/authors.txt [new file with mode: 0644]
extra/chicago-talk/chicago-talk.factor [new file with mode: 0644]
extra/chicago-talk/deploy.factor [new file with mode: 0755]
extra/chicago-talk/summary.txt [new file with mode: 0755]
extra/chicago-talk/tags.txt [new file with mode: 0644]
extra/color-picker/deploy.factor
extra/color-table/color-table.factor
extra/ctags/ctags-docs.factor
extra/ctags/ctags.factor
extra/ctags/etags/etags.factor
extra/curses/ffi/ffi.factor
extra/demos/demos.factor
extra/descriptive/descriptive-docs.factor
extra/descriptive/descriptive.factor
extra/descriptive/tags.txt [new file with mode: 0644]
extra/drills/drills.factor [new file with mode: 0644]
extra/drills/tags.txt [new file with mode: 0644]
extra/ecdsa/authors.txt [new file with mode: 0644]
extra/ecdsa/ecdsa-tests.factor [new file with mode: 0644]
extra/ecdsa/ecdsa.factor [new file with mode: 0644]
extra/ecdsa/summary.txt [new file with mode: 0644]
extra/ecdsa/tags.txt [new file with mode: 0644]
extra/fjsc/fjsc.factor
extra/freetype/freetype.factor
extra/fuel/help/help.factor
extra/galois-talk/galois-talk.factor
extra/game-input/dinput/dinput.factor
extra/game-input/game-input-tests.factor
extra/game-input/game-input.factor
extra/geo-ip/geo-ip.factor
extra/geobytes/authors.txt [new file with mode: 0644]
extra/geobytes/geobytes.factor [new file with mode: 0644]
extra/geobytes/summary.txt [new file with mode: 0644]
extra/geobytes/tags.txt [new file with mode: 0644]
extra/google-tech-talk/google-tech-talk.factor
extra/hello-unicode/deploy.factor [new file with mode: 0644]
extra/hello-unicode/hello-unicode.factor
extra/html/parser/analyzer/analyzer.factor
extra/html/parser/parser-tests.factor
extra/html/parser/parser.factor
extra/html/parser/state/state-tests.factor [deleted file]
extra/html/parser/state/state.factor [deleted file]
extra/html/parser/utils/utils-tests.factor
extra/html/parser/utils/utils.factor
extra/id3/id3-docs.factor
extra/id3/id3-tests.factor
extra/id3/id3.factor
extra/images/normalization/authors.txt [new file with mode: 0644]
extra/images/normalization/normalization.factor [new file with mode: 0755]
extra/infix/infix-tests.factor
extra/infix/infix.factor
extra/io/serial/unix/unix-tests.factor
extra/irc/client/client.factor
extra/lint/lint-tests.factor
extra/literals/literals-docs.factor
extra/literals/literals.factor
extra/mason/build/build.factor
extra/mason/child/child-tests.factor
extra/mason/child/child.factor [changed mode: 0644->0755]
extra/mason/report/report.factor
extra/mason/test/test.factor
extra/math/affine-transforms/affine-transforms-tests.factor
extra/math/affine-transforms/affine-transforms.factor
extra/math/analysis/analysis-tests.factor
extra/math/derivatives/syntax/syntax.factor
extra/math/matrices/matrices-tests.factor
extra/math/matrices/matrices.factor
extra/method-chains/authors.txt [new file with mode: 0644]
extra/method-chains/method-chains-tests.factor [new file with mode: 0644]
extra/method-chains/method-chains.factor [new file with mode: 0644]
extra/minneapolis-talk/deploy.factor
extra/minneapolis-talk/summary.txt
extra/models/history/history-docs.factor [new file with mode: 0644]
extra/models/history/history-tests.factor [new file with mode: 0644]
extra/models/history/history.factor [new file with mode: 0644]
extra/models/history/summary.txt [new file with mode: 0644]
extra/monads/monads-tests.factor
extra/monads/monads.factor
extra/money/money.factor
extra/multi-methods/multi-methods.factor
extra/multi-methods/tags.txt [new file with mode: 0644]
extra/multi-methods/tests/canonicalize.factor
extra/multi-methods/tests/definitions.factor
extra/multi-methods/tests/legacy.factor
extra/multi-methods/tests/syntax.factor
extra/newfx/newfx.factor
extra/opengl/glu/authors.txt [new file with mode: 0644]
extra/opengl/glu/glu.factor [new file with mode: 0644]
extra/opengl/glu/summary.txt [new file with mode: 0644]
extra/opengl/glu/tags.txt [new file with mode: 0644]
extra/otug-talk/otug-talk.factor
extra/parser-combinators/regexp/authors.txt [deleted file]
extra/parser-combinators/regexp/regexp-tests.factor [deleted file]
extra/parser-combinators/regexp/regexp.factor [deleted file]
extra/parser-combinators/regexp/summary.txt [deleted file]
extra/parser-combinators/regexp/tags.txt [deleted file]
extra/peg-lexer/authors.txt [new file with mode: 0644]
extra/peg-lexer/peg-lexer-docs.factor [new file with mode: 0644]
extra/peg-lexer/peg-lexer-tests.factor [new file with mode: 0644]
extra/peg-lexer/peg-lexer.factor [new file with mode: 0644]
extra/peg-lexer/summary.txt [new file with mode: 0755]
extra/peg-lexer/tags.txt [new file with mode: 0644]
extra/peg-lexer/test-parsers/test-parsers.factor [new file with mode: 0644]
extra/peg/pl0/pl0.factor
extra/poker/arrays/arrays.factor [new file with mode: 0644]
extra/poker/authors.txt [new file with mode: 0644]
extra/poker/poker-docs.factor [new file with mode: 0644]
extra/poker/poker-tests.factor [new file with mode: 0644]
extra/poker/poker.factor [new file with mode: 0644]
extra/poker/summary.txt [new file with mode: 0644]
extra/project-euler/001/001-tests.factor
extra/project-euler/001/001.factor
extra/project-euler/002/002.factor
extra/project-euler/003/003.factor
extra/project-euler/004/004.factor
extra/project-euler/005/005.factor
extra/project-euler/006/006.factor
extra/project-euler/007/007.factor
extra/project-euler/008/008.factor
extra/project-euler/009/009.factor
extra/project-euler/010/010.factor
extra/project-euler/011/011.factor
extra/project-euler/012/012.factor
extra/project-euler/013/013.factor
extra/project-euler/014/014.factor
extra/project-euler/015/015.factor
extra/project-euler/016/016.factor
extra/project-euler/017/017.factor
extra/project-euler/018/018.factor
extra/project-euler/019/019.factor
extra/project-euler/020/020.factor
extra/project-euler/021/021.factor
extra/project-euler/022/022.factor
extra/project-euler/023/023.factor
extra/project-euler/024/024.factor
extra/project-euler/025/025.factor
extra/project-euler/026/026.factor
extra/project-euler/027/027.factor
extra/project-euler/028/028.factor
extra/project-euler/029/029.factor
extra/project-euler/030/030.factor
extra/project-euler/031/031.factor
extra/project-euler/032/032.factor
extra/project-euler/033/033.factor
extra/project-euler/034/034.factor
extra/project-euler/035/035.factor
extra/project-euler/036/036.factor
extra/project-euler/037/037.factor
extra/project-euler/038/038.factor
extra/project-euler/039/039.factor
extra/project-euler/040/040.factor
extra/project-euler/041/041.factor
extra/project-euler/042/042.factor
extra/project-euler/043/043.factor
extra/project-euler/044/044.factor
extra/project-euler/045/045.factor
extra/project-euler/046/046.factor
extra/project-euler/047/047.factor
extra/project-euler/048/048.factor
extra/project-euler/049/049-tests.factor [new file with mode: 0644]
extra/project-euler/049/049.factor [new file with mode: 0644]
extra/project-euler/050/050.factor
extra/project-euler/052/052.factor
extra/project-euler/053/053.factor
extra/project-euler/054/054-tests.factor [new file with mode: 0644]
extra/project-euler/054/054.factor [new file with mode: 0644]
extra/project-euler/054/poker.txt [new file with mode: 0644]
extra/project-euler/055/055.factor
extra/project-euler/056/056.factor
extra/project-euler/057/057.factor
extra/project-euler/058/058-tests.factor [new file with mode: 0644]
extra/project-euler/058/058.factor [new file with mode: 0644]
extra/project-euler/059/059.factor
extra/project-euler/063/063-tests.factor [new file with mode: 0644]
extra/project-euler/063/063.factor [new file with mode: 0644]
extra/project-euler/067/067.factor
extra/project-euler/069/069-tests.factor [new file with mode: 0644]
extra/project-euler/069/069.factor [new file with mode: 0644]
extra/project-euler/071/071.factor
extra/project-euler/073/073.factor
extra/project-euler/075/075.factor
extra/project-euler/076/076.factor
extra/project-euler/079/079.factor
extra/project-euler/092/092.factor
extra/project-euler/097/097.factor
extra/project-euler/099/099.factor
extra/project-euler/100/100.factor
extra/project-euler/116/116.factor
extra/project-euler/117/117.factor
extra/project-euler/134/134.factor
extra/project-euler/148/148.factor
extra/project-euler/150/150.factor
extra/project-euler/151/151.factor
extra/project-euler/164/164.factor
extra/project-euler/169/169.factor
extra/project-euler/173/173.factor
extra/project-euler/175/175.factor
extra/project-euler/186/186.factor
extra/project-euler/190/190.factor
extra/project-euler/203/203.factor
extra/project-euler/215/215.factor
extra/project-euler/common/common.factor
extra/project-euler/project-euler.factor
extra/promises/authors.txt [deleted file]
extra/promises/promises-docs.factor [deleted file]
extra/promises/promises.factor [deleted file]
extra/promises/summary.txt [deleted file]
extra/promises/tags.txt [deleted file]
extra/quadtrees/quadtrees.factor
extra/robots/authors.txt [new file with mode: 0644]
extra/robots/robots-tests.factor [new file with mode: 0644]
extra/robots/robots.factor [new file with mode: 0644]
extra/robots/robots.txt [new file with mode: 0644]
extra/sequence-parser/sequence-parser-tests.factor [new file with mode: 0644]
extra/sequence-parser/sequence-parser.factor [new file with mode: 0644]
extra/sequences/n-based/n-based-docs.factor
extra/sequences/n-based/n-based-tests.factor
extra/site-watcher/authors.txt [new file with mode: 0644]
extra/site-watcher/db/authors.txt [new file with mode: 0644]
extra/site-watcher/db/db.factor [new file with mode: 0644]
extra/site-watcher/email/authors.txt [new file with mode: 0644]
extra/site-watcher/email/email.factor [new file with mode: 0644]
extra/site-watcher/site-watcher-tests.factor [new file with mode: 0644]
extra/site-watcher/site-watcher.factor [new file with mode: 0644]
extra/site-watcher/spider/authors.txt [new file with mode: 0644]
extra/site-watcher/spider/spider.factor [new file with mode: 0644]
extra/slides/slides.factor
extra/smalltalk/ast/ast.factor [new file with mode: 0644]
extra/smalltalk/ast/authors.txt [new file with mode: 0644]
extra/smalltalk/authors.txt [new file with mode: 0644]
extra/smalltalk/classes/authors.txt [new file with mode: 0644]
extra/smalltalk/classes/classes.factor [new file with mode: 0644]
extra/smalltalk/compiler/assignment/assignment.factor [new file with mode: 0644]
extra/smalltalk/compiler/assignment/authors.txt [new file with mode: 0644]
extra/smalltalk/compiler/authors.txt [new file with mode: 0644]
extra/smalltalk/compiler/compiler-tests.factor [new file with mode: 0644]
extra/smalltalk/compiler/compiler.factor [new file with mode: 0644]
extra/smalltalk/compiler/lexenv/authors.txt [new file with mode: 0644]
extra/smalltalk/compiler/lexenv/lexenv-tests.factor [new file with mode: 0644]
extra/smalltalk/compiler/lexenv/lexenv.factor [new file with mode: 0644]
extra/smalltalk/compiler/return/authors.txt [new file with mode: 0644]
extra/smalltalk/compiler/return/return-tests.factor [new file with mode: 0644]
extra/smalltalk/compiler/return/return.factor [new file with mode: 0644]
extra/smalltalk/eval/authors.txt [new file with mode: 0644]
extra/smalltalk/eval/eval-tests.factor [new file with mode: 0644]
extra/smalltalk/eval/eval.factor [new file with mode: 0644]
extra/smalltalk/eval/fib.st [new file with mode: 0644]
extra/smalltalk/library/authors.txt [new file with mode: 0644]
extra/smalltalk/library/library.factor [new file with mode: 0644]
extra/smalltalk/listener/authors.txt [new file with mode: 0644]
extra/smalltalk/listener/listener.factor [new file with mode: 0644]
extra/smalltalk/parser/authors.txt [new file with mode: 0644]
extra/smalltalk/parser/parser-tests.factor [new file with mode: 0644]
extra/smalltalk/parser/parser.factor [new file with mode: 0644]
extra/smalltalk/parser/test.st [new file with mode: 0644]
extra/smalltalk/printer/authors.txt [new file with mode: 0644]
extra/smalltalk/printer/printer-tests.factor [new file with mode: 0644]
extra/smalltalk/printer/printer.factor [new file with mode: 0644]
extra/smalltalk/selectors/authors.txt [new file with mode: 0644]
extra/smalltalk/selectors/selectors.factor [new file with mode: 0644]
extra/spider/report/authors.txt [new file with mode: 0644]
extra/spider/report/report.factor [new file with mode: 0644]
extra/spider/spider-docs.factor
extra/spider/spider.factor
extra/spider/unique-deque/authors.txt [new file with mode: 0644]
extra/spider/unique-deque/unique-deque.factor [new file with mode: 0644]
extra/state-machine/authors.txt [deleted file]
extra/state-machine/state-machine.factor [deleted file]
extra/svg/svg-tests.factor
extra/tetris/gl/gl.factor
extra/trees/authors.txt [new file with mode: 0644]
extra/trees/avl/authors.txt [new file with mode: 0644]
extra/trees/avl/avl-docs.factor [new file with mode: 0644]
extra/trees/avl/avl-tests.factor [new file with mode: 0755]
extra/trees/avl/avl.factor [new file with mode: 0755]
extra/trees/avl/summary.txt [new file with mode: 0644]
extra/trees/avl/tags.txt [new file with mode: 0644]
extra/trees/splay/authors.txt [new file with mode: 0644]
extra/trees/splay/splay-docs.factor [new file with mode: 0644]
extra/trees/splay/splay-tests.factor [new file with mode: 0644]
extra/trees/splay/splay.factor [new file with mode: 0755]
extra/trees/splay/summary.txt [new file with mode: 0644]
extra/trees/splay/tags.txt [new file with mode: 0644]
extra/trees/summary.txt [new file with mode: 0644]
extra/trees/tags.txt [new file with mode: 0644]
extra/trees/trees-docs.factor [new file with mode: 0644]
extra/trees/trees-tests.factor [new file with mode: 0644]
extra/trees/trees.factor [new file with mode: 0755]
extra/ui/gadgets/alerts/alerts.factor [new file with mode: 0644]
extra/ui/gadgets/book-extras/book-extras.factor [new file with mode: 0644]
extra/ui/gadgets/lists/lists.factor
extra/ui/offscreen/offscreen-docs.factor
extra/ui/offscreen/offscreen.factor
extra/ui/offscreen/tags.txt
extra/ui/render/test/reference.bmp
extra/ui/render/test/test.factor
extra/ui/utils/utils.factor [new file with mode: 0644]
extra/units/units-tests.factor
extra/vars/vars.factor
extra/vpri-talk/vpri-talk.factor
extra/webapps/irc-log/irc-log.factor
extra/webapps/pastebin/pastebin.factor
extra/webapps/site-watcher/authors.txt [new file with mode: 0644]
extra/webapps/site-watcher/common/authors.txt [new file with mode: 0644]
extra/webapps/site-watcher/common/common.factor [new file with mode: 0644]
extra/webapps/site-watcher/common/main.xml [new file with mode: 0644]
extra/webapps/site-watcher/common/site-list.xml [new file with mode: 0644]
extra/webapps/site-watcher/common/site-watcher.xml [new file with mode: 0644]
extra/webapps/site-watcher/common/spider-list.xml [new file with mode: 0644]
extra/webapps/site-watcher/common/update-notify.xml [new file with mode: 0644]
extra/webapps/site-watcher/site-watcher.factor [new file with mode: 0644]
extra/webapps/site-watcher/spidering/authors.txt [new file with mode: 0644]
extra/webapps/site-watcher/spidering/spidering.factor [new file with mode: 0644]
extra/webapps/site-watcher/watching/authors.txt [new file with mode: 0644]
extra/webapps/site-watcher/watching/watching.factor [new file with mode: 0644]
extra/webapps/wiki/view.xml
extra/webapps/wiki/wiki-common.xml
extra/webapps/wiki/wiki.factor
extra/webkit-demo/webkit-demo.factor
extra/wordtimer/wordtimer.factor
misc/fuel/fuel-font-lock.el
misc/fuel/fuel-refactor.el
misc/fuel/fuel-syntax.el
unmaintained/trees/authors.txt [deleted file]
unmaintained/trees/avl/authors.txt [deleted file]
unmaintained/trees/avl/avl-docs.factor [deleted file]
unmaintained/trees/avl/avl-tests.factor [deleted file]
unmaintained/trees/avl/avl.factor [deleted file]
unmaintained/trees/avl/summary.txt [deleted file]
unmaintained/trees/avl/tags.txt [deleted file]
unmaintained/trees/splay/authors.txt [deleted file]
unmaintained/trees/splay/splay-docs.factor [deleted file]
unmaintained/trees/splay/splay-tests.factor [deleted file]
unmaintained/trees/splay/splay.factor [deleted file]
unmaintained/trees/splay/summary.txt [deleted file]
unmaintained/trees/splay/tags.txt [deleted file]
unmaintained/trees/summary.txt [deleted file]
unmaintained/trees/tags.txt [deleted file]
unmaintained/trees/trees-docs.factor [deleted file]
unmaintained/trees/trees-tests.factor [deleted file]
unmaintained/trees/trees.factor [deleted file]
vm/Config.macosx
vm/Config.unix
vm/Config.windows
vm/alien.c
vm/alien.h
vm/callstack.c
vm/callstack.h
vm/code_block.c
vm/code_block.h
vm/code_gc.c
vm/code_gc.h
vm/code_heap.c
vm/code_heap.h
vm/cpu-ppc.S
vm/cpu-x86.32.S
vm/cpu-x86.64.S
vm/data_gc.h
vm/debug.c
vm/errors.c
vm/errors.h
vm/factor.c
vm/image.c
vm/io.c
vm/io.h
vm/layouts.h
vm/os-unix.h
vm/os-windows.h
vm/platform.h
vm/primitives.c
vm/profiler.c
vm/quotations.c
vm/run.c
vm/run.h
vm/types.c
vm/types.h

diff --git a/Factor.app/Contents/Frameworks/libfreetype.6.dylib b/Factor.app/Contents/Frameworks/libfreetype.6.dylib
deleted file mode 100755 (executable)
index 381e74b..0000000
Binary files a/Factor.app/Contents/Frameworks/libfreetype.6.dylib and /dev/null differ
index 5461ea5de963bd0eaaca5a17ef1bd2ebbb7b03d4..35a5ba58bfac5e73a25aa4911718dce7262bb955 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,12 +4,14 @@ LD = ld
 
 EXECUTABLE = factor
 CONSOLE_EXECUTABLE = factor-console
+TEST_LIBRARY = factor-ffi-test
 VERSION = 0.92
 
 IMAGE = factor.image
 BUNDLE = Factor.app
 LIBPATH = -L/usr/X11R6/lib
 CFLAGS = -Wall
+FFI_TEST_CFLAGS = -fPIC
 
 ifdef DEBUG
        CFLAGS += -g
@@ -35,7 +37,6 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
        vm/debug.o \
        vm/errors.o \
        vm/factor.o \
-       vm/ffi_test.o \
        vm/image.o \
        vm/io.o \
        vm/math.o \
@@ -48,6 +49,8 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
 
 EXE_OBJS = $(PLAF_EXE_OBJS)
 
+TEST_OBJS = vm/ffi_test.o
+
 default:
        $(MAKE) `./build-support/factor.sh make-target`
 
@@ -81,70 +84,67 @@ help:
        @echo "X11=1  force link with X11 libraries instead of Cocoa (only on Mac OS X)"
 
 openbsd-x86-32:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.openbsd.x86.32
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.openbsd.x86.32
 
 openbsd-x86-64:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.openbsd.x86.64
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.openbsd.x86.64
 
 freebsd-x86-32:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.freebsd.x86.32
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.freebsd.x86.32
 
 freebsd-x86-64:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.freebsd.x86.64
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.freebsd.x86.64
 
 netbsd-x86-32:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.netbsd.x86.32
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.netbsd.x86.32
 
 netbsd-x86-64:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.netbsd.x86.64
-
-macosx-freetype:
-       ln -sf libfreetype.6.dylib \
-               Factor.app/Contents/Frameworks/libfreetype.dylib
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.netbsd.x86.64
 
-macosx-ppc: macosx-freetype
-       $(MAKE) $(EXECUTABLE) macosx.app CONFIG=vm/Config.macosx.ppc
+macosx-ppc:
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) macosx.app CONFIG=vm/Config.macosx.ppc
 
-macosx-x86-32: macosx-freetype
-       $(MAKE) $(EXECUTABLE) macosx.app CONFIG=vm/Config.macosx.x86.32
+macosx-x86-32:
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) macosx.app CONFIG=vm/Config.macosx.x86.32
 
-macosx-x86-64: macosx-freetype
-       $(MAKE) $(EXECUTABLE) macosx.app CONFIG=vm/Config.macosx.x86.64
+macosx-x86-64:
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) macosx.app CONFIG=vm/Config.macosx.x86.64
 
 linux-x86-32:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.linux.x86.32
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.linux.x86.32
 
 linux-x86-64:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.linux.x86.64
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.linux.x86.64
 
 linux-ppc:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.linux.ppc
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.linux.ppc
 
 linux-arm:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.linux.arm
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.linux.arm
 
 solaris-x86-32:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.solaris.x86.32
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.solaris.x86.32
 
 solaris-x86-64:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.solaris.x86.64
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.solaris.x86.64
 
 winnt-x86-32:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.windows.nt.x86.32
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.windows.nt.x86.32
        $(MAKE) $(CONSOLE_EXECUTABLE) CONFIG=vm/Config.windows.nt.x86.32
 
 winnt-x86-64:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.windows.nt.x86.64
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.windows.nt.x86.64
        $(MAKE) $(CONSOLE_EXECUTABLE) CONFIG=vm/Config.windows.nt.x86.64
 
 wince-arm:
-       $(MAKE) $(EXECUTABLE) CONFIG=vm/Config.windows.ce.arm
+       $(MAKE) $(EXECUTABLE) $(TEST_LIBRARY) CONFIG=vm/Config.windows.ce.arm
 
 macosx.app: factor
        mkdir -p $(BUNDLE)/Contents/MacOS
+       mkdir -p $(BUNDLE)/Contents/Frameworks
        mv $(EXECUTABLE) $(BUNDLE)/Contents/MacOS/factor
        ln -s Factor.app/Contents/MacOS/factor ./factor
-       cp $(ENGINE) $(BUNDLE)/Contents/Frameworks
+       cp $(ENGINE) $(BUNDLE)/Contents/Frameworks/$(ENGINE)
 
        install_name_tool \
                -change libfactor.dylib \
@@ -161,13 +161,19 @@ factor-console: $(DLL_OBJS) $(EXE_OBJS)
        $(CC) $(LIBS) $(LIBPATH) -L. $(LINK_WITH_ENGINE) \
                $(CFLAGS) $(CFLAGS_CONSOLE) -o factor$(EXE_SUFFIX)$(CONSOLE_EXTENSION) $(EXE_OBJS)
 
+factor-ffi-test: vm/ffi_test.o
+       $(CC) $(LIBPATH) $(CFLAGS) $(FFI_TEST_CFLAGS) $(SHARED_FLAG) -o libfactor-ffi-test$(SHARED_DLL_EXTENSION) $(TEST_OBJS)
+
 clean:
        rm -f vm/*.o
-       rm -f factor*.dll libfactor.{a,so,dylib}
+       rm -f factor*.dll libfactor.{a,so,dylib} libfactor-ffi-test.{a,so,dylib} Factor.app/Contents/Frameworks/libfactor.dylib
 
 vm/resources.o:
        $(WINDRES) vm/factor.rs vm/resources.o
 
+vm/ffi_test.o: vm/ffi_test.c
+       $(CC) -c $(CFLAGS) $(FFI_TEST_CFLAGS) -o $@ $<
+
 .c.o:
        $(CC) -c $(CFLAGS) -o $@ $<
 
index bd9da0ab2bc85318bf37526af68a75b4ca312ecb..c5d53de84275c86a69f8b4eb7394800fbd98ea8c 100755 (executable)
@@ -113,12 +113,6 @@ the command prompt using the console application:
 
   factor.com -i=boot.<cpu>.image
 
-Before bootstrapping, you will need to download the DLLs for the Pango
-text rendering library. The required DLLs are listed in
-build-support/dlls.txt and are available from the following location:
-
-  <http://factorcode.org/dlls>
-
 Once bootstrapped, double-clicking factor.exe or factor.com starts
 the Factor UI.
 
index dc29ea9bb356826ce56af454aa6d157248331a6a..46afc05e2dfa9074978ea6be12c554121b4787a3 100644 (file)
@@ -217,6 +217,8 @@ $nl
 "Utilities for automatically freeing memory in conjunction with " { $link with-destructors } ":"
 { $subsection &free }
 { $subsection |free }
+"The " { $link &free } " and " { $link |free } " words are generated using " { $link "alien.destructors" } "."
+$nl
 "You can unsafely copy a range of bytes from one memory location to another:"
 { $subsection memcpy }
 "You can copy a range of bytes from memory into a byte array:"
@@ -243,4 +245,6 @@ $nl
 "New C types can be defined:"
 { $subsection "c-structs" }
 { $subsection "c-unions" }
+"A utility for defining " { $link "destructors" } " for deallocating memory:"
+{ $subsection "alien.destructors" }
 { $see-also "aliens" } ;
index 40171f56e7917bda2b0916c6c1903f61672ca30d..988dc180e017b42f75048ec0f0a5143d6946c320 100644 (file)
@@ -4,7 +4,7 @@ sequences system libc alien.strings io.encodings.utf8 ;
 
 \ expand-constants must-infer
 
-: xyz 123 ;
+CONSTANT: xyz 123
 
 [ { "blah" 123 } ] [ { "blah" xyz } expand-constants ] unit-test
 
index c3fd41e68973ee64545218b49d216003782c5dba..dc35f8bbb05fb94f0345c512c0907241df5f1721 100755 (executable)
@@ -4,7 +4,7 @@ USING: byte-arrays arrays assocs kernel kernel.private libc math
 namespaces make parser sequences strings words assocs splitting
 math.parser cpu.architecture alien alien.accessors quotations
 layouts system compiler.units io.files io.encodings.binary
-accessors combinators effects continuations fry call classes ;
+accessors combinators effects continuations fry classes ;
 IN: alien.c-types
 
 DEFER: <int>
diff --git a/basis/alien/destructors/destructors-docs.factor b/basis/alien/destructors/destructors-docs.factor
new file mode 100644 (file)
index 0000000..bc08dc7
--- /dev/null
@@ -0,0 +1,30 @@
+IN: alien.destructors
+USING: help.markup help.syntax alien destructors ;
+
+HELP: DESTRUCTOR:
+{ $syntax "DESTRUCTOR: word" }
+{ $description "Defines four things:"
+  { $list
+    { "a tuple named " { $snippet "word" } " with a single slot holding a " { $link c-ptr } }
+    { "a " { $link dispose } " method on the tuple which calls " { $snippet "word" } " with the " { $link c-ptr } }
+    { "a pair of words, " { $snippet "&word" } " and " { $snippet "|word" } ", which call " { $link &dispose } " and " { $link |dispose } " with a new instance of the tuple" }
+  }
+  "The " { $snippet "word" } " must be defined in the current vocabulary, and must have stack effect " { $snippet "( c-ptr -- )" } "."
+}
+{ $examples
+  "Suppose you are writing a binding to the GLib library, which as a " { $snippet "g_object_unref" } " function. Then you can define the function and destructor like so,"
+  { $code
+    "FUNCTION: void g_object_unref ( gpointer object ) ;"
+    "DESTRUCTOR: g_object_unref"
+  }
+  "Now, memory management becomes easier:"
+  { $code
+    "[ g_new_foo &g_object_unref ... ] with-destructors"
+  }
+} ;
+
+ARTICLE: "alien.destructors" "Alien destructors"
+"The " { $vocab-link "alien.destructors" } " vocabulary defines a utility parsing word for defining new disposable classes."
+{ $subsection POSTPONE: DESTRUCTOR: } ;
+
+ABOUT: "alien.destructors"
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 6c55528..374d642
@@ -1,6 +1,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: functors destructors accessors kernel parser words ;
+USING: functors destructors accessors kernel parser words
+effects generalizations sequences ;
 IN: alien.destructors
 
 SLOT: alien
@@ -11,6 +12,7 @@ F-destructor DEFINES-CLASS ${F}-destructor
 <F-destructor> DEFINES <${F}-destructor>
 &F DEFINES &${F}
 |F DEFINES |${F}
+N [ F stack-effect out>> length ]
 
 WHERE
 
@@ -18,7 +20,7 @@ TUPLE: F-destructor alien disposed ;
 
 : <F-destructor> ( alien -- destructor ) f F-destructor boa ; inline
 
-M: F-destructor dispose* alien>> F ;
+M: F-destructor dispose* alien>> F N ndrop ;
 
 : &F ( alien -- alien ) dup <F-destructor> &dispose drop ; inline
 
@@ -26,4 +28,4 @@ M: F-destructor dispose* alien>> F ;
 
 ;FUNCTOR
 
-: DESTRUCTOR: scan-word define-destructor ; parsing
\ No newline at end of file
+SYNTAX: DESTRUCTOR: scan-word define-destructor ;
\ No newline at end of file
index c5d124e198a744be4eb80b68eae43ae2812f0eba..8027020c75004e57e0a50fea5dc5fd7c8c8b54d9 100644 (file)
@@ -7,10 +7,10 @@ IN: alien.fortran
 ARTICLE: "alien.fortran-abis" "Fortran ABIs"
 "Fortran does not have a standard ABI like C does. Factor supports the following Fortran ABIs:"
 { $list
-    { { $subsection gfortran-abi } " is used by gfortran, the Fortran compiler included with GCC 4." }
-    { { $subsection f2c-abi } " is used by the F2C Fortran-to-C translator and G77, the Fortran compiler included with GCC 3.x and earlier. It is also used by gfortran when compiling with the -ff2c flag." }
-    { { $subsection intel-unix-abi } " is used by the Intel Fortran Compiler on Linux and Mac OS X." }
-    { { $subsection intel-windows-abi } " is used by the Intel Fortran Compiler on Windows." }
+    { { $link gfortran-abi } " is used by gfortran, the Fortran compiler included with GCC 4." }
+    { { $link f2c-abi } " is used by the F2C Fortran-to-C translator and G77, the Fortran compiler included with GCC 3.x and earlier. It is also used by gfortran when compiling with the -ff2c flag." }
+    { { $link intel-unix-abi } " is used by the Intel Fortran Compiler on Linux and Mac OS X." }
+    { { $link intel-windows-abi } " is used by the Intel Fortran Compiler on Windows." }
 }
 "A library's ABI is specified when that library is opened by the " { $link add-fortran-library } " word." ;
 
index 5e3dc24476520496b59b36c59987d9ccfda93562..b27c62b9a1399691b3bae335eeb2bebcddcf78b8 100644 (file)
@@ -5,10 +5,10 @@ byte-arrays combinators combinators.short-circuit fry generalizations
 kernel lexer macros math math.parser namespaces parser sequences
 splitting stack-checker vectors vocabs.parser words locals
 io.encodings.ascii io.encodings.string shuffle effects math.ranges
-math.order sorting strings system ;
+math.order sorting strings system alien.libraries ;
 IN: alien.fortran
 
-SINGLETONS: f2c-abi gfortran-abi intel-unix-abi intel-windows-abi ;
+SINGLETONS: f2c-abi g95-abi gfortran-abi intel-unix-abi intel-windows-abi ;
 
 << 
 : add-f2c-libraries ( -- )
@@ -42,30 +42,35 @@ library-fortran-abis [ H{ } clone ] initialize
 
 HOOK: fortran-c-abi fortran-abi ( -- abi )
 M: f2c-abi fortran-c-abi "cdecl" ;
+M: g95-abi fortran-c-abi "cdecl" ;
 M: gfortran-abi fortran-c-abi "cdecl" ;
 M: intel-unix-abi fortran-c-abi "cdecl" ;
 M: intel-windows-abi fortran-c-abi "cdecl" ;
 
 HOOK: real-functions-return-double? fortran-abi ( -- ? )
 M: f2c-abi real-functions-return-double? t ;
+M: g95-abi real-functions-return-double? f ;
 M: gfortran-abi real-functions-return-double? f ;
 M: intel-unix-abi real-functions-return-double? f ;
 M: intel-windows-abi real-functions-return-double? f ;
 
 HOOK: complex-functions-return-by-value? fortran-abi ( -- ? )
 M: f2c-abi complex-functions-return-by-value? f ;
+M: g95-abi complex-functions-return-by-value? f ;
 M: gfortran-abi complex-functions-return-by-value? t ;
 M: intel-unix-abi complex-functions-return-by-value? f ;
 M: intel-windows-abi complex-functions-return-by-value? f ;
 
 HOOK: character(1)-maps-to-char? fortran-abi ( -- ? )
 M: f2c-abi character(1)-maps-to-char? f ;
+M: g95-abi character(1)-maps-to-char? f ;
 M: gfortran-abi character(1)-maps-to-char? f ;
 M: intel-unix-abi character(1)-maps-to-char? t ;
 M: intel-windows-abi character(1)-maps-to-char? t ;
 
 HOOK: mangle-name fortran-abi ( name -- name' )
 M: f2c-abi mangle-name lowercase-name-with-extra-underscore ;
+M: g95-abi mangle-name lowercase-name-with-extra-underscore ;
 M: gfortran-abi mangle-name lowercase-name-with-underscore ;
 M: intel-unix-abi mangle-name lowercase-name-with-underscore ;
 M: intel-windows-abi mangle-name >upper ;
@@ -416,7 +421,7 @@ PRIVATE>
 : define-fortran-record ( name vocab fields -- )
     [ >lower ] [ ] [ fortran-record>c-struct ] tri* define-struct ;
 
-: RECORD: scan in get parse-definition define-fortran-record ; parsing
+SYNTAX: RECORD: scan in get parse-definition define-fortran-record ;
 
 : set-fortran-abi ( library -- )
     library-fortran-abis get-global at fortran-abi set ;
@@ -437,16 +442,16 @@ MACRO: fortran-invoke ( return library function parameters -- )
     return library function parameters return [ "void" ] unless* parse-arglist
     [ \ fortran-invoke 5 [ ] nsequence ] dip define-declared ;
 
-: SUBROUTINE: 
+SYNTAX: SUBROUTINE: 
     f "c-library" get scan ";" parse-tokens
-    [ "()" subseq? not ] filter define-fortran-function ; parsing
+    [ "()" subseq? not ] filter define-fortran-function ;
 
-: FUNCTION:
+SYNTAX: FUNCTION:
     scan "c-library" get scan ";" parse-tokens
-    [ "()" subseq? not ] filter define-fortran-function ; parsing
+    [ "()" subseq? not ] filter define-fortran-function ;
 
-: LIBRARY:
+SYNTAX: LIBRARY:
     scan
     [ "c-library" set ]
-    [ set-fortran-abi ] bi  ; parsing
+    [ set-fortran-abi ] bi ;
 
diff --git a/basis/alien/libraries/authors.txt b/basis/alien/libraries/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/alien/libraries/libraries-docs.factor b/basis/alien/libraries/libraries-docs.factor
new file mode 100644 (file)
index 0000000..3b9c56c
--- /dev/null
@@ -0,0 +1,60 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.syntax assocs help.markup
+help.syntax io.backend kernel namespaces ;
+IN: alien.libraries
+
+HELP: <library>
+{ $values
+     { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
+     { "library" library } }
+{ $description "Opens a C library using the path and ABI parameters and outputs a library tuple." }
+{ $notes "User code should use " { $link add-library } " so that the opened library is added to a global hashtable, " { $link libraries } "." } ;
+
+HELP: libraries
+{ $description "A global hashtable that keeps a list of open libraries. Use the " { $link add-library } " word to construct a library and add it with a single call." } ;
+
+HELP: library
+{ $values { "name" "a string" } { "library" "a hashtable" } }
+{ $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
+    { $list
+        { { $snippet "name" } " - the full path of the C library binary" }
+        { { $snippet "abi" } " - the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
+        { { $snippet "dll" } " - an instance of the " { $link dll } " class; only set if the library is loaded" }
+    }
+} ;
+
+HELP: dlopen ( path -- dll )
+{ $values { "path" "a pathname string" } { "dll" "a DLL handle" } }
+{ $description "Opens a native library and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } "." }
+{ $errors "Throws an error if the library could not be found, or if loading fails for some other reason." }
+{ $notes "This is the low-level facility used to implement " { $link load-library } ". Use the latter instead." } ;
+
+HELP: dlsym ( name dll -- alien )
+{ $values { "name" "a C symbol name" } { "dll" "a DLL handle" } { "alien" "an alien pointer" } }
+{ $description "Looks up a symbol in a native library. If " { $snippet "dll" } " is " { $link f } " looks for the symbol in the runtime executable." }
+{ $errors "Throws an error if the symbol could not be found." } ;
+
+HELP: dlclose ( dll -- )
+{ $values { "dll" "a DLL handle" } }
+{ $description "Closes a DLL handle created by " { $link dlopen } ". This word might not be implemented on all platforms." } ;
+
+HELP: load-library
+{ $values { "name" "a string" } { "dll" "a DLL handle" } }
+{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
+
+HELP: add-library
+{ $values { "name" "a string" } { "path" "a string" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
+{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } "and the specified ABI." }
+{ $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " cannot be used in the same file as " { $link POSTPONE: FUNCTION: } " definitions from that library. The " { $link add-library } " call will happen too late, after compilation, and the alien calls will not work."
+$nl
+"Instead, " { $link add-library } " calls must either be placed in different source files from those that use that library, or alternatively, " { $link "syntax-immediate" } " can be used to load the library before compilation." }
+{ $examples "Here is a typical usage of " { $link add-library } ":"
+{ $code
+    "<< \"freetype\" {"
+    "    { [ os macosx? ] [ \"libfreetype.6.dylib\" \"cdecl\" add-library ] }"
+    "    { [ os windows? ] [ \"freetype6.dll\" \"cdecl\" add-library ] }"
+    "    [ drop ]"
+    "} cond >>"
+}
+"Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
diff --git a/basis/alien/libraries/libraries.factor b/basis/alien/libraries/libraries.factor
new file mode 100644 (file)
index 0000000..3fcc159
--- /dev/null
@@ -0,0 +1,21 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien assocs io.backend kernel namespaces ;
+IN: alien.libraries
+
+SYMBOL: libraries
+
+libraries [ H{ } clone ] initialize
+
+TUPLE: library path abi dll ;
+
+: library ( name -- library ) libraries get at ;
+
+: <library> ( path abi -- library )
+    over dup [ dlopen ] when \ library boa ;
+
+: load-library ( name -- dll )
+    library dup [ dll>> ] when ;
+
+: add-library ( name path abi -- )
+    <library> swap libraries get set-at ;
index 047768344279796f1c98ca005f9f4b78f6a11b6a..7e2d4615b5d0786b06433eb47a8b5282e8e8a57c 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel kernel.private math namespaces
 make sequences strings words effects combinators alien.c-types ;
@@ -6,28 +6,6 @@ IN: alien.structs.fields
 
 TUPLE: field-spec name offset type reader writer ;
 
-: reader-effect ( type spec -- effect )
-    [ 1array ] [ name>> 1array ] bi* <effect> ;
-
-PREDICATE: slot-reader < word "reading" word-prop >boolean ;
-
-: set-reader-props ( class spec -- )
-    2dup reader-effect
-    over reader>>
-    swap "declared-effect" set-word-prop
-    reader>> swap "reading" set-word-prop ;
-
-: writer-effect ( type spec -- effect )
-    name>> swap 2array 0 <effect> ;
-
-PREDICATE: slot-writer < word "writing" word-prop >boolean ;
-
-: set-writer-props ( class spec -- )
-    2dup writer-effect
-    over writer>>
-    swap "declared-effect" set-word-prop
-    writer>> swap "writing" set-word-prop ;
-
 : reader-word ( class name vocab -- word )
     [ "-" glue ] dip create ;
 
@@ -55,17 +33,13 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ;
 : define-struct-slot-word ( word quot spec effect -- )
     [ offset>> prefix ] dip define-inline ;
 
-: define-getter ( type spec -- )
-    [ set-reader-props ] keep
-    [ reader>> ]
-    [ type>> c-type-getter-boxer ]
-    [ ] tri
+: define-getter ( spec -- )
+    [ reader>> ] [ type>> c-type-getter-boxer ] [ ] tri
     (( c-ptr -- value )) define-struct-slot-word ;
 
-: define-setter ( type spec -- )
-    [ set-writer-props ] keep
+: define-setter ( spec -- )
     [ writer>> ] [ type>> c-setter ] [ ] tri
     (( value c-ptr -- )) define-struct-slot-word ;
 
-: define-field ( type spec -- )
-    [ define-getter ] [ define-setter ] 2bi ;
+: define-field ( spec -- )
+    [ define-getter ] [ define-setter ] bi ;
index 8bc570c4484f2a02de2c3bbc628647000b678b34..231f1bd42876a1e4f842fc97e0cd5a7b816604ff 100755 (executable)
@@ -24,7 +24,7 @@ os winnt? cpu x86? and [
     ] when
 ] when
 
-: MAX_FOOS 30 ;
+CONSTANT: MAX_FOOS 30
 
 C-STRUCT: foox
     { { "int" MAX_FOOS } "x" } ;
index ec9080690a4e27368bf01cac7a8fc499ddcaa2fc..b618e7974bc76cd9647f5fcd0f3f4a2c39f12616 100755 (executable)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs generic hashtables kernel kernel.private
 math namespaces parser sequences strings words libc fry
@@ -56,10 +56,10 @@ M: struct-type stack-size
 : (define-struct) ( name size align fields -- )
     [ [ align ] keep ] dip
     struct-type new
-    swap >>fields
-    swap >>align
-    swap >>size
-    swap typedef ;
+        swap >>fields
+        swap >>align
+        swap >>size
+        swap typedef ;
 
 : make-fields ( name vocab fields -- fields )
     [ first2 <field-spec> ] with with map ;
@@ -68,12 +68,11 @@ M: struct-type stack-size
     [ c-type-align ] [ max ] map-reduce ;
 
 : define-struct ( name vocab fields -- )
-    [
-        [ 2drop ] [ make-fields ] 3bi
-        [ struct-offsets ] keep
-        [ [ type>> ] map compute-struct-align ] keep
-        [ (define-struct) ] keep
-    ] [ 2drop '[ _ swap define-field ] ] 3bi each ;
+    [ 2drop ] [ make-fields ] 3bi
+    [ struct-offsets ] keep
+    [ [ type>> ] map compute-struct-align ] keep
+    [ (define-struct) ] keep
+    [ define-field ] each ;
 
 : define-union ( name members -- )
     [ expand-constants ] map
@@ -83,4 +82,3 @@ M: struct-type stack-size
 : offset-of ( field struct -- offset )
     c-types get at fields>> 
     [ name>> = ] with find nip offset>> ;
-
index 987c73127ee5feddf694a3bed65338920af44225..6a1bf7f635ff9bc502b163713b9d12e99dd3369b 100644 (file)
@@ -4,38 +4,37 @@ USING: accessors arrays alien alien.c-types alien.structs
 alien.arrays alien.strings kernel math namespaces parser
 sequences words quotations math.parser splitting grouping
 effects assocs combinators lexer strings.parser alien.parser 
-fry vocabs.parser words.constant ;
+fry vocabs.parser words.constant alien.libraries ;
 IN: alien.syntax
 
-: DLL" lexer get skip-blank parse-string dlopen parsed ; parsing
+SYNTAX: DLL" lexer get skip-blank parse-string dlopen parsed ;
 
-: ALIEN: scan string>number <alien> parsed ; parsing
+SYNTAX: ALIEN: scan string>number <alien> parsed ;
 
-: BAD-ALIEN <bad-alien> parsed ; parsing
+SYNTAX: BAD-ALIEN <bad-alien> parsed ;
 
-: LIBRARY: scan "c-library" set ; parsing
+SYNTAX: LIBRARY: scan "c-library" set ;
 
-: FUNCTION:
+SYNTAX: FUNCTION:
     scan "c-library" get scan ";" parse-tokens
     [ "()" subseq? not ] filter
-    define-function ; parsing
+    define-function ;
 
-: TYPEDEF:
-    scan scan typedef ; parsing
+SYNTAX: TYPEDEF:
+    scan scan typedef ;
 
-: C-STRUCT:
-    scan in get parse-definition define-struct ; parsing
+SYNTAX: C-STRUCT:
+    scan in get parse-definition define-struct ;
 
-: C-UNION:
-    scan parse-definition define-union ; parsing
+SYNTAX: C-UNION:
+    scan parse-definition define-union ;
 
-: C-ENUM:
+SYNTAX: C-ENUM:
     ";" parse-tokens
     [ [ create-in ] dip define-constant ] each-index ;
-    parsing
 
 : address-of ( name library -- value )
     load-library dlsym [ "No such symbol" throw ] unless* ;
 
-: &:
-    scan "c-library" get '[ _ _ address-of ] over push-all ; parsing
+SYNTAX: &:
+    scan "c-library" get '[ _ _ address-of ] over push-all ;
diff --git a/basis/alien/syntax/tags.txt b/basis/alien/syntax/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/basis/assoc-heaps/assoc-heaps-docs.factor b/basis/assoc-heaps/assoc-heaps-docs.factor
deleted file mode 100644 (file)
index b148995..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax io.streams.string assocs
-heaps.private ;
-IN: assoc-heaps
-
-HELP: <assoc-heap>
-{ $values { "assoc" assoc } { "heap" heap } { "assoc-heap" assoc-heap } }
-{ $description "Constructs a new " { $link assoc-heap } " from two existing data structures." } ;
-
-HELP: <unique-max-heap>
-{ $values { "unique-heap" assoc-heap } }
-{ $description "Creates a new " { $link assoc-heap } " where the assoc is a hashtable and the heap is a max-heap. Popping an element from the heap leaves this element in the hashtable to ensure that the element will not be processed again." } ;
-
-HELP: <unique-min-heap>
-{ $values { "unique-heap" assoc-heap } }
-{ $description "Creates a new " { $link assoc-heap } " where the assoc is a hashtable and the heap is a min-heap. Popping an element from the heap leaves this element in the hashtable to ensure that the element will not be processed again." } ;
-
-{ <unique-max-heap> <unique-min-heap> } related-words
-
-HELP: assoc-heap
-{ $description "A data structure containing an assoc and a heap to get certain properties with better time constraints at the expense of more space and complexity. For instance, a hashtable and a heap can be combined into one assoc-heap to get a sorted data structure with O(1) lookup. Operations on assoc-heap may update both the assoc and the heap or leave them out of sync if it's advantageous." } ;
-
-ARTICLE: "assoc-heaps" "Associative heaps"
-"The " { $vocab-link "assoc-heaps" } " vocabulary combines exists to synthesize data structures with better time properties than either of the two component data structures alone." $nl
-"Associative heap constructor:"
-{ $subsection <assoc-heap> }
-"Unique heaps:"
-{ $subsection <unique-min-heap> }
-{ $subsection <unique-max-heap> } ;
-
-ABOUT: "assoc-heaps"
diff --git a/basis/assoc-heaps/assoc-heaps-tests.factor b/basis/assoc-heaps/assoc-heaps-tests.factor
deleted file mode 100644 (file)
index 6ea3fe1..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test assoc-heaps ;
-IN: assoc-heaps.tests
diff --git a/basis/assoc-heaps/assoc-heaps.factor b/basis/assoc-heaps/assoc-heaps.factor
deleted file mode 100644 (file)
index a495aed..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-! Copyright (C) 2008 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs hashtables heaps kernel ;
-IN: assoc-heaps
-
-TUPLE: assoc-heap assoc heap ;
-
-C: <assoc-heap> assoc-heap
-
-: <unique-min-heap> ( -- unique-heap )
-    H{ } clone <min-heap> <assoc-heap> ;
-
-: <unique-max-heap> ( -- unique-heap )
-    H{ } clone <max-heap> <assoc-heap> ;
-
-M: assoc-heap heap-push* ( value key assoc-heap -- entry )
-    pick over assoc>> key? [
-        3drop f
-    ] [
-        [ assoc>> swapd set-at ] [ heap>> heap-push* ] 3bi
-    ] if ;
-
-M: assoc-heap heap-pop ( assoc-heap -- value key )
-    heap>> heap-pop ;
-
-M: assoc-heap heap-peek ( assoc-heap -- value key )
-    heap>> heap-peek ;
-
-M: assoc-heap heap-empty? ( assoc-heap -- value key )
-    heap>> heap-empty? ;
diff --git a/basis/assoc-heaps/authors.txt b/basis/assoc-heaps/authors.txt
deleted file mode 100644 (file)
index b4bd0e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Doug Coleman
\ No newline at end of file
diff --git a/basis/assoc-heaps/summary.txt b/basis/assoc-heaps/summary.txt
deleted file mode 100644 (file)
index 792be0a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Priority queue with fast insertion, removal of first element, and lookup of arbitrary elements by key
index ddefff35bb653a57356a502a5d997e4859bdabbc..572d8a5227db00f68e687376b5fa05658f811b21 100644 (file)
@@ -23,5 +23,8 @@ IN: base64.tests
     ascii encode >base64-lines >string
 ] unit-test
 
+[ { 33 52 17 40 12 51 33 43 18 33 23 } base64> ]
+[ malformed-base64? ] must-fail-with
+
 \ >base64 must-infer
 \ base64> must-infer
index c51d871bb5996009d8a3b226c81bc29901b5cef3..47147fa3066f90711f64dc5d6d1266f17b6c7fca 100644 (file)
@@ -5,6 +5,8 @@ io.streams.byte-array kernel math namespaces
 sequences strings io.crlf ;
 IN: base64
 
+ERROR: malformed-base64 ;
+
 <PRIVATE
 
 : read1-ignoring ( ignoring -- ch )
@@ -25,7 +27,7 @@ IN: base64
         f 0 f f f 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
         22 23 24 25 f f f f f f 26 27 28 29 30 31 32 33 34 35 36 37 38 39
         40 41 42 43 44 45 46 47 48 49 50 51
-    } nth ; inline
+    } nth [ malformed-base64 ] unless* ; inline
 
 SYMBOL: column
 
@@ -48,8 +50,6 @@ SYMBOL: column
     [ 3 0 pad-tail binary [ encode3 ] with-byte-writer ]
     [ 1+ ] bi* head-slice 4 CHAR: = pad-tail write-lines ; inline
 
-ERROR: malformed-base64 ;
-
 : decode4 ( seq -- )
     [ 0 [ base64>ch swap 6 shift bitor ] reduce 3 >be ]
     [ [ CHAR: = = ] count ] bi head-slice*
index cf7915159abb5a4dc1cba1c2a3b3d80a7ef47a83..20b33a0bcbf3e5dbf492fb743e20331f5234e423 100644 (file)
@@ -14,7 +14,7 @@ $nl
 
 HELP: sorted-index
 { $values { "obj" object } { "seq" "a sorted sequence" } { "i" "an index, or " { $link f } } }
-{ $description "Outputs the index and value of the element closest to " { $snippet "elt" } " in the sequence. See " { $link search } " for details." }
+{ $description "Outputs the index of the element closest to " { $snippet "elt" } " in the sequence. See " { $link search } " for details." }
 { $notes "If the sequence has at least one element, this word always outputs a valid index, because it finds the closest match, not necessarily an exact one. In this respect its behavior differs from " { $link index } "." } ;
 
 { index index-from last-index last-index-from sorted-index } related-words
index f29e05c0234b115d1902f319f6e91684ea900545..aba3cfbfe5c8b9a0643ffb3fae2771befc4d678f 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences sequences.private accessors math
 math.order combinators hints arrays ;
@@ -16,14 +16,19 @@ IN: binary-search
     [ [ from>> ] [ midpoint@ ] bi + ] [ seq>> ] bi
     [ drop ] [ dup ] [ ] tri* nth ; inline
 
+DEFER: (search)
+
+: keep-searching ( seq quot -- slice )
+    [ dup midpoint@ ] dip call collapse-slice slice boa (search) ; inline
+
 : (search) ( quot: ( elt -- <=> ) seq -- i elt )
     dup length 1 <= [
         finish
     ] [
         decide {
             { +eq+ [ finish ] }
-            { +lt+ [ dup midpoint@ head-slice (search) ] }
-            { +gt+ [ dup midpoint@ tail-slice (search) ] }
+            { +lt+ [ [ (head) ] keep-searching ] }
+            { +gt+ [ [ (tail) ] keep-searching ] }
         } case
     ] if ; inline recursive
 
index e7dd6695a7e90bdfc36c3bb9bdbf290272faa8fa..be8c434e36918c9f60b937fcf4d263042515394c 100644 (file)
@@ -68,7 +68,7 @@ M: bit-array resize
 
 M: bit-array byte-length length 7 + -3 shift ;
 
-: ?{ \ } [ >bit-array ] parse-literal ; parsing
+SYNTAX: ?{ \ } [ >bit-array ] parse-literal ;
 
 : integer>bit-array ( n -- bit-array )
     dup 0 = [
index 31327999e73fceccb6ecd6c38ee9ff036cfaf3d2..41efdbd0d22b491fda2eca30d89b61a5381deba0 100644 (file)
@@ -3,7 +3,7 @@ USING: tools.test bit-vectors vectors sequences kernel math ;
 \r
 [ 0 ] [ 123 <bit-vector> length ] unit-test\r
 \r
-: do-it\r
+: do-it ( seq -- )\r
     1234 swap [ [ even? ] dip push ] curry each ;\r
 \r
 [ t ] [\r
index 85bea80b2dbadc239747c2a20fa22d65314a5c4e..a238f61244dc1675fed7bf94c32344e65035a924 100644 (file)
@@ -31,7 +31,7 @@ M: bit-array new-resizable drop <bit-vector> ;
 \r
 INSTANCE: bit-vector growable\r
 \r
-: ?V{ \ } [ >bit-vector ] parse-literal ; parsing\r
+SYNTAX: ?V{ \ } [ >bit-vector ] parse-literal ;\r
 \r
 M: bit-vector >pprint-sequence ;\r
 M: bit-vector pprint-delims drop \ ?V{ \ } ;\r
index c3e74f7863eca9b029f8dc078d0d9856193acae5..553b91a6aee084ce85489bf540bcf75646a693eb 100644 (file)
@@ -5,7 +5,7 @@ IN: bootstrap.help
 
 : load-help ( -- )
     "help.lint" require
-    "tools.vocabs.browser" require
+    "help.vocabs" require
     "alien.syntax" require
     "compiler" require
 
index 5c76a0fcf849ed1a875df1d4f19490c4723d6cd7..504afae018e38bfb8a8c36c8a7510428b9afc659 100644 (file)
@@ -95,10 +95,10 @@ CONSTANT: -1-offset             9
 SYMBOL: sub-primitives
 
 : make-jit ( quot rc rt offset -- quad )
-    [ { } make ] 3dip 4array ; inline
+    [ [ call( -- ) ] { } make ] 3dip 4array ;
 
 : jit-define ( quot rc rt offset name -- )
-    [ make-jit ] dip set ; inline
+    [ make-jit ] dip set ;
 
 : define-sub-primitive ( quot rc rt offset word -- )
     [ make-jit ] dip sub-primitives get set-at ;
@@ -398,9 +398,14 @@ M: byte-array '
     ] emit-object ;
 
 ! Tuples
+ERROR: tuple-removed class ;
+
+: require-tuple-layout ( word -- layout )
+    dup tuple-layout [ ] [ tuple-removed ] ?if ;
+
 : (emit-tuple) ( tuple -- pointer )
     [ tuple-slots ]
-    [ class transfer-word tuple-layout ] bi prefix [ ' ] map
+    [ class transfer-word require-tuple-layout ] bi prefix [ ' ] map
     tuple type-number dup [ emit-seq ] emit-object ;
 
 : emit-tuple ( tuple -- pointer )
@@ -446,6 +451,8 @@ M: quotation '
         quotation type-number object tag-number [
             emit ! array
             f ' emit ! compiled
+            f ' emit ! cached-effect
+            f ' emit ! cache-counter
             0 emit ! xt
             0 emit ! code
         ] emit-object
@@ -515,7 +522,7 @@ M: quotation '
     20000 <hashtable> objects set
     emit-header t, 0, 1, -1,
     "Building generic words..." print flush
-    call-remake-generics-hook
+    remake-generics
     "Serializing words..." print flush
     emit-words
     "Serializing JIT data..." print flush
index 070618ebb487eaa39c9266aaa71d21d19b393af6..12741f2170fba9dbb826481b26664cabdfc58b11 100644 (file)
@@ -30,7 +30,7 @@ SYMBOL: bootstrap-time
     [ "bootstrap." prepend require ] each ;
 
 : count-words ( pred -- )
-    all-words swap count number>string write ;
+    all-words swap count number>string write ; inline
 
 : print-time ( ms -- )
     1000 /i
@@ -45,11 +45,18 @@ SYMBOL: bootstrap-time
     [ optimized>> ] count-words " compiled words" print
     [ symbol? ] count-words " symbol words" print
     [ ] count-words " words total" print
-
+    
     "Bootstrapping is complete." print
     "Now, you can run Factor:" print
     vm write " -i=" write "output-image" get print flush ;
 
+: save/restore-error ( quot -- )
+    error get-global
+    error-continuation get-global
+    [ call ] 2dip
+    error-continuation set-global
+    error set-global ; inline
+
 [
     ! We time bootstrap
     millis
@@ -104,6 +111,7 @@ SYMBOL: bootstrap-time
     drop
     [
         load-help? off
-        "vocab:bootstrap/bootstrap-error.factor" run-file
+        [ "vocab:bootstrap/bootstrap-error.factor" parse-file ] save/restore-error
+        call
     ] with-scope
 ] recover
index c6ec7f0b995b159f079348f7cd4df0d9f6e4c9c1..b0afe4a1d9bd0bf01545988b0bdc777a352d61ff 100644 (file)
@@ -14,7 +14,6 @@ IN: bootstrap.tools
     "tools.time"
     "tools.threads"
     "tools.vocabs"
-    "tools.vocabs.browser"
     "tools.vocabs.monitor"
     "editors"
 } [ require ] each
index 4f7f82a0674f572fa0deb9cc771362dc1a41711c..271a99c22398a34993801e49114724bcdcfcc7d0 100755 (executable)
@@ -10,12 +10,4 @@ IN: bootstrap.ui
             { [ os unix? ] [ "x11" ] }
         } cond
     ] unless* "ui.backend." prepend require
-
-    "ui-text-backend" get [
-        {
-            { [ os macosx? ] [ "core-text" ] }
-            { [ os windows? ] [ "pango" ] }
-            { [ os unix? ] [ "pango" ] }
-        } cond
-    ] unless* "ui.text." prepend require
 ] when
index 9a100d9795a36442696f1638c90574c25c0aa32e..bd7510c95f632cb8b90e77702429dbc7626815a0 100644 (file)
@@ -4,7 +4,7 @@ prettyprint ;
 \r
 [ 0 ] [ 123 <byte-vector> length ] unit-test\r
 \r
-: do-it\r
+: do-it ( seq -- seq )\r
     123 [ over push ] each ;\r
 \r
 [ t ] [\r
index d146017db08d636d5022f64fbf833e67f562e376..970f4abbd8918bd750aaecce36e5a1fcc8f9ec9c 100644 (file)
@@ -42,7 +42,7 @@ M: byte-array like
 \r
 M: byte-array new-resizable drop <byte-vector> ;\r
 \r
-: BV{ \ } [ >byte-vector ] parse-literal ; parsing\r
+SYNTAX: BV{ \ } [ >byte-vector ] parse-literal ;\r
 \r
 M: byte-vector pprint* pprint-object ;\r
 M: byte-vector pprint-delims drop \ BV{ \ } ;\r
index e7c0a1766043b600b362d0f33eeb922c7cc3656a..2930843ad7a9c44115f38178f3ae1464d4c6d7ba 100644 (file)
@@ -5,7 +5,8 @@
 ! License: http://factorcode.org/license.txt
 
 USING: system combinators alien alien.syntax alien.c-types
-alien.destructors kernel accessors sequences arrays ui.gadgets ;
+alien.destructors kernel accessors sequences arrays ui.gadgets
+alien.libraries ;
 
 IN: cairo.ffi
 << {
index 433459cb24457823fd5b61c253f88132580c0d19..3aae10f6a7461ef0d7b8cd7257da5d2c0429d134 100644 (file)
@@ -36,7 +36,7 @@ HELP: month-name
 { $description "Looks up the month name and returns it as a string.  January has an index of 1 instead of zero." } ;
 
 HELP: month-abbreviations
-{ $values { "array" array } }
+{ $values { "value" array } }
 { $description "Returns an array with the English abbreviated names of all the months." }
 { $warning "Do not use this array for looking up a month name directly. Use month-abbreviation instead." } ;
 
@@ -54,7 +54,7 @@ HELP: day-name
 { $description "Looks up the day name and returns it as a string." } ;
 
 HELP: day-abbreviations2
-{ $values { "array" array } }
+{ $values { "value" array } }
 { $description "Returns an array with the abbreviated English names of the days of the week.  This abbreviation is two characters long." } ;
 
 HELP: day-abbreviation2
@@ -62,7 +62,7 @@ HELP: day-abbreviation2
 { $description "Looks up the abbreviated day name and returns it as a string. This abbreviation is two characters long." } ;
 
 HELP: day-abbreviations3
-{ $values { "array" array } }
+{ $values { "value" array } }
 { $description "Returns an array with the abbreviated English names of the days of the week.  This abbreviation is three characters long." } ;
 
 HELP: day-abbreviation3
index 00d5730745728979aa94b2e49007e9e0f7327e07..b6d8e74072edb7ab0bdd7bbdd7d773150915cc11 100644 (file)
@@ -148,7 +148,7 @@ IN: calendar.tests
 [ t ] [ 123456789000000 [ micros>timestamp timestamp>micros ] keep = ] unit-test
 [ t ] [ 123456789123456000 [ micros>timestamp timestamp>micros ] keep = ] unit-test
 
-: checktime+ now dup clone [ rot time+ drop ] keep = ;
+: checktime+ ( duration -- ? ) now dup clone [ rot time+ drop ] keep = ;
 
 [ t ] [ 5 seconds checktime+ ] unit-test
 
index dc9442259b53c20b1d1cf5c0bed082f3f9b3a0d6..7a03fe44089323f929f406fd4a0e6001fa6ae35d 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2007 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math math.functions namespaces sequences
-strings system vocabs.loader threads accessors combinators
-locals classes.tuple math.order summary combinators.short-circuit ;
+USING: accessors arrays classes.tuple combinators combinators.short-circuit
+    kernel locals math math.functions math.order namespaces sequences strings
+    summary system threads vocabs.loader ;
 IN: calendar
 
 HOOK: gmt-offset os ( -- hours minutes seconds )
@@ -39,8 +39,10 @@ M: not-a-month summary
     drop "Months are indexed starting at 1" ;
 
 <PRIVATE
+
 : check-month ( n -- n )
     dup zero? [ not-a-month ] when ;
+
 PRIVATE>
 
 : month-names ( -- array )
@@ -52,11 +54,11 @@ PRIVATE>
 : month-name ( n -- string )
     check-month 1- month-names nth ;
 
-: month-abbreviations ( -- array )
+CONSTANT: month-abbreviations
     {
         "Jan" "Feb" "Mar" "Apr" "May" "Jun"
         "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
-    } ;
+    }
 
 : month-abbreviation ( n -- string )
     check-month 1- month-abbreviations nth ;
@@ -70,17 +72,17 @@ CONSTANT: day-counts { 0 31 28 31 30 31 30 31 31 30 31 30 31 }
 
 : day-name ( n -- string ) day-names nth ;
 
-: day-abbreviations2 ( -- array )
-    { "Su" "Mo" "Tu" "We" "Th" "Fr" "Sa" } ;
+CONSTANT: day-abbreviations2
+    { "Su" "Mo" "Tu" "We" "Th" "Fr" "Sa" }
 
 : day-abbreviation2 ( n -- string )
-    day-abbreviations2 nth ;
+    day-abbreviations2 nth ; inline
 
-: day-abbreviations3 ( -- array )
-    { "Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" } ;
+CONSTANT: day-abbreviations3
+    { "Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" }
 
 : day-abbreviation3 ( n -- string )
-    day-abbreviations3 nth ;
+    day-abbreviations3 nth ; inline
 
 : average-month ( -- ratio ) 30+5/12 ; inline
 : months-per-year ( -- integer ) 12 ; inline
@@ -134,7 +136,7 @@ CONSTANT: day-counts { 0 31 28 31 30 31 30 31 31 30 31 30 31 }
 GENERIC: leap-year? ( obj -- ? )
 
 M: integer leap-year? ( year -- ? )
-    dup 100 mod zero? 400 4 ? mod zero? ;
+    dup 100 divisor? 400 4 ? divisor? ;
 
 M: timestamp leap-year? ( timestamp -- ? )
     year>> leap-year? ;
@@ -346,7 +348,7 @@ M: duration time-
     #! good for any date since October 15, 1582
     [
         dup 2 <= [ [ 1- ] [ 12 + ] bi* ] when
-        [ dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + ] dip
+        [ dup [ 4 /i + ] [ 100 /i - ] [ 400 /i + ] tri ] dip
         [ 1+ 3 * 5 /i + ] keep 2 * +
     ] dip 1+ + 7 mod ;
 
index 916d3499fe61286a7e0055003c0d11574194d87b..c2e95f2a9eaba04cad881883883500a1186e9a95 100644 (file)
@@ -46,6 +46,11 @@ IN: calendar.format
 \r
 : read-0000 ( -- n ) 4 read string>number ;\r
 \r
+: hhmm>timestamp ( hhmm -- timestamp )\r
+    [\r
+        0 0 0 read-00 read-00 0 instant <timestamp>\r
+    ] with-string-reader ;\r
+\r
 GENERIC: day. ( obj -- )\r
 \r
 M: integer day. ( n -- )\r
diff --git a/basis/call/call-docs.factor b/basis/call/call-docs.factor
deleted file mode 100644 (file)
index 5f76f53..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-! Copyright (C) 2009 Daniel Ehrenberg.
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax quotations effects words call.private ;
-IN: call
-
-ABOUT: "call"
-
-ARTICLE: "call" "Calling code with known stack effects"
-"The " { $vocab-link "call" } " vocabulary allows for arbitrary quotations to be called from code accepted by the optimizing compiler. This is done by specifying the stack effect of the quotation literally. It is checked at runtime that the stack effect is accurate."
-$nl
-"Quotations:"
-{ $subsection POSTPONE: call( }
-{ $subsection call-effect }
-"Words:"
-{ $subsection POSTPONE: execute( }
-{ $subsection execute-effect }
-"Unsafe calls:"
-{ $subsection POSTPONE: execute-unsafe( }
-{ $subsection execute-effect-unsafe } ;
-
-HELP: call(
-{ $syntax "call( stack -- effect )" }
-{ $description "Calls the quotation on the top of the stack, asserting that it has the given stack effect. The quotation does not need to be known at compile time." } ;
-
-HELP: call-effect
-{ $values { "quot" quotation } { "effect" effect } }
-{ $description "Given a quotation and a stack effect, calls the quotation, asserting at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary quotation which is not required at compile time." } ;
-
-HELP: execute(
-{ $syntax "execute( stack -- effect )" }
-{ $description "Calls the word on the top of the stack, asserting that it has the given stack effect. The word does not need to be known at compile time." } ;
-
-HELP: execute-effect
-{ $values { "word" word } { "effect" effect } }
-{ $description "Given a word and a stack effect, executes the word, asserting at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary word which is not required at compile time." } ;
-
-HELP: execute-unsafe(
-{ $syntax "execute-unsafe( stack -- effect )" }
-{ $description "Calls the word on the top of the stack, blindly declaring that it has the given stack effect. The word does not need to be known at compile time." }
-{ $warning "If the word being executed has an incorrect stack effect, undefined behavior will result. User code should use " { $link POSTPONE: execute( } " instead." } ;
-HELP: execute-effect-unsafe
-{ $values { "word" word } { "effect" effect } }
-{ $description "Given a word and a stack effect, executes the word, blindly declaring at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary word which is not required at compile time." }
-{ $warning "If the word being executed has an incorrect stack effect, undefined behavior will result. User code should use " { $link execute-effect-unsafe } " instead." } ;
-    
-{ call-effect execute-effect execute-effect-unsafe } related-words
-{ POSTPONE: call( POSTPONE: execute( POSTPONE: execute-unsafe( } related-words
\ No newline at end of file
diff --git a/basis/call/call-tests.factor b/basis/call/call-tests.factor
deleted file mode 100644 (file)
index 002478f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-! Copyright (C) 2009 Daniel Ehrenberg.
-! See http://factorcode.org/license.txt for BSD license.
-USING: math tools.test call call.private kernel accessors ;
-IN: call.tests
-
-[ 3 ] [ 1 2 [ + ] call( x y -- z ) ] unit-test
-[ 1 2 [ + ] call( -- z ) ] must-fail
-[ 1 2 [ + ] call( x y -- z a ) ] must-fail
-[ 1 2 3 { 4 } ] [ 1 2 3 4 [ datastack nip ] call( x -- y ) ] unit-test
-[ [ + ] call( x y -- z ) ] must-infer
-
-[ 3 ] [ 1 2 \ + execute( x y -- z ) ] unit-test
-[ 1 2 \ + execute( -- z ) ] must-fail
-[ 1 2 \ + execute( x y -- z a ) ] must-fail
-[ \ + execute( x y -- z ) ] must-infer
-
-[ t ] [ \ + (( a b -- c )) execute-effect-unsafe? ] unit-test
-[ t ] [ \ + (( a b c -- d e )) execute-effect-unsafe? ] unit-test
-[ f ] [ \ + (( a b c -- d )) execute-effect-unsafe? ] unit-test
-[ f ] [ \ call (( x -- )) execute-effect-unsafe? ] unit-test
-
-: compile-execute(-test ( a b -- c ) \ + execute( a b -- c ) ;
-
-[ t ] [ \ compile-execute(-test optimized>> ] unit-test
-[ 4 ] [ 1 3 compile-execute(-test ] unit-test
\ No newline at end of file
diff --git a/basis/call/call.factor b/basis/call/call.factor
deleted file mode 100644 (file)
index 0ccc774..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-! Copyright (C) 2009 Daniel Ehrenberg.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel macros fry summary sequences generalizations accessors
-continuations effects effects.parser parser words ;
-IN: call
-
-ERROR: wrong-values values quot length-required ;
-
-M: wrong-values summary
-    drop "Wrong number of values returned from quotation" ;
-
-<PRIVATE
-
-: firstn-safe ( array quot n -- ... )
-    3dup nip swap length = [ nip firstn ] [ wrong-values ] if ; inline
-
-: execute-effect-unsafe ( word effect -- )
-    drop execute ;
-
-: execute-effect-unsafe? ( word effect -- ? )
-    swap dup optimized>> [ stack-effect swap effect<= ] [ 2drop f ] if ; inline
-
-: parse-call( ( accum word -- accum )
-    [ ")" parse-effect parsed ] dip parsed ;
-
-: execute-unsafe( \ execute-effect-unsafe parse-call( ; parsing
-
-PRIVATE>
-
-MACRO: call-effect ( effect -- quot )
-    [ in>> length ] [ out>> length ] bi
-    '[ [ _ narray ] dip [ with-datastack ] keep _ firstn-safe ] ;
-
-: call( \ call-effect parse-call( ; parsing
-
-: execute-effect ( word effect -- )
-    2dup execute-effect-unsafe?
-    [ execute-effect-unsafe ]
-    [ [ [ execute ] curry ] dip call-effect ]
-    if ; inline
-
-: execute( \ execute-effect parse-call( ; parsing
diff --git a/basis/call/summary.txt b/basis/call/summary.txt
deleted file mode 100644 (file)
index d449497..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Calling arbitrary quotations and executing arbitrary words with a static stack effect
index 9437051dad91a1c388b95eb68636ae21e67d3cc5..8b33986fc2864a938bfe35497118987fb811ebf5 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.syntax io kernel namespaces core-foundation
 core-foundation.strings cocoa.messages cocoa cocoa.classes
-cocoa.runtime sequences threads init summary kernel.private
+cocoa.runtime sequences init summary kernel.private
 assocs ;
 IN: cocoa.application
 
index d77435a8ad21263353f34428b76b549d202dfc38..4b5af2e39d3ce533aa8b24b0a7512df388b15edc 100644 (file)
@@ -13,7 +13,7 @@ CLASS: {
     [ gc "x" set 2drop ]
 } ;
 
-: test-foo
+: test-foo ( -- )
     Foo -> alloc -> init
     dup 1.0 2.0 101.0 102.0 <CGRect> -> foo:
     -> release ;
index 01f134e2836cac06f1f314f5fc2119ea12abda39..69d698f9b10c1943a4170eebe2f92d64ddd59cf8 100644 (file)
@@ -14,18 +14,14 @@ SYMBOL: sent-messages
 : remember-send ( selector -- )
     sent-messages (remember-send) ;
 
-: ->
-    scan dup remember-send parsed \ send parsed ;
-    parsing
+SYNTAX: -> scan dup remember-send parsed \ send parsed ;
 
 SYMBOL: super-sent-messages
 
 : remember-super-send ( selector -- )
     super-sent-messages (remember-send) ;
 
-: SUPER->
-    scan dup remember-super-send parsed \ super-send parsed ;
-    parsing
+SYNTAX: SUPER-> scan dup remember-super-send parsed \ super-send parsed ;
 
 SYMBOL: frameworks
 
@@ -33,9 +29,9 @@ frameworks [ V{ } clone ] initialize
 
 [ frameworks get [ load-framework ] each ] "cocoa.messages" add-init-hook
 
-: FRAMEWORK: scan [ load-framework ] [ frameworks get push ] bi ; parsing
+SYNTAX: FRAMEWORK: scan [ load-framework ] [ frameworks get push ] bi ;
 
-: IMPORT: scan [ ] import-objc-class ; parsing
+SYNTAX: IMPORT: scan [ ] import-objc-class ;
 
 "Compiling Objective C bridge..." print
 
index 8818c9a217a6f241231db53ba6d05555cc148863..65bb2c02ef19fd372b1f9d56f01ea4c7498837cb 100644 (file)
@@ -5,7 +5,7 @@ continuations combinators compiler compiler.alien stack-checker kernel
 math namespaces make parser quotations sequences strings words
 cocoa.runtime io macros memoize io.encodings.utf8 effects libc
 libc.private parser lexer init core-foundation fry generalizations
-specialized-arrays.direct.alien call ;
+specialized-arrays.direct.alien ;
 IN: cocoa.messages
 
 : make-sender ( method function -- quot )
@@ -22,15 +22,13 @@ SYMBOL: super-message-senders
 message-senders [ H{ } clone ] initialize
 super-message-senders [ H{ } clone ] initialize
 
-: cache-stub ( method function hash -- )
-    [
-        over get [ 2drop ] [ over [ sender-stub ] dip set ] if
-    ] bind ;
+: cache-stub ( method assoc function -- )
+    '[ _ sender-stub ] cache drop ;
 
 : cache-stubs ( method -- )
-    dup
-    "objc_msgSendSuper" super-message-senders get cache-stub
-    "objc_msgSend" message-senders get cache-stub ;
+    [ super-message-senders get "objc_msgSendSuper" cache-stub ]
+    [ message-senders get "objc_msgSend" cache-stub ]
+    bi ;
 
 : <super> ( receiver -- super )
     "objc-super" <c-object> [
index 394f45bef39fdfd25082233118e2045c85acf5be..e4db56221f33a40e0c7ba5911bb0e7d3a04f6896 100644 (file)
@@ -8,7 +8,7 @@ IN: cocoa.subclassing
 
 : init-method ( method -- sel imp types )
     first3 swap
-    [ sel_registerName ] [ execute ] [ utf8 string>alien ]
+    [ sel_registerName ] [ execute( -- xt ) ] [ utf8 string>alien ]
     tri* ;
 
 : throw-if-false ( obj what -- )
@@ -76,6 +76,6 @@ SYMBOL: +superclass+
         import-objc-class
     ] bind ;
 
-: CLASS:
+SYNTAX: CLASS:
     parse-definition unclip
-    >hashtable define-objc-class ; parsing
+    >hashtable define-objc-class ;
index 0b8346db4bb6a3b610ad96652e81f7f4d4f03d9e..3c60a6a7c1a276fecdc6321a33d60dee97d970ba 100644 (file)
@@ -89,4 +89,4 @@ PRIVATE>
         -> locationInWindow f -> convertPoint:fromView:
         [ CGPoint-x ] [ CGPoint-y ] bi
     ] [ drop -> frame CGRect-h ] 2bi
-    swap - 2array ;
+    swap - [ >integer ] bi@ 2array ;
index 8881d8971144a6ef8aec3b662b7851c05e28fa35..5e2b09380dbb1264b839d0afd4fb1434c3daced9 100644 (file)
@@ -23,7 +23,7 @@ $nl
 ARTICLE: "colors" "Colors"
 "The " { $vocab-link "colors" } " vocabulary defines a protocol for colors, with a concrete implementation for RGBA colors. This vocabulary is used by " { $vocab-link "io.styles" } ", " { $vocab-link "ui" } " and other vocabularies, but it is independent of them."
 $nl
-"RGBA colors:"
+"RGBA colors with floating point components in the range " { $snippet "[0,1]" } ":"
 { $subsection rgba }
 { $subsection <rgba> }
 "Converting a color to RGBA:"
index 91621c110b4bcdd663ac0404117edaab5e930478..38339577cf93a37c7c4de7a16bed77aa54147f01 100644 (file)
@@ -30,4 +30,4 @@ ERROR: no-such-color name ;
 : named-color ( name -- color )
     dup rgb.txt at [ ] [ no-such-color ] ?if ;
 
-: COLOR: scan named-color parsed ; parsing
\ No newline at end of file
+SYNTAX: COLOR: scan named-color parsed ;
\ No newline at end of file
diff --git a/basis/combinators/short-circuit/smart/tags.txt b/basis/combinators/short-circuit/smart/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/basis/combinators/short-circuit/tags.txt b/basis/combinators/short-circuit/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 75f83c1a5576ac46185c98bb069d7e96e817c20b..679b5877594d7af40cdfb0b1b6bca227ee0e92f5 100644 (file)
@@ -108,17 +108,19 @@ HELP: append-outputs-as
 
 
 ARTICLE: "combinators.smart" "Smart combinators"
-"The " { $vocab-link "combinators.smart" } " vocabulary implements " { $emphasis "smart combinators" } ". A smart combinator is one whose behavior depends on the static stack effect of an input quotation." $nl
-"Smart inputs from a sequence:"
+"The macros in the " { $vocab-link "combinators.smart" } " vocabulary look at the static stack effects of input quotations and generate code which produces or consumes the relevant number of stack values." $nl
+"Call a quotation and discard all output values:"
+{ $subsection drop-outputs }
+"Take all input values from a sequence:"
 { $subsection input<sequence }
-"Smart outputs to a sequence:"
+"Store all output values to a sequence:"
 { $subsection output>sequence }
 { $subsection output>array }
-"Reducing the output of a quotation:"
+"Reducing the set of output values:"
 { $subsection reduce-outputs }
-"Summing the output of a quotation:"
+"Summing output values:"
 { $subsection sum-outputs }
-"Appending the results of a quotation:"
+"Concatenating output values:"
 { $subsection append-outputs }
 { $subsection append-outputs-as } ;
 
index e7bdd75ced39028508cd709d1c41d53ae75772c3..aa7960539cca6f6d66c022b8262911481c0f06d1 100644 (file)
@@ -4,6 +4,9 @@ USING: accessors fry generalizations kernel macros math.order
 stack-checker math ;
 IN: combinators.smart
 
+MACRO: drop-outputs ( quot -- quot' )
+    dup infer out>> '[ @ _ ndrop ] ;
+
 MACRO: output>sequence ( quot exemplar -- newquot )
     [ dup infer out>> ] dip
     '[ @ _ _ nsequence ] ;
diff --git a/basis/combinators/smart/tags.txt b/basis/combinators/smart/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 38d40d84828b0055873718a7c3be9221e151d3c1..56d7fbd2070bcf8366e3eab60347ee03cd2cb750 100644 (file)
@@ -54,13 +54,12 @@ SYMBOL: main-vocab-hook
     embedded? [
         "alien.remote-control"
     ] [
-        main-vocab-hook get [ call ] [ "listener" ] if*
+        main-vocab-hook get [ call( -- vocab ) ] [ "listener" ] if*
     ] if ;
 
 : default-cli-args ( -- )
     global [
         "quiet" off
-        "script" off
         "e" off
         "user-init" on
         embedded? "quiet" set
index 0389841e8f5ec78a25eaa410c4e7fff405ceb798..876ac5596cd829906b03b19505286f004daf6e1a 100644 (file)
@@ -13,10 +13,10 @@ IN: compiler.cfg.instructions.syntax
 : insn-effect ( word -- effect )
     boa-effect in>> but-last f <effect> ;
 
-: INSN:
+SYNTAX: INSN:
     parse-tuple-definition "regs" suffix
     [ dup tuple eq? [ drop insn-word ] when ] dip
     [ define-tuple-class ]
     [ 2drop save-location ]
     [ 2drop [ ] [ '[ f _ boa , ] ] [ insn-effect ] tri define-inline ]
-    3tri ; parsing
+    3tri ;
index 8d00a14ea2142c69463605ef53404dae56607f19..908bf2475b980e154ffdf445699ccf3466f64e32 100644 (file)
@@ -99,7 +99,7 @@ SYMBOL: spill-counts
 : interval-to-spill ( active-intervals current -- live-interval )
     #! We spill the interval with the most distant use location.
     start>> '[ dup _ [ >= ] find-use nip ] { } map>assoc
-    unclip-slice [ [ [ second ] bi@ > ] most ] reduce first ;
+    [ ] [ [ [ second ] bi@ > ] most ] map-reduce first ;
 
 : assign-spill ( before after -- before after )
     #! If it has been spilled already, reuse spill location.
index 2b9d3df6f674896fb4e42a3a7759fb1e5eb17f9e..0882bed06e696d5b9fe255d9376dd5cd52ec8f83 100644 (file)
@@ -17,6 +17,6 @@ C: <ds-loc> ds-loc
 TUPLE: rs-loc < loc ;
 C: <rs-loc> rs-loc
 
-: V scan-word scan-word vreg boa parsed ; parsing
-: D scan-word <ds-loc> parsed ; parsing
-: R scan-word <rs-loc> parsed ; parsing
+SYNTAX: V scan-word scan-word vreg boa parsed ;
+SYNTAX: D scan-word <ds-loc> parsed ;
+SYNTAX: R scan-word <rs-loc> parsed ;
index d915b29ae56834b020c246983bb6b8831e6508ca..65e70bd04228565aa3ae2c39e3c74e5f4d0c56d1 100755 (executable)
@@ -3,7 +3,7 @@
 USING: namespaces make math math.order math.parser sequences accessors
 kernel kernel.private layouts assocs words summary arrays
 combinators classes.algebra alien alien.c-types alien.structs
-alien.strings alien.arrays alien.complex sets libc
+alien.strings alien.arrays alien.complex sets libc alien.libraries
 continuations.private fry cpu.architecture
 compiler.errors
 compiler.alien
@@ -53,7 +53,7 @@ SYMBOL: labels
     V{ } clone literal-table set
     V{ } clone calls set
     compiling-word set
-    compiled-stack-traces? compiling-word get f ? add-literal drop ;
+    compiled-stack-traces? [ compiling-word get add-literal ] when ;
 
 : generate ( mr -- asm )
     [
@@ -464,7 +464,7 @@ TUPLE: callback-context ;
     dup current-callback eq? [
         drop
     ] [
-        yield-hook get call wait-to-return
+        yield-hook get call( -- ) wait-to-return
     ] if ;
 
 : do-callback ( quot token -- )
index e0f391deb5f925740c9f410253bb638701f32cd2..3a047a8d3915481cb035583bce86803bbf977ed7 100755 (executable)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays byte-arrays byte-vectors generic assocs hashtables
 io.binary kernel kernel.private math namespaces make sequences
@@ -28,51 +28,47 @@ M: label-fixup fixup*
     [ label>> ] [ class>> ] bi compiled-offset 4 - rot
     3array label-table get push ;
 
-TUPLE: rel-fixup arg class type ;
+TUPLE: rel-fixup class type ;
 
-: rel-fixup ( arg class type -- ) \ rel-fixup boa , ;
+: rel-fixup ( class type -- ) \ rel-fixup boa , ;
 
 : push-4 ( value vector -- )
     [ length ] [ B{ 0 0 0 0 } swap push-all ] [ underlying>> ] tri
     swap set-alien-unsigned-4 ;
 
 M: rel-fixup fixup*
-    [ [ arg>> ] [ class>> ] [ type>> ] tri { 0 8 16 } bitfield ]
-    [ class>> rc-absolute-cell = cell 4 ? compiled-offset swap - ] bi
-    [ relocation-table get push-4 ] bi@ ;
+    [ type>> ]
+    [ class>> ]
+    [ class>> rc-absolute-cell = cell 4 ? compiled-offset swap - ] tri
+    { 0 24 28 } bitfield
+    relocation-table get push-4 ;
 
 M: integer fixup* , ;
 
-: indq ( elt seq -- n ) [ eq? ] with find drop ;
-
-: adjoin* ( obj table -- n )
-    2dup indq [ 2nip ] [ dup length [ push ] dip ] if* ;
-
 SYMBOL: literal-table
 
-: add-literal ( obj -- n ) literal-table get adjoin* ;
+: add-literal ( obj -- ) literal-table get push ;
 
 : add-dlsym-literals ( symbol dll -- )
-    [ string>symbol ] dip 2array literal-table get push-all ;
+    [ string>symbol add-literal ] [ add-literal ] bi* ;
 
 : rel-dlsym ( name dll class -- )
-    [ literal-table get length [ add-dlsym-literals ] dip ] dip
-    rt-dlsym rel-fixup ;
+    [ add-dlsym-literals ] dip rt-dlsym rel-fixup ;
 
 : rel-word ( word class -- )
     [ add-literal ] dip rt-xt rel-fixup ;
 
 : rel-primitive ( word class -- )
-    [ def>> first ] dip rt-primitive rel-fixup ;
+    [ def>> first add-literal ] dip rt-primitive rel-fixup ;
 
 : rel-immediate ( literal class -- )
     [ add-literal ] dip rt-immediate rel-fixup ;
 
 : rel-this ( class -- )
-    0 swap rt-label rel-fixup ;
+    rt-this rel-fixup ;
 
 : rel-here ( offset class -- )
-    rt-here rel-fixup ;
+    [ add-literal ] dip rt-here rel-fixup ;
 
 : init-fixup ( -- )
     BV{ } clone relocation-table set
index 9169e9e0fa38eeabf8b7624b0dfcad22abaaaf45..f19225a45c60d8ef1c0c2e2446c4662441eaa5bf 100644 (file)
@@ -12,8 +12,6 @@ ARTICLE: "compiler-usage" "Calling the optimizing compiler"
 "Normally, new word definitions are recompiled automatically. This can be changed:"
 { $subsection disable-compiler }
 { $subsection enable-compiler }
-"The optimizing compiler can be called directly, although this should not be necessary under normal circumstances:"
-{ $subsection optimized-recompile-hook }
 "Removing a word's optimized definition:"
 { $subsection decompile }
 "Compiling a single quotation:"
@@ -46,9 +44,8 @@ HELP: (compile)
 { $description "Compile a single word." }
 { $notes "This is an internal word, and user code should call " { $link compile } " instead." } ;
 
-HELP: optimized-recompile-hook
-{ $values { "words" "a sequence of words" } { "alist" "an association list" } }
-{ $description "Compile a set of words." }
+HELP: optimizing-compiler
+{ $description "Singleton class implementing " { $link recompile } " to call the optimizing compiler." }
 { $notes "This is an internal word, and user code should call " { $link compile } " instead." } ;
 
 HELP: compile-call
index 24ce3debeb3a4cf535858666d05af9e187015954..04c1a9c55fb9a69033e871f7b818a79ac4337641 100644 (file)
@@ -35,11 +35,14 @@ SYMBOLS: +optimized+ +unoptimized+ ;
     [ usage [ word? ] filter ] [ compiled-usage keys ] if
     [ queue-compile ] each ;
 
-: ripple-up? ( word status -- ? )
-    swap "compiled-status" word-prop [ = not ] keep and ;
+: ripple-up? ( status word -- ? )
+    [
+        [ nip changed-effects get key? ]
+        [ "compiled-status" word-prop eq? not ] 2bi or
+    ] keep "compiled-status" word-prop and ;
 
 : save-compiled-status ( word status -- )
-    [ dupd ripple-up? [ ripple-up ] [ drop ] if ]
+    [ over ripple-up? [ ripple-up ] [ drop ] if ]
     [ "compiled-status" set-word-prop ]
     2bi ;
 
@@ -111,7 +114,7 @@ t compile-dependencies? set-global
     ] with-return ;
 
 : compile-loop ( deque -- )
-    [ (compile) yield-hook get call ] slurp-deque ;
+    [ (compile) yield-hook get call( -- ) ] slurp-deque ;
 
 : decompile ( word -- )
     f 2array 1array modify-code-heap ;
@@ -119,7 +122,9 @@ t compile-dependencies? set-global
 : compile-call ( quot -- )
     [ dup infer define-temp ] with-compilation-unit execute ;
 
-: optimized-recompile-hook ( words -- alist )
+SINGLETON: optimizing-compiler
+
+M: optimizing-compiler recompile ( words -- alist )
     [
         <hashed-dlist> compile-queue set
         H{ } clone compiled set
@@ -129,10 +134,10 @@ t compile-dependencies? set-global
     ] with-scope ;
 
 : enable-compiler ( -- )
-    [ optimized-recompile-hook ] recompile-hook set-global ;
+    optimizing-compiler compiler-impl set-global ;
 
 : disable-compiler ( -- )
-    [ default-recompile-hook ] recompile-hook set-global ;
+    f compiler-impl set-global ;
 
 : recompile-all ( -- )
     forget-errors all-words compile ;
index e03c062e9e0249ad6485fbf21e94a92bd67309bc..b3757bf008ae4ddf0966fbdd2bf518b77b53e66b 100644 (file)
@@ -20,10 +20,10 @@ CONSTANT: deck-bits 18
 : tuple-class-offset ( -- n ) bootstrap-cell tuple tag-number - ; inline
 : class-hash-offset ( -- n ) bootstrap-cell object tag-number - ; inline
 : word-xt-offset ( -- n ) 9 bootstrap-cells object tag-number - ; inline
-: quot-xt-offset ( -- n ) 3 bootstrap-cells object tag-number - ; inline
+: quot-xt-offset ( -- n ) 5 bootstrap-cells object tag-number - ; inline
 : word-code-offset ( -- n ) 10 bootstrap-cells object tag-number - ; inline
 : array-start-offset ( -- n ) 2 bootstrap-cells object tag-number - ; inline
-: compiled-header-size ( -- n ) 4 bootstrap-cells ; inline
+: compiled-header-size ( -- n ) 5 bootstrap-cells ; inline
 
 ! Relocation classes
 CONSTANT: rc-absolute-cell    0
@@ -42,7 +42,7 @@ CONSTANT: rt-dlsym       1
 CONSTANT: rt-dispatch    2
 CONSTANT: rt-xt          3
 CONSTANT: rt-here        4
-CONSTANT: rt-label       5
+CONSTANT: rt-this        5
 CONSTANT: rt-immediate   6
 CONSTANT: rt-stack-chain 7
 
old mode 100644 (file)
new mode 100755 (executable)
index f3c2deb..4d7882a
@@ -1,10 +1,27 @@
-IN: compiler.tests
 USING: alien alien.c-types alien.syntax compiler kernel
 namespaces namespaces tools.test sequences stack-checker
 stack-checker.errors words arrays parser quotations
 continuations effects namespaces.private io io.streams.string
 memory system threads tools.test math accessors combinators
-specialized-arrays.float ;
+specialized-arrays.float alien.libraries io.pathnames
+io.backend ;
+IN: compiler.tests
+
+<<
+: libfactor-ffi-tests-path ( -- string )
+    "resource:" (normalize-path)
+    {
+        { [ os winnt? ]  [ "libfactor-ffi-test.dll" ] }
+        { [ os macosx? ] [ "libfactor-ffi-test.dylib" ] }
+        { [ os unix?  ]  [ "libfactor-ffi-test.so" ] }
+    } cond append-path ;
+
+"f-cdecl" libfactor-ffi-tests-path "cdecl" add-library
+
+"f-stdcall" libfactor-ffi-tests-path "stdcall" add-library
+>>
+
+LIBRARY: f-cdecl
 
 FUNCTION: void ffi_test_0 ;
 [ ] [ ffi_test_0 ] unit-test
@@ -107,9 +124,7 @@ unit-test
     "int" { "int" "int" "int" "int" } "stdcall" alien-indirect
     gc ;
 
-<< "f-stdcall" f "stdcall" add-library >>
-
-[ f ] [ "f-stdcall" load-library ] unit-test
+[ f ] [ "f-stdcall" load-library f = ] unit-test
 [ "stdcall" ] [ "f-stdcall" library abi>> ] unit-test
 
 : ffi_test_18 ( w x y z -- int )
@@ -149,7 +164,7 @@ FUNCTION: void ffi_test_20 double x1, double x2, double x3,
 
 : ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result y )
     "int"
-    f "ffi_test_31"
+    "f-cdecl" "ffi_test_31"
     { "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" }
     alien-invoke gc 3 ;
 
@@ -157,7 +172,7 @@ FUNCTION: void ffi_test_20 double x1, double x2, double x3,
 
 : ffi_test_31_point_5 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result )
     "float"
-    f "ffi_test_31_point_5"
+    "f-cdecl" "ffi_test_31_point_5"
     { "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" }
     alien-invoke ;
 
index 6c6d580c877e13b9d8d4b381db1170b08b1a4701..93860db92475b13cc32980a61c7db294c34147b9 100644 (file)
@@ -270,7 +270,7 @@ cell 8 = [
 ] when
 
 ! Some randomized tests
-: compiled-fixnum* fixnum* ;
+: compiled-fixnum* ( a b -- c ) fixnum* ;
 
 [ ] [
     10000 [ 
@@ -281,7 +281,7 @@ cell 8 = [
     ] times
 ] unit-test
 
-: compiled-fixnum>bignum fixnum>bignum ;
+: compiled-fixnum>bignum ( a -- b ) fixnum>bignum ;
 
 [ bignum ] [ 0 compiled-fixnum>bignum class ] unit-test
 
@@ -293,7 +293,7 @@ cell 8 = [
     ] times
 ] unit-test
 
-: compiled-bignum>fixnum bignum>fixnum ;
+: compiled-bignum>fixnum ( a -- b ) bignum>fixnum ;
 
 [ ] [
     10000 [
index b5cb0ddbdbe4561c9ccd47de2a781ece20d63bb7..3aed47ae7e73a329a1be22c8211d58990235b80b 100644 (file)
@@ -13,7 +13,7 @@ M: array xyz xyz ;
 [ t ] [ \ xyz optimized>> ] unit-test
 
 ! Test predicate inlining
-: pred-test-1
+: pred-test-1 ( a -- b c )
     dup fixnum? [
         dup integer? [ "integer" ] [ "nope" ] if
     ] [
@@ -24,7 +24,7 @@ M: array xyz xyz ;
 
 TUPLE: pred-test ;
 
-: pred-test-2
+: pred-test-2 ( a -- b c )
     dup tuple? [
         dup pred-test? [ "pred-test" ] [ "nope" ] if
     ] [
@@ -33,7 +33,7 @@ TUPLE: pred-test ;
 
 [ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-2 ] unit-test
 
-: pred-test-3
+: pred-test-3 ( a -- b c )
     dup pred-test? [
         dup tuple? [ "pred-test" ] [ "nope" ] if
     ] [
@@ -42,14 +42,14 @@ TUPLE: pred-test ;
 
 [ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-3 ] unit-test
 
-: inline-test
+: inline-test ( a -- b )
     "nom" = ;
 
 [ t ] [ "nom" inline-test ] unit-test
 [ f ] [ "shayin" inline-test ] unit-test
 [ f ] [ 3 inline-test ] unit-test
 
-: fixnum-declarations >fixnum 24 shift 1234 bitxor ;
+: fixnum-declarations ( a -- b ) >fixnum 24 shift 1234 bitxor ;
 
 [ ] [ 1000000 fixnum-declarations . ] unit-test
 
@@ -61,13 +61,13 @@ TUPLE: pred-test ;
 
 ! regression
 
-: bad-kill-1 ( a b -- c d e ) [ 3 f ] [ dup bad-kill-1 ] if ; inline
-: bad-kill-2 bad-kill-1 drop ;
+: bad-kill-1 ( a b -- c d e ) [ 3 f ] [ dup bad-kill-1 ] if ; inline recursive
+: bad-kill-2 ( a b -- c d ) bad-kill-1 drop ;
 
 [ 3 ] [ t bad-kill-2 ] unit-test
 
 ! regression
-: (the-test) ( x -- y ) dup 0 > [ 1- (the-test) ] when ; inline
+: (the-test) ( x -- y ) dup 0 > [ 1- (the-test) ] when ; inline recursive
 : the-test ( -- x y ) 2 dup (the-test) ;
 
 [ 2 0 ] [ the-test ] unit-test
@@ -77,7 +77,7 @@ TUPLE: pred-test ;
     < [
         6 1 (double-recursion)
         3 2 (double-recursion)
-    ] when ; inline
+    ] when ; inline recursive
 
 : double-recursion ( -- ) 0 2 (double-recursion) ;
 
@@ -85,7 +85,7 @@ TUPLE: pred-test ;
 
 ! regression
 : double-label-1 ( a b c -- d )
-    [ f double-label-1 ] [ swap nth-unsafe ] if ; inline
+    [ f double-label-1 ] [ swap nth-unsafe ] if ; inline recursive
 
 : double-label-2 ( a -- b )
     dup array? [ ] [ ] if 0 t double-label-1 ;
@@ -100,7 +100,7 @@ GENERIC: void-generic ( obj -- * )
 
 ! regression
 : branch-fold-regression-0 ( m -- n )
-    t [ ] [ 1+ branch-fold-regression-0 ] if ; inline
+    t [ ] [ 1+ branch-fold-regression-0 ] if ; inline recursive
 
 : branch-fold-regression-1 ( -- m )
     10 branch-fold-regression-0 ;
@@ -224,7 +224,7 @@ USE: binary-search.private
 ] unit-test
 
 ! Regression
-: empty-compound ;
+: empty-compound ( -- ) ;
 
 : node-successor-f-bug ( x -- * )
     [ 3 throw ] [ empty-compound ] compose [ 3 throw ] if ;
@@ -293,7 +293,7 @@ HINTS: recursive-inline-hang-3 array ;
 
 ! Wow
 : counter-example ( a b c d -- a' b' c' d' )
-    dup 0 > [ 1 - [ rot 2 * ] dip counter-example ] when ; inline
+    dup 0 > [ 1 - [ rot 2 * ] dip counter-example ] when ; inline recursive
 
 : counter-example' ( -- a' b' c' d' )
     1 2 3.0 3 counter-example ;
diff --git a/basis/compiler/tests/redefine15.factor b/basis/compiler/tests/redefine15.factor
new file mode 100644 (file)
index 0000000..797460a
--- /dev/null
@@ -0,0 +1,20 @@
+USING: compiler.units words tools.test math kernel ;
+IN: compiler.tests.redefine15
+
+DEFER: word-1
+
+: word-2 ( a -- b ) word-1 ;
+
+[ \ word-1 [ ] (( a -- b )) define-declared ] with-compilation-unit 
+
+[ "a" ] [ "a" word-2 ] unit-test
+
+: word-3 ( a -- b ) 1 + ;
+
+: word-4 ( a -- b c ) 0 swap word-3 swap 1+ ;
+
+[ 1 1 ] [ 0 word-4 ] unit-test
+
+[ \ word-3 [ [ 2 + ] bi@ ] (( a b -- c d )) define-declared ] with-compilation-unit
+
+[ 2 3 ] [ 0 word-4 ] unit-test
\ No newline at end of file
index d6e90187feb8ed10997b9215955836c6f81f992b..5a28b282618dc83f9e91301fc85e6dd1b18e9eb0 100644 (file)
@@ -1,12 +1,14 @@
 IN: compiler.tests
 USING: compiler compiler.units tools.test math parser kernel
 sequences sequences.private classes.mixin generic definitions
-arrays words assocs eval ;
+arrays words assocs eval words.symbol ;
 
 DEFER: redefine2-test
 
 [ ] [ "USE: sequences USE: kernel IN: compiler.tests TUPLE: redefine2-test ; M: redefine2-test nth 2drop 3 ; INSTANCE: redefine2-test sequence" eval ] unit-test
 
+[ t ] [ \ redefine2-test symbol? ] unit-test
+
 [ t ] [ redefine2-test new sequence? ] unit-test
 
 [ 3 ] [ 0 redefine2-test new nth-unsafe ] unit-test
index cfbea3bcb92c9e060e932876a86cdf1faa47f2cb..b317ed3eb5e5ef6a606625919540b1a9cecf020b 100755 (executable)
@@ -14,7 +14,7 @@ words splitting grouping sorting accessors ;
 [ t ] [
     symbolic-stack-trace
     [ word? ] filter
-    { baz bar foo throw } tail?
+    { baz bar foo } tail?
 ] unit-test
 
 : bleh ( seq -- seq' ) [ 3 + ] map [ 0 > ] filter ;
index e451694f480b05d80e145787d0599c1b9096979b..7de092d84aac6608b50e6b0a61f2318deb392f7b 100755 (executable)
@@ -90,7 +90,7 @@ M: object xyz ;
         [ swap [ call 1+ ] dip ] keep (i-repeat)
     ] if ; inline recursive
 
-: i-repeat [ { integer } declare ] dip 0 -rot (i-repeat) ; inline
+: i-repeat ( n quot -- ) [ { integer } declare ] dip 0 -rot (i-repeat) ; inline
 
 [ t ] [
     [ [ dup xyz drop ] i-repeat ] \ xyz inlined?
@@ -197,7 +197,7 @@ M: fixnum annotate-entry-test-1 drop ;
         [ dup annotate-entry-test-1 1+ ] dip (annotate-entry-test-2)
     ] if ; inline recursive
 
-: annotate-entry-test-2 0 -rot (annotate-entry-test-2) ; inline
+: annotate-entry-test-2 ( from to -- ) 0 -rot (annotate-entry-test-2) ; inline
 
 [ f ] [
     [ { bignum } declare annotate-entry-test-2 ]
index eb0bbd5ce638299c5a867d33bf29b659f12a518c..9b4a6da12a50ebbf9085e9d573f418dfc61d0294 100644 (file)
@@ -1,5 +1,8 @@
 IN: compiler.tree.debugger.tests
-USING: compiler.tree.debugger tools.test ;
+USING: compiler.tree.debugger tools.test sorting sequences io math.order ;
 
 \ optimized. must-infer
 \ optimizer-report. must-infer
+
+[ [ <=> ] sort ] optimized.
+[ <reversed> [ print ] each ] optimizer-report.
\ No newline at end of file
index 188dcdb93598384281fb4e95e163d0ada87353e9..8e102e0ea3cc9bc6da4dd3b768ad5d9ac1d852ad 100644 (file)
@@ -130,8 +130,6 @@ M: node node>quot drop ;
 
 GENERIC: optimized. ( quot/word -- )
 
-M: method-spec optimized. first2 method optimized. ;
-
 M: word optimized. specialized-def optimized. ;
 
 M: callable optimized. build-tree optimize-tree nodes>quot . ;
@@ -160,7 +158,7 @@ SYMBOL: node-count
                     { [ dup generic? ] [ generics-called ] }
                     { [ dup method-body? ] [ methods-called ] }
                     [ words-called ]
-                } cond inc-at
+                } cond get inc-at
             ] [ drop ] if
         ] each-node
         node-count set
index c56db570b21735c1c0574d45ccec102ec1ccd00c..a22b7aa1727f70f801c062b5a16279fffac94a17 100644 (file)
@@ -238,7 +238,7 @@ DEFER: (value-info-union)
 
 : value-infos-union ( infos -- info )
     [ null-info ]
-    [ unclip-slice [ value-info-union ] reduce ] if-empty ;
+    [ [ ] [ value-info-union ] map-reduce ] if-empty ;
 
 : literals<= ( info1 info2 -- ? )
     {
index 953956c3bd20b738be8a6e685f28e2c42e1d21f0..f18cfcd3a3aad1e48c56ddd3d12a4c0cf5798fb5 100755 (executable)
@@ -1,6 +1,6 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel arrays sequences math math.order call
+USING: accessors kernel arrays sequences math math.order
 math.partial-dispatch generic generic.standard generic.math
 classes.algebra classes.union sets quotations assocs combinators
 words namespaces continuations classes fry combinators.smart
index ecfd415579cee80deb784703965793f2bc7747e0..1b5d38335383df7f44ea2366e2615365d30e0992 100644 (file)
@@ -312,7 +312,7 @@ generic-comparison-ops [
 \ clone [
     in-d>> first value-info literal>> {
         { V{ } [ [ drop { } 0 vector boa ] ] }
-        { H{ } [ [ drop hashtable new ] ] }
+        { H{ } [ [ drop 0 <hashtable> ] ] }
         [ drop f ]
     } case
 ] "custom-inlining" set-word-prop
index d369c22e4c4b6bf0936167bcf3a525d193a8791c..a472f9a2fe85479c52d161f48ca05abfedf91a46 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax combinators system ;
+USING: alien alien.syntax combinators system alien.libraries ;
 IN: compression.zlib.ffi
 
 << "zlib" {
index 11e624110c634e790eb1d88cd4ba41f20c84da91..ad00bbdfa9ff262ca7f36af3248efc478c81f4c5 100644 (file)
@@ -20,10 +20,12 @@ IN: concurrency.conditions
         ]\r
     ] dip later ;\r
 \r
+ERROR: wait-timeout ;\r
+\r
 : wait ( queue timeout status -- )\r
     over [\r
         [ queue-timeout [ drop ] ] dip suspend\r
-        [ "Timeout" throw ] [ cancel-alarm ] if\r
+        [ wait-timeout ] [ cancel-alarm ] if\r
     ] [\r
         [ drop '[ _ push-front ] ] dip suspend drop\r
     ] if ;\r
index 64971eeb77c95f7b45322d4987efd1bd4038a9d2..81e54f18078d907f7740ec97dafd371140eaf837 100644 (file)
@@ -1,6 +1,6 @@
 IN: concurrency.mailboxes.tests\r
-USING: concurrency.mailboxes concurrency.count-downs vectors\r
-sequences threads tools.test math kernel strings namespaces\r
+USING: concurrency.mailboxes concurrency.count-downs concurrency.conditions\r
+vectors sequences threads tools.test math kernel strings namespaces\r
 continuations calendar destructors ;\r
 \r
 { 1 1 } [ [ integer? ] mailbox-get? ] must-infer-as\r
@@ -75,3 +75,15 @@ continuations calendar destructors ;
 [ ] [ "d" get 5 seconds await-timeout ] unit-test\r
 \r
 [ ] [ "m" get dispose ] unit-test\r
+\r
+[ { "foo" "bar" } ] [\r
+    <mailbox>\r
+    "foo" over mailbox-put\r
+    "bar" over mailbox-put\r
+    mailbox-get-all\r
+] unit-test\r
+\r
+[\r
+    <mailbox> 1 seconds mailbox-get-timeout\r
+] [ wait-timeout? ] must-fail-with\r
+    
\ No newline at end of file
index f6aec94b4140de12537dbc0e9e8a83bfe3c79a51..200adb14aea9148793785c66458504ce70e6e8e7 100755 (executable)
@@ -49,7 +49,7 @@ M: mailbox dispose* threads>> notify-all ;
 \r
 : mailbox-get-all-timeout ( mailbox timeout -- array )\r
     block-if-empty\r
-    [ dup mailbox-empty? ]\r
+    [ dup mailbox-empty? not ]\r
     [ dup data>> pop-back ]\r
     produce nip ;\r
 \r
index 2eab91310ff7f37d0d70114d4142bfde6e4b4b9e..7a98cd5e0a905baf7f975cec6df1a421825f4400 100644 (file)
@@ -16,8 +16,8 @@ MACRO: set-slots ( slots -- quot )
     [ [ in>> '[ _ _ construct ] ] dip compose ] [ drop ] 2bi
     define-declared ;
 
-: CONSTRUCTOR:
+SYNTAX: CONSTRUCTOR:
     scan-word [ name>> "<" ">" surround create-in ] keep
-    "(" expect ")" parse-effect
+    complete-effect
     parse-definition
-    define-constructor ; parsing
\ No newline at end of file
+    define-constructor ;
\ No newline at end of file
index 06b9c6407bddf3647bc802296d132a6e3e76e76b..46f6639ab8f4b6b57693659944b1ec591dc9c092 100644 (file)
@@ -167,7 +167,7 @@ SYMBOL: event-stream-callbacks
     eventFlags numEvents <direct-int-array>
     eventIds numEvents <direct-longlong-array>
     3array flip
-    info event-stream-callbacks get at [ drop ] or call ;
+    info event-stream-callbacks get at [ drop ] or call( changes -- ) ;
 
 : master-event-source-callback ( -- alien )
     "void"
index 21f3d7efd44771f7687a38510575212a3daea7b8..413709d142ee2fbddf49dc243b69446df4160ac1 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.syntax alien.strings io.encodings.string kernel
 sequences byte-arrays io.encodings.utf8 math core-foundation
-core-foundation.arrays destructors unicode.data ;
+core-foundation.arrays destructors ;
 IN: core-foundation.strings
 
 TYPEDEF: void* CFStringRef
@@ -62,7 +62,7 @@ FUNCTION: CFStringRef CFStringCreateWithCString (
 : prepare-CFString ( string -- byte-array )
     [
         dup HEX: 10ffff >
-        [ drop CHAR: replacement-character ] when
+        [ drop HEX: fffd ] when
     ] map utf8 encode ;
 
 : <CFString> ( string -- alien )
diff --git a/basis/core-graphics/core-graphics-docs.factor b/basis/core-graphics/core-graphics-docs.factor
deleted file mode 100644 (file)
index e69de29..0000000
index 8c085d40be3094e41ac7ffb26ab63353e0b90743..d3b1352750a20ede8721e6433e9be054f12dd342 100644 (file)
@@ -1,9 +1,10 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: words parser alien alien.c-types kernel fry accessors ;
+USING: words parser alien alien.c-types kernel fry accessors
+alien.libraries ;
 IN: core-text.utilities
 
-: C-GLOBAL:
+SYNTAX: C-GLOBAL:
     CREATE-WORD
     dup name>> '[ _ f dlsym *void* ]
-    (( -- value )) define-declared ; parsing
+    (( -- value )) define-declared ;
index c6a3a941949dfb0eca459d232c75056500b4a53e..befbe112bd0d248fa46d4404eb5feb82d8170471 100644 (file)
@@ -21,7 +21,7 @@ IN: cpu.ppc.assembler.backend
 : define-d-insn ( word opcode -- )
     [ d-insn ] curry (( d a simm -- )) define-declared ;
 
-: D: CREATE scan-word define-d-insn ; parsing
+SYNTAX: D: CREATE scan-word define-d-insn ;
 
 : sd-insn ( d a simm opcode -- )
     [ s>u16 { 0 21 16 } bitfield ] dip insn ;
@@ -29,7 +29,7 @@ IN: cpu.ppc.assembler.backend
 : define-sd-insn ( word opcode -- )
     [ sd-insn ] curry (( d a simm -- )) define-declared ;
 
-: SD: CREATE scan-word define-sd-insn ; parsing
+SYNTAX: SD: CREATE scan-word define-sd-insn ;
 
 : i-insn ( li aa lk opcode -- )
     [ { 0 1 0 } bitfield ] dip insn ;
@@ -40,26 +40,26 @@ IN: cpu.ppc.assembler.backend
 : (X) ( -- word quot )
     CREATE scan-word scan-word scan-word [ x-insn ] 3curry ;
 
-: X: (X) (( a s b -- )) define-declared ; parsing
+SYNTAX: X: (X) (( a s b -- )) define-declared ;
 
 : (1) ( quot -- quot' ) [ 0 ] prepose ;
 
-: X1: (X) (1) (( a s -- )) define-declared ; parsing
+SYNTAX: X1: (X) (1) (( a s -- )) define-declared ;
 
 : xfx-insn ( d spr xo opcode -- )
     [ { 1 11 21 } bitfield ] dip insn ;
 
 : CREATE-MF ( -- word ) scan "MF" prepend create-in ;
 
-: MFSPR:
+SYNTAX: MFSPR:
     CREATE-MF scan-word 5 shift [ 339 31 xfx-insn ] curry
-    (( d -- )) define-declared ; parsing
+    (( d -- )) define-declared ;
 
 : CREATE-MT ( -- word ) scan "MT" prepend create-in ;
 
-: MTSPR:
+SYNTAX: MTSPR:
     CREATE-MT scan-word 5 shift [ 467 31 xfx-insn ] curry
-    (( d -- )) define-declared ; parsing
+    (( d -- )) define-declared ;
 
 : xo-insn ( d a b oe rc xo opcode -- )
     [ { 1 0 10 11 16 21 } bitfield ] dip insn ;
@@ -68,9 +68,9 @@ IN: cpu.ppc.assembler.backend
     CREATE scan-word scan-word scan-word scan-word
     [ xo-insn ] 2curry 2curry ;
 
-: XO: (XO) (( a s b -- )) define-declared ; parsing
+SYNTAX: XO: (XO) (( a s b -- )) define-declared ;
 
-: XO1: (XO) (1) (( a s -- )) define-declared ; parsing
+SYNTAX: XO1: (XO) (1) (( a s -- )) define-declared ;
 
 GENERIC# (B) 2 ( dest aa lk -- )
 M: integer (B) 18 i-insn ;
@@ -84,11 +84,11 @@ M: label BC [ 0 BC ] dip rc-relative-ppc-2 label-fixup ;
 
 : CREATE-B ( -- word ) scan "B" prepend create-in ;
 
-: BC:
+SYNTAX: BC:
     CREATE-B scan-word scan-word
-    [ rot BC ] 2curry (( c -- )) define-declared ; parsing
+    [ rot BC ] 2curry (( c -- )) define-declared ;
 
-: B:
+SYNTAX: B:
     CREATE-B scan-word scan-word scan-word scan-word scan-word
     [ b-insn ] curry curry curry curry curry
-    (( bo -- )) define-declared ; parsing
+    (( bo -- )) define-declared ;
index b27f3aee72b0f7940405ce65572943d501af3ce4..ec7bf8f34185a1cba1b73692a624b7b4e76cdb77 100644 (file)
@@ -11,8 +11,8 @@ big-endian on
 \r
 4 jit-code-format set\r
 \r
-: ds-reg 29 ;\r
-: rs-reg 30 ;\r
+CONSTANT: ds-reg 29\r
+CONSTANT: rs-reg 30\r
 \r
 : factor-area-size ( -- n ) 4 bootstrap-cells ;\r
 \r
@@ -41,7 +41,7 @@ big-endian on
     stack-frame 6 LI\r
     6 1 next-save STW\r
     0 1 lr-save stack-frame + STW\r
-] rc-absolute-ppc-2/2 rt-label 1 jit-prolog jit-define\r
+] rc-absolute-ppc-2/2 rt-this 1 jit-prolog jit-define\r
 \r
 [\r
     0 6 LOAD32\r
index 8b6b4fbb11cc356e09426134ce71c28ad975df78..85bf188bb81298731d3bdf46f9575ffaa85ce836 100644 (file)
@@ -659,13 +659,40 @@ M: ppc %callback-value ( ctype -- )
 
 M: ppc small-enough? ( n -- ? ) -32768 32767 between? ;
 
-M: ppc return-struct-in-registers? ( c-type -- ? ) drop f ;
-
-M: ppc %box-small-struct
-    drop "No small structs" throw ;
-
-M: ppc %unbox-small-struct
-    drop "No small structs" throw ;
+M: ppc return-struct-in-registers? ( c-type -- ? )
+    c-type return-in-registers?>> ;
+
+M: ppc %box-small-struct ( c-type -- )
+    #! Box a <= 16-byte struct returned in r3:r4:r5:r6
+    heap-size 7 LI
+    "box_medium_struct" f %alien-invoke ;
+
+: %unbox-struct-1 ( -- )
+    ! Alien must be in r3.
+    "alien_offset" f %alien-invoke
+    3 3 0 LWZ ;
+
+: %unbox-struct-2 ( -- )
+    ! Alien must be in r3.
+    "alien_offset" f %alien-invoke
+    4 3 4 LWZ
+    3 3 0 LWZ ;
+
+: %unbox-struct-4 ( -- )
+    ! Alien must be in r3.
+    "alien_offset" f %alien-invoke
+    6 3 12 LWZ
+    5 3 8 LWZ
+    4 3 4 LWZ
+    3 3 0 LWZ ;
+
+M: ppc %unbox-small-struct ( size -- )
+    #! Alien must be in EAX.
+    heap-size cell align cell /i {
+        { 1 [ %unbox-struct-1 ] }
+        { 2 [ %unbox-struct-2 ] }
+        { 4 [ %unbox-struct-4 ] }
+    } case ;
 
 USE: vocabs.loader
 
@@ -673,3 +700,5 @@ USE: vocabs.loader
     { [ os macosx? ] [ "cpu.ppc.macosx" require ] }
     { [ os linux? ] [ "cpu.ppc.linux" require ] }
 } cond
+
+"complex-double" c-type t >>return-in-registers? drop
index f881792ac60007440f7815f9800f9c69e6e261b0..b280afc01e93bfcf152a0133fdaaeda71398fbf0 100755 (executable)
@@ -309,8 +309,7 @@ FUNCTION: bool check_sse2 ( ) ;
     check_sse2 ;
 
 "-no-sse2" (command-line) member? [
-    [ optimized-recompile-hook ] recompile-hook
-    [ { check_sse2 } compile ] with-variable
+    optimizing-compiler compiler-impl [ { check_sse2 } compile ] with-variable
 
     "Checking if your CPU supports SSE2..." print flush
     sse2? [
index 343850f9e639dc47ffb8bb59947cb1e868721de9..631dcaa8f7d3536fae6f9d169f407a523a3c20bb 100644 (file)
@@ -11,5 +11,4 @@ IN: cpu.x86.assembler.syntax
 : define-registers ( names size -- )
     '[ _ define-register ] each-index ;
 
-: REGISTERS: ( -- )
-    scan-word ";" parse-tokens swap define-registers ; parsing
+SYNTAX: REGISTERS: scan-word ";" parse-tokens swap define-registers ;
index 5e3405e93ad80fe5544787b57021762fcd0f5dc7..f5829d76ea267edf32f21c9090574df1b5ac2ca9 100644 (file)
@@ -32,7 +32,7 @@ big-endian off
     temp0 PUSH
     ! alignment
     stack-reg stack-frame-size 3 bootstrap-cells - SUB
-] rc-absolute-cell rt-label 1 rex-length + jit-prolog jit-define
+] rc-absolute-cell rt-this 1 rex-length + jit-prolog jit-define
 
 [
     ! load literal
index c392ec6b8514a894db0ba1ab6b46cdfb52cf7685..154d8961a2d93afd30354275ec10089bf131aa06 100644 (file)
@@ -279,7 +279,7 @@ ARTICLE: "db-custom-database-combinators" "Custom database combinators"
 
 "SQLite example combinator:"
 { $code <"
-USING: db.sqlite db io.files ;
+USING: db.sqlite db io.files io.files.temp ;
 : with-sqlite-db ( quot -- )
     "my-database.db" temp-file <sqlite-db> swap with-db ; inline"> } 
 
index 96b72b8865a224f563345dbbbe218c4e1bd4f5ae..bd523b38e6d81a887ab9f3db2ce5e9653b50e0c3 100644 (file)
@@ -149,4 +149,4 @@ M: db-connection rollback-transaction ( -- ) "ROLLBACK" sql-command ;
     t in-transaction [
         begin-transaction
         [ ] [ rollback-transaction ] cleanup commit-transaction
-    ] with-variable ;
+    ] with-variable ; inline
index c247a36257b20032a4bb1c385c1e27e41c908213..c73409b850b576aeb0231f34f63634f9e9af0ae7 100644 (file)
@@ -4,7 +4,8 @@ USING: accessors combinators db kernel sequences peg.ebnf
 strings db.errors ;
 IN: db.errors.sqlite
 
-ERROR: unparsed-sqlite-error error ;
+TUPLE: unparsed-sqlite-error error ;
+C: <unparsed-sqlite-error> unparsed-sqlite-error
 
 SINGLETONS: table-exists table-missing ;
 
@@ -22,4 +23,6 @@ SqliteError =
       => [[ table >string message sqlite-table-error ]]
     | "no such table: " .+:table
       => [[ table >string <sql-table-missing> ]]
+    | .*:error
+      => [[ error >string <unparsed-sqlite-error> ]]
 ;EBNF
index fc407b06bd2f4d81c5c675b8e5f211214e2e881f..93f93c9a13ce1952fbc7d1961155be7b13d9bfb7 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2007, 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 ! tested on debian linux with postgresql 8.1
-USING: alien alien.syntax combinators system ;
+USING: alien alien.syntax combinators system alien.libraries ;
 IN: db.postgresql.ffi
 
 << "postgresql" {
index 2730340bfc11c376936e7b19da3989336c47886f..c4aa47d383b3a1281ff091887449bb6e6ad39be6 100755 (executable)
@@ -4,7 +4,7 @@ USING: accessors kernel math namespaces make sequences random
 strings math.parser math.intervals combinators math.bitwise
 nmake db db.tuples db.types classes words shuffle arrays
 destructors continuations db.tuples.private prettyprint
-db.private ;
+db.private byte-arrays ;
 IN: db.queries
 
 GENERIC: where ( specs obj -- )
@@ -115,6 +115,9 @@ M: sequence where ( spec obj -- )
         [ " or " 0% ] [ dupd where ] interleave drop
     ] in-parens ;
 
+M: byte-array where ( spec obj -- )
+    over column-name>> 0% " = " 0% bind# ;
+
 M: NULL where ( spec obj -- )
     drop column-name>> 0% " is NULL" 0% ;
 
index 341995634e1a971cfc0032d6f939a9602489686b..61394391a00cc5b285ba30e406bc58f0d83e68e9 100644 (file)
@@ -3,7 +3,7 @@
 ! An interface to the sqlite database. Tested against sqlite v3.1.3.
 ! Not all functions have been wrapped.
 USING: alien compiler kernel math namespaces sequences strings alien.syntax
-    system combinators alien.c-types ;
+system combinators alien.c-types alien.libraries ;
 IN: db.sqlite.ffi
 
 << "sqlite" {
index af77ce6ac1ced820de85ac2f3c378835d5534a87..d4a58fa4fcaa195e876832256f11226bf577ff60 100644 (file)
@@ -285,7 +285,7 @@ paste "PASTE"
 [ test-cascade ] test-postgresql
 [ test-restrict ] test-postgresql
 
-: test-repeated-insert
+: test-repeated-insert ( -- )
     [ ] [ person ensure-table ] unit-test
     [ ] [ person1 get insert-tuple ] unit-test
     [ person1 get insert-tuple ] must-fail ;
@@ -458,7 +458,7 @@ TUPLE: bignum-test id m n o ;
         swap >>n
         swap >>m ;
 
-: test-bignum
+: test-bignum ( -- )
     bignum-test "BIGNUM_TEST"
     {
         { "id" "ID" +db-assigned-id+ }
@@ -478,7 +478,7 @@ TUPLE: bignum-test id m n o ;
 TUPLE: secret n message ;
 C: <secret> secret
 
-: test-random-id
+: test-random-id ( -- )
     secret "SECRET"
     {
         { "n" "ID" +random-id+ system-random-generator }
@@ -634,3 +634,22 @@ compound-foo "COMPOUND_FOO"
 
 [ test-compound-primary-key ] test-sqlite
 [ test-compound-primary-key ] test-postgresql
+
+
+TUPLE: example id data ;
+
+example "EXAMPLE"
+{
+    { "id" "ID" +db-assigned-id+ }
+    { "data" "DATA" BLOB }
+} define-persistent
+
+: test-blob-select ( -- )
+    example ensure-table
+    [ ] [ example new B{ 1 2 3 4 5 } >>data insert-tuple ] unit-test
+    [
+        T{ example { id 1 } { data B{ 1 2 3 4 5 } } }
+    ] [ example new B{ 1 2 3 4 5 } >>data select-tuple ] unit-test ;
+
+[ test-blob-select ] test-sqlite
+[ test-blob-select ] test-postgresql
index 30c9fd37abf529c106699bfe84bd1a84e1a460ca..ff5869efab5c9634627dc6df81398e6f000f860b 100644 (file)
@@ -1,6 +1,7 @@
 USING: alien arrays generic generic.math help.markup help.syntax
 kernel math memory strings sbufs vectors io io.files classes
-help generic.standard continuations io.files.private listener ;
+help generic.standard continuations io.files.private listener
+alien.libraries ;
 IN: debugger
 
 ARTICLE: "debugger" "The debugger"
index 627fd953843f1e361ce3a874da3dc20e3c085a40..efd35ab2803055b47556bbf552bc73c1e7d991c9 100644 (file)
@@ -325,3 +325,5 @@ M: bad-literal-tuple summary drop "Bad literal tuple" ;
 M: check-mixin-class summary drop "Not a mixin class" ;
 
 M: not-found-in-roots summary drop "Cannot resolve vocab: path" ;
+
+M: wrong-values summary drop "Quotation called with wrong stack effect" ;
\ No newline at end of file
diff --git a/basis/definitions/icons/icons-docs.factor b/basis/definitions/icons/icons-docs.factor
new file mode 100644 (file)
index 0000000..8bca46b
--- /dev/null
@@ -0,0 +1,12 @@
+IN: definitions.icons
+USING: help.markup help.syntax ;
+
+ARTICLE: "definitions.icons" "Definition icons"
+"The " { $vocab-link "definitions.icons" } " vocabulary associates common definition types with icons."
+{ $definition-icons }
+"Looking up the icon associated with a definition:"
+{ $subsection definition-icon }
+"Defining new icons:"
+{ $subsection POSTPONE: ICON: } ;
+
+ABOUT: "definitions.icons"
\ No newline at end of file
index fb25ccf7151bc5b83163427e441fb588b8290f11..7562658ea4bc0c02aad399d2a5c489ad78cde9b1 100644 (file)
@@ -2,22 +2,29 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs classes.predicate fry generic io.pathnames kernel
 macros sequences vocabs words words.symbol words.constant
-lexer parser help.topics ;
+lexer parser help.topics help.markup namespaces sorting ;
 IN: definitions.icons
 
 GENERIC: definition-icon ( definition -- path )
 
-<PRIVATE
-
 : definition-icon-path ( string -- string' )
-    "resource:basis/definitions/icons/" prepend-path ".tiff" append ;
+    "vocab:definitions/icons/" prepend-path ".tiff" append ;
 
 <<
 
-: ICON:
-    scan-word \ definition-icon create-method
-    scan '[ drop _ definition-icon-path ]
-    define ; parsing
+SYMBOL: icons
+
+icons [ H{ } clone ] initialize
+
+: define-icon ( class name -- )
+    [ swap icons get set-at ]
+    [
+        [ \ definition-icon create-method ]
+        [ '[ drop _ definition-icon-path ] ] bi*
+        define
+    ] 2bi ;
+
+SYNTAX: ICON: scan-word scan define-icon ;
 
 >>
 
@@ -29,12 +36,15 @@ ICON: primitive primitive-word
 ICON: symbol symbol-word
 ICON: constant constant-word
 ICON: word normal-word
-ICON: vocab-link unopen-vocab
 ICON: word-link word-help-article
 ICON: link help-article
+ICON: runnable-vocab runnable-vocab
+ICON: vocab open-vocab
+ICON: vocab-link unopen-vocab
 
-PRIVATE>
-
-M: vocab definition-icon
-    vocab-main "runnable-vocab" "open-vocab" ? definition-icon-path ;
-    
\ No newline at end of file
+: $definition-icons ( element -- )
+    drop
+    icons get >alist sort-keys
+    [ [ <$link> ] [ definition-icon-path <$image> ] bi* swap ] assoc-map
+    { "" "Definition class" } prefix
+    $table ;
\ No newline at end of file
index 9bf07a5330a556dad88bbb3cb5ed8a65d333e187..cf822b40a351f25e2a92c7893b6342b3546369aa 100644 (file)
@@ -41,13 +41,13 @@ M: hello bing hello-test ;
 
 [ "USING: delegate ;\nIN: delegate.tests\nPROTOCOL: baz foo bar { whoa 1 } ; inline\n" ] [ [ baz see ] with-string-writer ] unit-test
 
-GENERIC: one
+GENERIC: one ( a -- b )
 M: integer one ;
-GENERIC: two
+GENERIC: two ( a -- b )
 M: integer two ;
-GENERIC: three
+GENERIC: three ( a -- b )
 M: integer three ;
-GENERIC: four
+GENERIC: four ( a -- b )
 M: integer four ;
 
 PROTOCOL: alpha one two ;
index 0c16b7c336e0647aee9bc48515998bdf5397cf0c..fe6ea03794f01fa5e9578ee4c789260dbc3e2ee2 100644 (file)
@@ -85,9 +85,9 @@ PRIVATE>
 : define-consult ( consultation -- )
     [ register-consult ] [ consult-methods ] bi ;
 
-: CONSULT:
+SYNTAX: CONSULT:
     scan-word scan-word parse-definition <consultation>
-    [ save-location ] [ define-consult ] bi ; parsing
+    [ save-location ] [ define-consult ] bi ;
 
 M: consultation where loc>> ;
 
@@ -144,8 +144,8 @@ PRIVATE>
         [ initialize-protocol-props ] 2tri
     ] 2bi ;
 
-: PROTOCOL:
-    CREATE-WORD parse-definition define-protocol ; parsing
+SYNTAX: PROTOCOL:
+    CREATE-WORD parse-definition define-protocol ;
 
 PREDICATE: protocol < word protocol-words ; ! Subclass of symbol?
 
@@ -159,7 +159,7 @@ M: protocol definer drop \ PROTOCOL: \ ; ;
 
 M: protocol group-words protocol-words ;
 
-: SLOT-PROTOCOL:
+SYNTAX: SLOT-PROTOCOL:
     CREATE-WORD ";" parse-tokens
     [ [ reader-word ] [ writer-word ] bi 2array ] map concat
-    define-protocol ; parsing
\ No newline at end of file
+    define-protocol ;
\ No newline at end of file
index f568a3e3885b09285c3a02c7b16dc895348d6fd8..40054bc4b0f721858c81efe706880855898d83d3 100644 (file)
@@ -1,7 +1,6 @@
 ! Copyright (C) 2007 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: delegate sequences.private sequences assocs
-io definitions kernel continuations ;
+USING: delegate sequences.private sequences assocs io ;
 IN: delegate.protocols
 
 PROTOCOL: sequence-protocol
@@ -19,7 +18,3 @@ stream-read-until ;
 
 PROTOCOL: output-stream-protocol
 stream-flush stream-write1 stream-write stream-nl ;
-
-PROTOCOL: definition-protocol
-where set-where forget uses
-synopsis* definer definition ;
index a3f05d7a715a86b41d1313064c5e0df28b002739..9b323ae8e9749af200ce892b644d20bac11b0477 100644 (file)
@@ -3,68 +3,72 @@
 USING: tools.test namespaces documents documents.elements multiline ;
 IN: document.elements.tests
 
-<document> "doc" set
-"123\nabc" "doc" get set-doc-string
+SYMBOL: doc
+<document> doc set
+"123\nabcé" doc get set-doc-string
 
 ! char-elt
-[ { 0 0 } ] [ { 0 0 } "doc" get char-elt prev-elt ] unit-test
-[ { 0 0 } ] [ { 0 1 } "doc" get char-elt prev-elt ] unit-test
-[ { 0 3 } ] [ { 1 0 } "doc" get char-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 0 } doc get char-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 1 } doc get char-elt prev-elt ] unit-test
+[ { 0 3 } ] [ { 1 0 } doc get char-elt prev-elt ] unit-test
+[ { 1 3 } ] [ { 1 5 } doc get char-elt prev-elt ] unit-test
 
-[ { 1 3 } ] [ { 1 3 } "doc" get char-elt next-elt ] unit-test
-[ { 0 2 } ] [ { 0 1 } "doc" get char-elt next-elt ] unit-test
-[ { 1 0 } ] [ { 0 3 } "doc" get char-elt next-elt ] unit-test
+[ { 1 5 } ] [ { 1 5 } doc get char-elt next-elt ] unit-test
+[ { 0 2 } ] [ { 0 1 } doc get char-elt next-elt ] unit-test
+[ { 1 0 } ] [ { 0 3 } doc get char-elt next-elt ] unit-test
+[ { 1 5 } ] [ { 1 3 } doc get char-elt next-elt ] unit-test
 
 ! word-elt
-<document> "doc" set
-"Hello world\nanother line" "doc" get set-doc-string
+<document> doc set
+"Hello world\nanother line" doc get set-doc-string
 
-[ { 0 0 } ] [ { 0 0 } "doc" get word-elt prev-elt ] unit-test
-[ { 0 0 } ] [ { 0 2 } "doc" get word-elt prev-elt ] unit-test
-[ { 0 0 } ] [ { 0 5 } "doc" get word-elt prev-elt ] unit-test
-[ { 0 5 } ] [ { 0 6 } "doc" get word-elt prev-elt ] unit-test
-[ { 0 6 } ] [ { 0 8 } "doc" get word-elt prev-elt ] unit-test
-[ { 0 11 } ] [ { 1 0 } "doc" get word-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 0 } doc get word-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 2 } doc get word-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 5 } doc get word-elt prev-elt ] unit-test
+[ { 0 5 } ] [ { 0 6 } doc get word-elt prev-elt ] unit-test
+[ { 0 6 } ] [ { 0 8 } doc get word-elt prev-elt ] unit-test
+[ { 0 11 } ] [ { 1 0 } doc get word-elt prev-elt ] unit-test
+
+[ { 0 5 } ] [ { 0 0 } doc get word-elt next-elt ] unit-test
+[ { 0 6 } ] [ { 0 5 } doc get word-elt next-elt ] unit-test
+[ { 0 11 } ] [ { 0 6 } doc get word-elt next-elt ] unit-test
+[ { 1 0 } ] [ { 0 11 } doc get word-elt next-elt ] unit-test
 
-[ { 0 5 } ] [ { 0 0 } "doc" get word-elt next-elt ] unit-test
-[ { 0 6 } ] [ { 0 5 } "doc" get word-elt next-elt ] unit-test
-[ { 0 11 } ] [ { 0 6 } "doc" get word-elt next-elt ] unit-test
-[ { 1 0 } ] [ { 0 11 } "doc" get word-elt next-elt ] unit-test
 
 ! one-word-elt
-[ { 0 0 } ] [ { 0 0 } "doc" get one-word-elt prev-elt ] unit-test
-[ { 0 0 } ] [ { 0 2 } "doc" get one-word-elt prev-elt ] unit-test
-[ { 0 0 } ] [ { 0 5 } "doc" get one-word-elt prev-elt ] unit-test
-[ { 0 5 } ] [ { 0 2 } "doc" get one-word-elt next-elt ] unit-test
-[ { 0 5 } ] [ { 0 5 } "doc" get one-word-elt next-elt ] unit-test
+[ { 0 0 } ] [ { 0 0 } doc get one-word-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 2 } doc get one-word-elt prev-elt ] unit-test
+[ { 0 0 } ] [ { 0 5 } doc get one-word-elt prev-elt ] unit-test
+[ { 0 5 } ] [ { 0 2 } doc get one-word-elt next-elt ] unit-test
+[ { 0 5 } ] [ { 0 5 } doc get one-word-elt next-elt ] unit-test
 
 ! line-elt
-<document> "doc" set
-"Hello\nworld, how are\nyou?" "doc" get set-doc-string
+<document> doc set
+"Hello\nworld, how are\nyou?" doc get set-doc-string
 
-[ { 0 0 } ] [ { 0 3 } "doc" get line-elt prev-elt ] unit-test
-[ { 0 3 } ] [ { 1 3 } "doc" get line-elt prev-elt ] unit-test
-[ { 2 4 } ] [ { 2 1 } "doc" get line-elt next-elt ] unit-test
+[ { 0 0 } ] [ { 0 3 } doc get line-elt prev-elt ] unit-test
+[ { 0 3 } ] [ { 1 3 } doc get line-elt prev-elt ] unit-test
+[ { 2 4 } ] [ { 2 1 } doc get line-elt next-elt ] unit-test
 
 ! one-line-elt
-[ { 1 0 } ] [ { 1 3 } "doc" get one-line-elt prev-elt ] unit-test
-[ { 1 14 } ] [ { 1 3 } "doc" get one-line-elt next-elt ] unit-test
+[ { 1 0 } ] [ { 1 3 } doc get one-line-elt prev-elt ] unit-test
+[ { 1 14 } ] [ { 1 3 } doc get one-line-elt next-elt ] unit-test
 
 ! page-elt
-<document> "doc" set
+<document> doc set
 <" First line
 Second line
 Third line
 Fourth line
 Fifth line
-Sixth line"> "doc" get set-doc-string
+Sixth line"> doc get set-doc-string
 
-[ { 0 0 } ] [ { 3 3 } "doc" get 4 <page-elt> prev-elt ] unit-test
-[ { 1 2 } ] [ { 5 2 } "doc" get 4 <page-elt> prev-elt ] unit-test
+[ { 0 0 } ] [ { 3 3 } doc get 4 <page-elt> prev-elt ] unit-test
+[ { 1 2 } ] [ { 5 2 } doc get 4 <page-elt> prev-elt ] unit-test
 
-[ { 4 3 } ] [ { 0 3 } "doc" get 4 <page-elt> next-elt ] unit-test
-[ { 5 10 } ] [ { 4 2 } "doc" get 4 <page-elt> next-elt ] unit-test
+[ { 4 3 } ] [ { 0 3 } doc get 4 <page-elt> next-elt ] unit-test
+[ { 5 10 } ] [ { 4 2 } doc get 4 <page-elt> next-elt ] unit-test
 
 ! doc-elt
-[ { 0 0 } ] [ { 3 4 } "doc" get doc-elt prev-elt ] unit-test
-[ { 5 10 } ] [ { 3 4 } "doc" get doc-elt next-elt ] unit-test
\ No newline at end of file
+[ { 0 0 } ] [ { 3 4 } doc get doc-elt prev-elt ] unit-test
+[ { 5 10 } ] [ { 3 4 } doc get doc-elt next-elt ] unit-test
index adb498df138d277c11e2aad42e07e5fbd4bfc406..f485f1bec10a6ceddfa54962753baa3d85d3abab 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays combinators documents fry kernel math sequences
-unicode.categories accessors ;
+accessors unicode.categories unicode.breaks combinators.short-circuit ;
 IN: documents.elements
 
 GENERIC: prev-elt ( loc document elt -- newloc )
@@ -20,27 +20,32 @@ SINGLETON: char-elt
 
 <PRIVATE
 
-: (prev-char) ( loc document quot -- loc )
+: prev ( loc document quot: ( loc document -- loc ) -- loc )
     {
         { [ pick { 0 0 } = ] [ 2drop ] }
         { [ pick second zero? ] [ drop [ first 1- ] dip line-end ] }
         [ call ]
     } cond ; inline
 
-: (next-char) ( loc document quot -- loc )
+: next ( loc document quot: ( loc document -- loc ) -- loc )
     {
         { [ 2over doc-end = ] [ 2drop ] }
         { [ 2over line-end? ] [ 2drop first 1+ 0 2array ] }
         [ call ]
     } cond ; inline
 
+: modify-col ( loc document quot: ( col str -- col' ) -- loc )
+    pick [
+        [ [ first2 swap ] dip doc-line ] dip call
+    ] dip =col ; inline
+
 PRIVATE>
 
 M: char-elt prev-elt
-    drop [ drop -1 +col ] (prev-char) ;
+    drop [ [ last-grapheme-from ] modify-col ] prev ;
 
 M: char-elt next-elt
-    drop [ drop 1 +col ] (next-char) ;
+    drop [ [ first-grapheme-from ] modify-col ] next ;
 
 SINGLETON: one-char-elt
 
@@ -50,21 +55,16 @@ M: one-char-elt next-elt 2drop ;
 
 <PRIVATE
 
-: (word-elt) ( loc document quot -- loc )
-    pick [
-        [ [ first2 swap ] dip doc-line ] dip call
-    ] dip =col ; inline
-
-: ((word-elt)) ( n seq -- n seq ? )
+: blank-at? ( n seq -- n seq ? )
     2dup ?nth blank? ;
 
 : break-detector ( ? -- quot )
     '[ blank? _ xor ] ; inline
 
-: (prev-word) ( col str ? -- col )
+: prev-word ( col str ? -- col )
     break-detector find-last-from drop ?1+ ;
 
-: (next-word) ( col str ? -- col )
+: next-word ( col str ? -- col )
     [ break-detector find-from drop ] [ drop length ] 2bi or ;
 
 PRIVATE>
@@ -73,23 +73,23 @@ SINGLETON: one-word-elt
 
 M: one-word-elt prev-elt
     drop
-    [ [ 1- ] dip f (prev-word) ] (word-elt) ;
+    [ [ 1- ] dip f prev-word ] modify-col ;
 
 M: one-word-elt next-elt
     drop
-    [ f (next-word) ] (word-elt) ;
+    [ f next-word ] modify-col ;
 
 SINGLETON: word-elt
 
 M: word-elt prev-elt
     drop
-    [ [ [ 1- ] dip ((word-elt)) (prev-word) ] (word-elt) ]
-    (prev-char) ;
+    [ [ [ 1- ] dip blank-at? prev-word ] modify-col ]
+    prev ;
 
 M: word-elt next-elt
     drop
-    [ [ ((word-elt)) (next-word) ] (word-elt) ]
-    (next-char) ;
+    [ [ blank-at? next-word ] modify-col ]
+    next ;
 
 SINGLETON: one-line-elt
 
@@ -118,4 +118,4 @@ SINGLETON: doc-elt
 
 M: doc-elt prev-elt 3drop { 0 0 } ;
 
-M: doc-elt next-elt drop nip doc-end ;
\ No newline at end of file
+M: doc-elt next-elt drop nip doc-end ;
index 0f50e40eb404f25d65061abd0a10c7710ba7d94d..e3961aef80dbab80e76181fe54fdf46f3b73e02e 100644 (file)
@@ -22,7 +22,7 @@ HELP: edit
     "A word's documentation:"
     { $code "\\ foo >link edit" }
     "A method definition:"
-    { $code "{ editor draw-gadget* } edit" }
+    { $code "M\\ fixnum + edit" }
     "A help article:"
     { $code "\"handbook\" >link edit" }
 } ;
index d060a3dfe67450042c47370bcb433cbc09fcc052..0003b508fb2c6903aad9e5532e3a2777d1d98bab 100644 (file)
@@ -28,7 +28,7 @@ SYMBOL: edit-hook
 
 : edit-location ( file line -- )
     [ (normalize-path) ] dip edit-hook get-global
-    [ call ] [ no-edit-hook edit-location ] if* ;
+    [ call( file line -- ) ] [ no-edit-hook edit-location ] if* ;
 
 ERROR: cannot-find-source definition ;
 
diff --git a/basis/editors/notepad/tags.txt b/basis/editors/notepad/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index b48a7a01add7b4cdf9774ca6966a90e6454fc84c..0f88181f28a3de964e32b14203f8f07eb1cbeb65 100644 (file)
@@ -17,7 +17,7 @@ HELP: (set-os-envs)
 { $notes "In most cases, use " { $link set-os-envs } " instead." } ;
 
 
-HELP: os-env ( key -- value )
+HELP: os-env
 { $values { "key" string } { "value" string } }
 { $description "Looks up the value of a shell environment variable." }
 { $examples
@@ -39,14 +39,14 @@ HELP: set-os-envs
     "Names and values of environment variables are operating system-specific. Windows NT allows values up to 32766 characters in length."
 } ;
 
-HELP: set-os-env ( value key -- )
+HELP: set-os-env
 { $values { "value" string } { "key" string } }
 { $description "Set an environment variable." }
 { $notes
     "Names and values of environment variables are operating system-specific."
 } ;
 
-HELP: unset-os-env ( key -- )
+HELP: unset-os-env
 { $values { "key" string } }
 { $description "Unset an environment variable." }
 { $notes
index dfa9baf418d2806859f2388e3eb717f2df36ea0c..3672337a584d0f17f8860a816246f6ef87d93348 100644 (file)
@@ -4,7 +4,7 @@ USING: splitting parser compiler.units kernel namespaces
 debugger io.streams.string fry ;
 IN: eval
 
-: parse-string ( str -- )
+: parse-string ( str -- quot )
     [ string-lines parse-lines ] with-compilation-unit ;
 
 : (eval) ( str -- )
index 56741201965fd1ac8e400094bb30d47ac3e97260..a4a77d97e963679ec4dbe6317c19e936c2ce96d9 100644 (file)
@@ -1,2 +1,2 @@
 Doug Coleman
-Slava Pestov
+Daniel Ehrenberg
index 8c6b07a01c61a866a5b2405842d3b96abd5c958c..036f0d667a488c9139df673507ed7451cc1a705c 100644 (file)
@@ -9,7 +9,7 @@ HELP: write-farkup
 { $values { "string" string } }
 { $description "Parse a Farkup string and writes the resulting HTML to " { $link output-stream } "." } ;
 
-HELP: parse-farkup ( string -- farkup )
+HELP: parse-farkup
 { $values { "string" string } { "farkup" "a Farkup syntax tree node" } }
 { $description "Parses Farkup and outputs a tree of " { $link "farkup-ast" } "." } ;
 
index 246da48b32eba0ade6f2a4131e96b05783d7141e..abee7194a2f76c9b8c0bf33cb6644c1655cc3c47 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: farkup kernel peg peg.ebnf tools.test namespaces xml
-urls.encoding assocs xml.traversal xml.data ;
+urls.encoding assocs xml.traversal xml.data sequences random
+io continuations math ;
 IN: farkup.tests
 
 relative-link-prefix off
@@ -20,50 +21,50 @@ link-no-follow? off
 ] unit-test
 
 [ "<p>a-b</p>" ] [ "a-b" convert-farkup ] unit-test
-[ "<p>*foo\nbar\n</p>" ] [ "*foo\nbar\n" convert-farkup ] unit-test
+[ "<p><strong>foo</strong></p><p>bar</p>" ] [ "*foo\nbar\n" convert-farkup ] unit-test
 [ "<p><strong>Wow!</strong></p>" ] [ "*Wow!*" convert-farkup ] unit-test
 [ "<p><em>Wow.</em></p>" ] [ "_Wow._" convert-farkup ] unit-test
 
-[ "<p>*</p>" ] [ "*" convert-farkup ] unit-test
+[ "<p><strong></strong></p>" ] [ "*" convert-farkup ] unit-test
 [ "<p>*</p>" ] [ "\\*" convert-farkup ] unit-test
-[ "<p>**</p>" ] [ "\\**" convert-farkup ] unit-test
+[ "<p>*<strong></strong></p>" ] [ "\\**" convert-farkup ] unit-test
 
 [ "<ul><li>a-b</li></ul>" ] [ "-a-b" convert-farkup ] unit-test
 [ "<ul><li>foo</li></ul>" ] [ "-foo" convert-farkup ] unit-test
-[ "<ul><li>foo</li>\n</ul>" ] [ "-foo\n" convert-farkup ] unit-test
-[ "<ul><li>foo</li>\n<li>bar</li></ul>" ] [ "-foo\n-bar" convert-farkup ] unit-test
-[ "<ul><li>foo</li>\n<li>bar</li>\n</ul>" ] [ "-foo\n-bar\n" convert-farkup ] unit-test
+[ "<ul><li>foo</li></ul>" ] [ "-foo\n" convert-farkup ] unit-test
+[ "<ul><li>foo</li><li>bar</li></ul>" ] [ "-foo\n-bar" convert-farkup ] unit-test
+[ "<ul><li>foo</li><li>bar</li></ul>" ] [ "-foo\n-bar\n" convert-farkup ] unit-test
 
-[ "<ul><li>foo</li>\n</ul><p>bar\n</p>" ] [ "-foo\nbar\n" convert-farkup ] unit-test
+[ "<ul><li>foo</li></ul><p>bar</p>" ] [ "-foo\nbar\n" convert-farkup ] unit-test
 
 [ "<ol><li>a-b</li></ol>" ] [ "#a-b" convert-farkup ] unit-test
 [ "<ol><li>foo</li></ol>" ] [ "#foo" convert-farkup ] unit-test
-[ "<ol><li>foo</li>\n</ol>" ] [ "#foo\n" convert-farkup ] unit-test
-[ "<ol><li>foo</li>\n<li>bar</li></ol>" ] [ "#foo\n#bar" convert-farkup ] unit-test
-[ "<ol><li>foo</li>\n<li>bar</li>\n</ol>" ] [ "#foo\n#bar\n" convert-farkup ] unit-test
+[ "<ol><li>foo</li></ol>" ] [ "#foo\n" convert-farkup ] unit-test
+[ "<ol><li>foo</li><li>bar</li></ol>" ] [ "#foo\n#bar" convert-farkup ] unit-test
+[ "<ol><li>foo</li><li>bar</li></ol>" ] [ "#foo\n#bar\n" convert-farkup ] unit-test
 
-[ "<ol><li>foo</li>\n</ol><p>bar\n</p>" ] [ "#foo\nbar\n" convert-farkup ] unit-test
+[ "<ol><li>foo</li></ol><p>bar</p>" ] [ "#foo\nbar\n" convert-farkup ] unit-test
 
 
-[ "\n\n" ] [ "\n\n" convert-farkup ] unit-test
-[ "\n\n" ] [ "\r\n\r\n" convert-farkup ] unit-test
-[ "\n\n\n\n" ] [ "\r\r\r\r" convert-farkup ] unit-test
-[ "\n\n\n" ] [ "\r\r\r" convert-farkup ] unit-test
-[ "\n\n\n" ] [ "\n\n\n" convert-farkup ] unit-test
-[ "<p>foo\n</p><p>bar</p>" ] [ "foo\n\nbar" convert-farkup ] unit-test
-[ "<p>foo\n</p><p>bar</p>" ] [ "foo\r\n\r\nbar" convert-farkup ] unit-test
-[ "<p>foo\n</p><p>bar</p>" ] [ "foo\r\rbar" convert-farkup ] unit-test
-[ "<p>foo\n</p><p>bar</p>" ] [ "foo\r\r\nbar" convert-farkup ] unit-test
+[ "" ] [ "\n\n" convert-farkup ] unit-test
+[ "" ] [ "\r\n\r\n" convert-farkup ] unit-test
+[ "" ] [ "\r\r\r\r" convert-farkup ] unit-test
+[ "" ] [ "\r\r\r" convert-farkup ] unit-test
+[ "" ] [ "\n\n\n" convert-farkup ] unit-test
+[ "<p>foo</p><p>bar</p>" ] [ "foo\n\nbar" convert-farkup ] unit-test
+[ "<p>foo</p><p>bar</p>" ] [ "foo\r\n\r\nbar" convert-farkup ] unit-test
+[ "<p>foo</p><p>bar</p>" ] [ "foo\r\rbar" convert-farkup ] unit-test
+[ "<p>foo</p><p>bar</p>" ] [ "foo\r\r\nbar" convert-farkup ] unit-test
 
-[ "\n<p>bar\n</p>" ] [ "\nbar\n" convert-farkup ] unit-test
-[ "\n<p>bar\n</p>" ] [ "\rbar\r" convert-farkup ] unit-test
-[ "\n<p>bar\n</p>" ] [ "\r\nbar\r\n" convert-farkup ] unit-test
+[ "<p>bar</p>" ] [ "\nbar\n" convert-farkup ] unit-test
+[ "<p>bar</p>" ] [ "\rbar\r" convert-farkup ] unit-test
+[ "<p>bar</p>" ] [ "\r\nbar\r\n" convert-farkup ] unit-test
 
-[ "<p>foo\n</p><p>bar</p>" ] [ "foo\n\n\nbar" convert-farkup ] unit-test
+[ "<p>foo</p><p>bar</p>" ] [ "foo\n\n\nbar" convert-farkup ] unit-test
 
 [ "" ] [ "" convert-farkup ] unit-test
 
-[ "<p>|a</p>" ]
+[ "<table><tr><td>a</td></tr></table>" ]
 [ "|a" convert-farkup ] unit-test
 
 [ "<table><tr><td>a</td></tr></table>" ]
@@ -78,24 +79,24 @@ link-no-follow? off
 [ "<table><tr><td>a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></table>" ]
 [ "|a|b|\n|c|d|\n" convert-farkup ] unit-test
 
-[ "<p><strong>foo</strong>\n</p><h1>aheading</h1>\n<p>adfasd</p>" ]
+[ "<p><strong>foo</strong></p><h1>aheading</h1><p>adfasd</p>" ]
 [ "*foo*\n=aheading=\nadfasd" convert-farkup ] unit-test
 
-[ "<h1>foo</h1>\n" ] [ "=foo=\n" convert-farkup ] unit-test
-[ "<p>lol</p><h1>foo</h1>\n" ] [ "lol=foo=\n" convert-farkup ] unit-test
-[ "<p>=foo\n</p>" ] [ "=foo\n" convert-farkup ] unit-test
+[ "<h1>foo</h1>" ] [ "=foo=\n" convert-farkup ] unit-test
+[ "<p>lol=foo=</p>" ] [ "lol=foo=\n" convert-farkup ] unit-test
+[ "<p>=foo</p>" ] [ "=foo\n" convert-farkup ] unit-test
 [ "<p>=foo</p>" ] [ "=foo" convert-farkup ] unit-test
 [ "<p>==foo</p>" ] [ "==foo" convert-farkup ] unit-test
-[ "<p>=</p><h1>foo</h1>" ] [ "==foo=" convert-farkup ] unit-test
+[ "<h1>foo</h1>" ] [ "==foo=" convert-farkup ] unit-test
 [ "<h2>foo</h2>" ] [ "==foo==" convert-farkup ] unit-test
 [ "<h2>foo</h2>" ] [ "==foo==" convert-farkup ] unit-test
-[ "<p>=</p><h2>foo</h2>" ] [ "===foo==" convert-farkup ] unit-test
-[ "<h1>foo</h1><p>=</p>" ] [ "=foo==" convert-farkup ] unit-test
+[ "<h2>foo</h2>" ] [ "===foo==" convert-farkup ] unit-test
+[ "<h1>foo</h1>" ] [ "=foo==" convert-farkup ] unit-test
 
 [ "<pre><span class=\"KEYWORD3\">int</span> <span class=\"FUNCTION\">main</span><span class=\"OPERATOR\">(</span><span class=\"OPERATOR\">)</span></pre>" ]
 [ "[c{int main()}]" convert-farkup ] unit-test
 
-[ "<p><img src=\"lol.jpg\"/></p>" ] [ "[[image:lol.jpg]]" convert-farkup ] unit-test
+[ "<p><img src=\"lol.jpg\" alt=\"image:lol.jpg\"/></p>" ] [ "[[image:lol.jpg]]" convert-farkup ] unit-test
 [ "<p><img src=\"lol.jpg\" alt=\"teh lol\"/></p>" ] [ "[[image:lol.jpg|teh lol]]" convert-farkup ] unit-test
 [ "<p><a href=\"http://lol.com\">http://lol.com</a></p>" ] [ "[[http://lol.com]]" convert-farkup ] unit-test
 [ "<p><a href=\"http://lol.com\">haha</a></p>" ] [ "[[http://lol.com|haha]]" convert-farkup ] unit-test
@@ -111,11 +112,11 @@ link-no-follow? off
 [ "<pre>hello</pre>" ] [ "[{hello}]" convert-farkup ] unit-test
 
 [
-    "<p>Feature comparison:\n<table><tr><td>a</td><td>Factor</td><td>Java</td><td>Lisp</td></tr><tr><td>Coolness</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Badass</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Enterprise</td><td>Yes</td><td>Yes</td><td>No</td></tr><tr><td>Kosher</td><td>Yes</td><td>No</td><td>Yes</td></tr></table></p>"
+    "<p>Feature comparison:</p><table><tr><td>a</td><td>Factor</td><td>Java</td><td>Lisp</td></tr><tr><td>Coolness</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Badass</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Enterprise</td><td>Yes</td><td>Yes</td><td>No</td></tr><tr><td>Kosher</td><td>Yes</td><td>No</td><td>Yes</td></tr></table>"
 ] [ "Feature comparison:\n|a|Factor|Java|Lisp|\n|Coolness|Yes|No|No|\n|Badass|Yes|No|No|\n|Enterprise|Yes|Yes|No|\n|Kosher|Yes|No|Yes|\n" convert-farkup ] unit-test
 
 [
-    "<p>Feature comparison:\n</p><table><tr><td>a</td><td>Factor</td><td>Java</td><td>Lisp</td></tr><tr><td>Coolness</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Badass</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Enterprise</td><td>Yes</td><td>Yes</td><td>No</td></tr><tr><td>Kosher</td><td>Yes</td><td>No</td><td>Yes</td></tr></table>"
+    "<p>Feature comparison:</p><table><tr><td>a</td><td>Factor</td><td>Java</td><td>Lisp</td></tr><tr><td>Coolness</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Badass</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Enterprise</td><td>Yes</td><td>Yes</td><td>No</td></tr><tr><td>Kosher</td><td>Yes</td><td>No</td><td>Yes</td></tr></table>"
 ] [ "Feature comparison:\n\n|a|Factor|Java|Lisp|\n|Coolness|Yes|No|No|\n|Badass|Yes|No|No|\n|Enterprise|Yes|Yes|No|\n|Kosher|Yes|No|Yes|\n" convert-farkup ] unit-test
 
 [
@@ -131,33 +132,33 @@ link-no-follow? off
 
 [ "<p>&lt;foo&gt;</p>" ] [ "<foo>" convert-farkup ] unit-test
 
-[ "<p>asdf\n<ul><li>lol</li>\n<li>haha</li></ul></p>" ] [ "asdf\n-lol\n-haha" convert-farkup ] unit-test
+[ "<p>asdf</p><ul><li>lol</li><li>haha</li></ul>" ] [ "asdf\n-lol\n-haha" convert-farkup ] unit-test
 
-[ "<p>asdf\n</p><ul><li>lol</li>\n<li>haha</li></ul>" ]
+[ "<p>asdf</p><ul><li>lol</li><li>haha</li></ul>" ]
  [ "asdf\n\n-lol\n-haha" convert-farkup ] unit-test
 
 [ "<hr/>" ] [ "___" convert-farkup ] unit-test
-[ "<hr/>\n" ] [ "___\n" convert-farkup ] unit-test
+[ "<hr/>" ] [ "___\n" convert-farkup ] unit-test
 
-[ "<p>before:\n<pre><span class=\"OPERATOR\">{</span> <span class=\"DIGIT\">1</span> <span class=\"DIGIT\">2</span> <span class=\"DIGIT\">3</span> <span class=\"OPERATOR\">}</span> <span class=\"DIGIT\">1</span> tail</pre></p>" ] 
+[ "<p>before:</p><pre><span class=\"OPERATOR\">{</span> <span class=\"DIGIT\">1</span> <span class=\"DIGIT\">2</span> <span class=\"DIGIT\">3</span> <span class=\"OPERATOR\">}</span> <span class=\"DIGIT\">1</span> tail</pre>" ] 
 [ "before:\n[factor{{ 1 2 3 } 1 tail}]" convert-farkup ] unit-test
  
 [ "<p><a href=\"Factor\">Factor</a>-rific!</p>" ]
 [ "[[Factor]]-rific!" convert-farkup ] unit-test
 
-[ "<p>[ factor { 1 2 3 }]</p>" ]
+[ "<pre> 1 2 3 </pre>" ]
 [ "[ factor { 1 2 3 }]" convert-farkup ] unit-test
 
-[ "<p>paragraph\n<hr/></p>" ]
+[ "<p>paragraph</p><hr/>" ]
 [ "paragraph\n___" convert-farkup ] unit-test
 
-[ "<p>paragraph\n a ___ b</p>" ]
+[ "<p>paragraph</p><p> a <em></em><em> b</em></p>" ]
 [ "paragraph\n a ___ b" convert-farkup ] unit-test
 
-[ "\n<ul><li> a</li>\n</ul><hr/>" ]
+[ "<ul><li> a</li></ul><hr/>" ]
 [ "\n- a\n___" convert-farkup ] unit-test
 
-[ "<p>hello_world how are you today?\n<ul><li> hello_world how are you today?</li></ul></p>" ]
+[ "<p>hello<em>world how are you today?</em></p><ul><li> hello<em>world how are you today?</em></li></ul>" ]
 [ "hello_world how are you today?\n- hello_world how are you today?" convert-farkup ] unit-test
 
 : check-link-escaping ( string -- link )
@@ -168,3 +169,41 @@ link-no-follow? off
 [ "<foo>" ] [ "[[<foo>]]" check-link-escaping ] unit-test
 [ "&blah;" ] [ "[[&blah;]]" check-link-escaping ] unit-test
 [ "C++" ] [ "[[C++]]" check-link-escaping ] unit-test
+
+[ "<h1>The <em>important</em> thing</h1>" ] [ "=The _important_ thing=" convert-farkup ] unit-test
+[ "<p><a href=\"Foo\"><strong>emphasized</strong> text</a></p>" ] [ "[[Foo|*emphasized* text]]" convert-farkup ] unit-test
+[ "<table><tr><td><strong>bold</strong></td><td><em>italics</em></td></tr></table>" ]
+[ "|*bold*|_italics_|" convert-farkup ] unit-test
+[ "<p><em>italics<strong>both</strong></em></p>" ] [ "_italics*both" convert-farkup ] unit-test
+[ "<p><em>italics<strong>both</strong></em></p>" ] [ "_italics*both*" convert-farkup ] unit-test
+[ "<p><em>italics<strong>both</strong></em></p>" ] [ "_italics*both*_" convert-farkup ] unit-test
+[ "<p><em>italics<strong>both</strong></em></p>" ] [ "_italics*both_" convert-farkup ] unit-test
+[ "<p><em>italics<strong>both</strong></em>after<strong></strong></p>" ] [ "_italics*both_after*" convert-farkup ] unit-test
+[ "<table><tr><td>foo|bar</td></tr></table>" ] [ "|foo\\|bar|" convert-farkup ] unit-test
+[ "<p></p>" ] [ "\\" convert-farkup ] unit-test
+
+[ "<p>[abc]</p>" ] [ "[abc]" convert-farkup ] unit-test
+
+: random-markup ( -- string )
+    10 [
+        2 random 1 = [
+            {
+                "[["
+                "*"
+                "_"
+                "|"
+                "-"
+                "[{"
+                "\n"
+            } random
+        ] [
+            "abc"
+        ] if
+    ] replicate concat ;
+
+[ t ] [
+    100 [
+        drop random-markup
+        [ convert-farkup drop t ] [ drop print f ] recover
+    ] all?
+] unit-test
old mode 100755 (executable)
new mode 100644 (file)
index 4041d92..c400457
@@ -1,10 +1,9 @@
-! Copyright (C) 2008 Doug Coleman.
+! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays combinators io
-io.streams.string kernel math namespaces peg peg.ebnf
-sequences sequences.deep strings xml.entities xml.syntax
-vectors splitting xmode.code2html urls.encoding xml.data
-xml.writer ;
+USING: sequences kernel splitting lists fry accessors assocs math.order
+math combinators namespaces urls.encoding xml.syntax xmode.code2html
+xml.data arrays strings vectors xml.writer io.streams.string locals
+unicode.categories ;
 IN: farkup
 
 SYMBOL: relative-link-prefix
@@ -39,123 +38,176 @@ TUPLE: line-break ;
 : simple-link-title ( string -- string' )
     dup absolute-url? [ "/" split1-last swap or ] unless ;
 
-EBNF: parse-farkup
-nl               = ("\r\n" | "\r" | "\n") => [[ drop "\n" ]]
-whitespace       = " " | "\t" | nl
-
-heading1      = "=" (!("=" | nl).)+ "="
-    => [[ second >string heading1 boa ]]
-
-heading2      = "==" (!("=" | nl).)+ "=="
-    => [[ second >string heading2 boa ]]
-
-heading3      = "===" (!("=" | nl).)+ "==="
-    => [[ second >string heading3 boa ]]
-
-heading4      = "====" (!("=" | nl).)+ "===="
-    => [[ second >string heading4 boa ]]
-
-heading          = heading4 | heading3 | heading2 | heading1
-
-
-
-strong        = "*" (!("*" | nl).)+ "*"
-    => [[ second >string strong boa ]]
-
-emphasis      = "_" (!("_" | nl).)+ "_"
-    => [[ second >string emphasis boa ]]
-
-superscript   = "^" (!("^" | nl).)+ "^"
-    => [[ second >string superscript boa ]]
-
-subscript     = "~" (!("~" | nl).)+ "~"
-    => [[ second >string subscript boa ]]
-
-inline-code   = "%" (!("%" | nl).)+ "%"
-    => [[ second >string inline-code boa ]]
-
-link-content     = (!("|"|"]").)+
-                    => [[ >string ]]
-
-image-link       = "[[image:" link-content  "|" link-content "]]"
-                    => [[ [ second >string ] [ fourth >string ] bi image boa ]]
-                  | "[[image:" link-content "]]"
-                    => [[ second >string f image boa ]]
-
-simple-link      = "[[" link-content "]]"
-    => [[ second >string dup simple-link-title link boa ]]
-
-labeled-link     = "[[" link-content "|" link-content "]]"
-    => [[ [ second >string ] [ fourth >string ] bi link boa ]]
-
-link             = image-link | labeled-link | simple-link
-
-escaped-char  = "\" .
-    => [[ second 1string ]]
-
-inline-tag       = strong | emphasis | superscript | subscript | inline-code
-                   | link | escaped-char
-
-
-
-inline-delimiter = '*' | '_' | '^' | '~' | '%' | '\' | '['
-
-cell             = (!(inline-delimiter | '|' | nl).)+
-    => [[ >string ]]
-    
-table-column     = (list | cell | inline-tag | inline-delimiter  ) '|'
-    => [[ first ]]
-table-row        = "|" (table-column)+
-    => [[ second table-row boa ]]
-table            =  ((table-row nl => [[ first ]] )+ table-row? | table-row)
-    => [[ table boa ]]
-
-text = (!(nl | code | heading | inline-delimiter | table ).)+
-    => [[ >string ]]
-
-paragraph-nl-item = nl list
-    | nl line
-    | nl => [[ line-breaks? get [ drop line-break new ] when ]]
-paragraph-item = (table | code | text | inline-tag | inline-delimiter)+
-paragraph = ((paragraph-item paragraph-nl-item)+ nl+ => [[ first ]]
-             | (paragraph-item paragraph-nl-item)+ paragraph-item?
-             | paragraph-item)
-    => [[ paragraph boa ]]
-
-
-list-item     = (cell | inline-tag | inline-delimiter)*
-
-ordered-list-item      = '#' list-item
-    => [[ second list-item boa ]]
-ordered-list = ((ordered-list-item nl)+ ordered-list-item? | ordered-list-item)
-    => [[ ordered-list boa ]]
-
-unordered-list-item    = '-' list-item
-    => [[ second list-item boa ]]
-unordered-list = ((unordered-list-item nl)+ unordered-list-item? | unordered-list-item)
-    => [[ unordered-list boa ]]
-
-list = ordered-list | unordered-list
-
-
-line = '___'
-    => [[ drop line new ]]
-
-
-named-code
-           =  '[' (!('{' | whitespace | '[').)+ '{' (!("}]").)+ "}]"
-    => [[ [ second >string ] [ fourth >string ] bi code boa ]]
-
-simple-code
-           = "[{" (!("}]").)+ "}]"
-    => [[ second >string f swap code boa ]]
-
-code = named-code | simple-code
+! _foo*bar_baz*bing works like <i>foo*bar</i>baz<b>bing</b>
+! I could support overlapping, but there's not a good use case for it.
+
+DEFER: (parse-paragraph)
+
+: parse-paragraph ( string -- seq )
+    (parse-paragraph) list>array ;
+
+: make-paragraph ( string -- paragraph )
+    parse-paragraph paragraph boa ;
+
+: cut-half-slice ( string i -- before after-slice )
+    [ head ] [ 1+ short tail-slice ] 2bi ;
+
+: find-cut ( string quot -- before after delimiter )
+    dupd find
+    [ [ cut-half-slice ] [ f ] if* ] dip ; inline
+
+: parse-delimiter ( string delimiter class -- paragraph )
+    [ '[ _ = ] find-cut drop ] dip
+    '[ parse-paragraph _ new swap >>child ]
+    [ (parse-paragraph) ] bi* cons ;
+
+: delimiter-class ( delimiter -- class )
+    H{
+        { CHAR: * strong }
+        { CHAR: _ emphasis }
+        { CHAR: ^ superscript }
+        { CHAR: ~ subscript }
+        { CHAR: % inline-code }
+    } at ;
+
+: parse-link ( string -- paragraph-list )
+    rest-slice "]]" split1-slice [
+        "|" split1
+        [ "" like dup simple-link-title ] unless*
+        [ "image:" ?head ] dip swap [ image boa ] [ parse-paragraph link boa ] if
+    ] dip [ (parse-paragraph) cons ] [ 1list ] if* ;
+
+: ?first ( seq -- elt ) 0 swap ?nth ;
+
+: parse-big-link ( before after -- link rest )
+    dup ?first CHAR: [ =
+    [ parse-link ]
+    [ [ CHAR: [ suffix ] [ (parse-paragraph) ] bi* ]
+    if ;
+
+: escape ( before after -- before' after' )
+    [ nil ] [ unclip-slice swap [ suffix ] dip (parse-paragraph) ] if-empty ;
+
+: (parse-paragraph) ( string -- list )
+    [ nil ] [
+        [ "*_^~%[\\" member? ] find-cut [
+            {
+                { CHAR: [ [ parse-big-link ] }
+                { CHAR: \\ [ escape ] }
+                [ dup delimiter-class parse-delimiter ]
+            } case cons
+        ] [ drop "" like 1list ] if*
+    ] if-empty ;
+
+: <farkup-state> ( string -- state ) string-lines ;
+: look ( state i -- char ) swap first ?nth ;
+: done? ( state -- ? ) empty? ;
+: take-line ( state -- state' line ) unclip-slice ;
+
+: take-lines ( state char -- state' lines )
+    dupd '[ ?first _ = not ] find drop
+    [ cut-slice ] [ f ] if* swap ;
+
+:: (take-until) ( state delimiter accum -- string/f state' )
+    state empty? [ accum "\n" join f ] [
+        state unclip-slice :> first :> rest
+        first delimiter split1 :> after :> before
+        before accum push
+        after [
+            accum "\n" join
+            rest after prefix
+        ] [
+            rest delimiter accum (take-until)
+        ] if
+    ] if ;
 
+: take-until ( state delimiter -- string state'/f )
+    V{ } clone (take-until) ;
+
+: count= ( string -- n )
+    dup <reversed> [ [ CHAR: = = not ] find drop 0 or ] bi@ min ;
+
+: trim= ( string -- string' )
+    [ CHAR: = = ] trim ;
+
+: make-heading ( string class -- heading )
+    [ trim= parse-paragraph ] dip boa ; inline
+
+: parse-heading ( state -- state' heading )
+    take-line dup count= {
+        { 0 [ make-paragraph ] }
+        { 1 [ heading1 make-heading ] }
+        { 2 [ heading2 make-heading ] }
+        { 3 [ heading3 make-heading ] }
+        { 4 [ heading4 make-heading ] }
+        [ drop heading4 make-heading ]
+    } case ;
+
+: trim-row ( seq -- seq' )
+    rest
+    dup peek empty? [ but-last ] when ;
+
+: ?peek ( seq -- elt/f )
+    [ f ] [ peek ] if-empty ;
+
+: coalesce ( rows -- rows' )
+    V{ } clone [
+        '[
+            _ dup ?peek ?peek CHAR: \\ =
+            [ [ pop "|" rot 3append ] keep ] when
+            push 
+        ] each
+    ] keep ;
+
+: parse-table ( state -- state' table )
+    CHAR: | take-lines [
+        "|" split
+        trim-row
+        coalesce
+        [ parse-paragraph ] map
+        table-row boa
+    ] map table boa ;
+
+: parse-line ( state -- state' item )
+    take-line dup "___" =
+    [ drop line new ] [ make-paragraph ] if ;
+
+: parse-list ( state char class -- state' list )
+    [
+        take-lines
+        [ rest parse-paragraph list-item boa ] map
+    ] dip boa ; inline
+
+: parse-ul ( state -- state' ul )
+    CHAR: - unordered-list parse-list ;
+
+: parse-ol ( state -- state' ul )
+    CHAR: # ordered-list parse-list ;
+
+: parse-code ( state -- state' item )
+    dup 1 look CHAR: [ =
+    [ take-line make-paragraph ] [
+        dup "{" take-until [
+            [ nip rest ] dip
+            "}]" take-until
+            [ code boa ] dip swap
+        ] [ drop take-line make-paragraph ] if*
+    ] if ;
 
-stand-alone
-           = (line | code | heading | list | table | paragraph | nl)*
-;EBNF
+: parse-item ( state -- state' item )
+    dup 0 look {
+        { CHAR: = [ parse-heading ] }
+        { CHAR: | [ parse-table ] }
+        { CHAR: _ [ parse-line ] }
+        { CHAR: - [ parse-ul ] }
+        { CHAR: # [ parse-ol ] } 
+        { CHAR: [ [ parse-code ] }
+        { f [ rest-slice f ] }
+        [ drop take-line make-paragraph ]
+    } case ;
+
+: parse-farkup ( string -- farkup )
+    <farkup-state> [ dup done? not ] [ parse-item ] produce nip sift ;
 
 CONSTANT: invalid-url "javascript:alert('Invalid URL in farkup');"
 
@@ -168,19 +220,6 @@ CONSTANT: invalid-url "javascript:alert('Invalid URL in farkup');"
         [ relative-link-prefix get prepend "" like url-encode ]
     } cond ;
 
-: write-link ( href text -- xml )
-    [ check-url link-no-follow? get "nofollow" and ] dip
-    [XML <a href=<-> rel=<->><-></a> XML] ;
-
-: write-image-link ( href text -- xml )
-    disable-images? get [
-        2drop
-        [XML <strong>Images are not allowed</strong> XML]
-    ] [
-        [ check-url ] [ f like ] bi*
-        [XML <img src=<-> alt=<->/> XML]
-    ] if ;
-
 : render-code ( string mode -- xml )
     [ string-lines ] dip htmlize-lines
     [XML <pre><-></pre> XML] ;
@@ -206,11 +245,27 @@ M: ordered-list (write-farkup) "ol" farkup-inside ;
 M: paragraph (write-farkup) "p" farkup-inside ;
 M: table (write-farkup) "table" farkup-inside ;
 
+: write-link ( href text -- xml )
+    [ check-url link-no-follow? get "nofollow" and ] dip
+    [XML <a href=<-> rel=<->><-></a> XML] ;
+
+: write-image-link ( href text -- xml )
+    disable-images? get [
+        2drop
+        [XML <strong>Images are not allowed</strong> XML]
+    ] [
+        [ check-url ] [ f like ] bi*
+        [XML <img src=<-> alt=<->/> XML]
+    ] if ;
+
+: open-link ( link -- href text )
+    [ href>> ] [ text>> (write-farkup) ] bi ;
+
 M: link (write-farkup)
-    [ href>> ] [ text>> ] bi write-link ;
+    open-link write-link ;
 
 M: image (write-farkup)
-    [ href>> ] [ text>> ] bi write-image-link ;
+    open-link write-image-link ;
 
 M: code (write-farkup)
     [ string>> ] [ mode>> ] bi render-code ;
@@ -228,9 +283,7 @@ M: table-row (write-farkup)
 
 M: string (write-farkup) ;
 
-M: vector (write-farkup) [ (write-farkup) ] map ;
-
-M: f (write-farkup) ;
+M: array (write-farkup) [ (write-farkup) ] map ;
 
 : farkup>xml ( string -- xml )
     parse-farkup (write-farkup) ;
@@ -240,3 +293,4 @@ M: f (write-farkup) ;
 
 : convert-farkup ( string -- string' )
     [ write-farkup ] with-string-writer ;
+
index 71894503945c43cd91b6944faef4b49f56543a00..d240e6f23374f769c15e3256843b24bc416d7420 100644 (file)
@@ -34,7 +34,7 @@ sequences eval accessors ;
     { "a" "b" "c" } swap map
 ] unit-test
 
-: funny-dip '[ [ @ ] dip ] call ; inline
+: funny-dip ( obj quot -- ) '[ [ @ ] dip ] call ; inline
 
 [ "hi" 3 ] [ "h" "i" 3 [ append ] funny-dip ] unit-test
 
index 9ffad43cf42fbf7483454c6210c61763c1088b53..d50fd9442bf72dd62baf65525f6a30e7e803b952 100644 (file)
@@ -53,4 +53,4 @@ M: callable deep-fry
 
 M: object deep-fry , ;
 
-: '[ parse-quotation fry over push-all ; parsing
+SYNTAX: '[ parse-quotation fry over push-all ;
index df008d52bdc4e4754955f3918f0995120ad02bbd..b4417532b4f64fc3f7aa018766f16ee9460f5f52 100644 (file)
@@ -13,7 +13,7 @@ WHERE
 
 TUPLE: B { value T } ;
 
-C: <B> B
+C: <B> B ( T -- B )
 
 ;FUNCTOR
 
index 6592a3c4f241fe938a135067b8b80d882276d47d..309154fb491e3887a5e78b7e8ce64fbfae9f4e3b 100644 (file)
@@ -14,7 +14,9 @@ IN: functors
 
 : scan-param ( -- obj ) scan-object literalize ;
 
-: define* ( word def effect -- ) pick set-word define-declared ;
+: define* ( word def -- ) over set-word define ;
+
+: define-declared* ( word def effect -- ) pick set-word define-declared ;
 
 TUPLE: fake-quotation seq ;
 
@@ -36,12 +38,17 @@ M: array fake-quotations> [ fake-quotations> ] map ;
 
 M: object fake-quotations> ;
 
-: parse-definition* ( -- )
+: parse-definition* ( accum -- accum )
     parse-definition >fake-quotations parsed \ fake-quotations> parsed ;
 
-: DEFINE* ( accum -- accum ) effect get parsed \ define* parsed ;
+: parse-declared* ( accum -- accum )
+    complete-effect
+    [ parse-definition* ] dip
+    parsed ;
+
+: DEFINE* ( accum -- accum ) \ define-declared* parsed ;
 
-: `TUPLE:
+SYNTAX: `TUPLE:
     scan-param parsed
     scan {
         { ";" [ tuple parsed f parsed ] }
@@ -52,40 +59,38 @@ M: object fake-quotations> ;
             make parsed
         ]
     } case
-    \ define-tuple-class parsed ; parsing
+    \ define-tuple-class parsed ;
 
-: `M:
-    effect off
+SYNTAX: `M:
     scan-param parsed
     scan-param parsed
     \ create-method-in parsed
     parse-definition*
-    DEFINE* ; parsing
+    \ define* parsed ;
 
-: `C:
-    effect off
+SYNTAX: `C:
+    scan-param parsed
     scan-param parsed
+    complete-effect
+    [ [ [ boa ] curry ] over push-all ] dip parsed
+    \ define-declared* parsed ;
+
+SYNTAX: `:
     scan-param parsed
-    [ [ boa ] curry ] over push-all
-    DEFINE* ; parsing
+    parse-declared*
+    \ define-declared* parsed ;
 
-: `:
-    effect off
+SYNTAX: `SYNTAX:
     scan-param parsed
     parse-definition*
-    DEFINE* ; parsing
+    \ define-syntax parsed ;
 
-: `INSTANCE:
+SYNTAX: `INSTANCE:
     scan-param parsed
     scan-param parsed
-    \ add-mixin-instance parsed ; parsing
-
-: `inline [ word make-inline ] over push-all ; parsing
-
-: `parsing [ word make-parsing ] over push-all ; parsing
+    \ add-mixin-instance parsed ;
 
-: `(
-    ")" parse-effect effect set ; parsing
+SYNTAX: `inline [ word make-inline ] over push-all ;
 
 : (INTERPOLATE) ( accum quot -- accum )
     [ scan interpolate-locals ] dip
@@ -93,11 +98,11 @@ M: object fake-quotations> ;
 
 PRIVATE>
 
-: IS [ dup search [ ] [ no-word ] ?if ] (INTERPOLATE) ; parsing
+SYNTAX: IS [ dup search [ ] [ no-word ] ?if ] (INTERPOLATE) ;
 
-: DEFINES [ create-in ] (INTERPOLATE) ; parsing
+SYNTAX: DEFINES [ create-in ] (INTERPOLATE) ;
 
-: DEFINES-CLASS [ create-class-in ] (INTERPOLATE) ; parsing
+SYNTAX: DEFINES-CLASS [ create-class-in ] (INTERPOLATE) ;
 
 DEFER: ;FUNCTOR delimiter
 
@@ -110,9 +115,8 @@ DEFER: ;FUNCTOR delimiter
         { "C:" POSTPONE: `C: }
         { ":" POSTPONE: `: }
         { "INSTANCE:" POSTPONE: `INSTANCE: }
+        { "SYNTAX:" POSTPONE: `SYNTAX: }
         { "inline" POSTPONE: `inline }
-        { "parsing" POSTPONE: `parsing }
-        { "(" POSTPONE: `( }
     } ;
 
 : push-functor-words ( -- )
@@ -127,9 +131,9 @@ DEFER: ;FUNCTOR delimiter
     [ \ ;FUNCTOR parse-until >quotation ] ((parse-lambda)) <let*> 1quotation
     pop-functor-words ;
 
-: (FUNCTOR:) ( -- word def )
+: (FUNCTOR:) ( -- word def effect )
     CREATE-WORD [ parse-functor-body ] parse-locals-definition ;
 
 PRIVATE>
 
-: FUNCTOR: (FUNCTOR:) define ; parsing
+SYNTAX: FUNCTOR: (FUNCTOR:) define-declared ;
index dd453ae16d528764a0453066f507f1bdb92f059a..83ed00ca1b8d34256b0197b33d2c6adbf1b619de 100644 (file)
@@ -1,6 +1,6 @@
 USING: assocs classes help.markup help.syntax io.streams.string
 http http.server.dispatchers http.server.responses
-furnace.redirection strings multiline ;
+furnace.redirection strings multiline html.forms ;
 IN: furnace.actions
 
 HELP: <action>
@@ -74,6 +74,8 @@ HELP: validate-params
     }
 } ;
 
+{ validate-params validate-values } related-words
+      
 HELP: validation-failed
 { $description "Stops processing the current request and takes action depending on the type of the current request:"
     { $list
index 60a526fb247996f05a7ca0b91001628c50d28dc1..cefeda04818c5084b8e678ac081b7985f89897b4 100644 (file)
@@ -7,7 +7,7 @@ IN: furnace.actions.tests
     [ "a" param "b" param [ string>number ] bi@ + ] >>display
 "action-1" set
 
-: lf>crlf "\n" split "\r\n" join ;
+: lf>crlf ( string -- string' ) "\n" split "\r\n" join ;
 
 STRING: action-request-test-1
 GET http://foo/bar?a=12&b=13 HTTP/1.1
index 166d2a88a2381a5349946ad8afac8284a70e6c0a..c7893117d16f8ae609275cad7bb989d46cb794b6 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.\r
+! Copyright (C) 2008, 2009 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: accessors sequences kernel assocs combinators\r
 validators http hashtables namespaces fry continuations locals\r
@@ -9,6 +9,7 @@ http.server.responses
 furnace.utilities\r
 furnace.redirection\r
 furnace.conversations\r
+furnace.chloe-tags\r
 html.forms\r
 html.components\r
 html.components\r
@@ -52,10 +53,10 @@ TUPLE: action rest init authorize display validate submit ;
     '[\r
         _ dup display>> [\r
             {\r
-                [ init>> call ]\r
-                [ authorize>> call ]\r
+                [ init>> call( -- ) ]\r
+                [ authorize>> call( -- ) ]\r
                 [ drop restore-validation-errors ]\r
-                [ display>> call ]\r
+                [ display>> call( -- response ) ]\r
             } cleave\r
         ] [ drop <400> ] if\r
     ] with-exit-continuation ;\r
@@ -81,9 +82,9 @@ CONSTANT: revalidate-url-key "__u"
 : handle-post ( action -- response )\r
     '[\r
         _ dup submit>> [\r
-            [ validate>> call ]\r
-            [ authorize>> call ]\r
-            [ submit>> call ]\r
+            [ validate>> call( -- ) ]\r
+            [ authorize>> call( -- ) ]\r
+            [ submit>> call( -- response ) ]\r
             tri\r
         ] [ drop <400> ] if\r
     ] with-exit-continuation ;\r
index 915ae1c2249d57331466daae541d63c61a1d2918..9c3d316d039f3d06173a61b8979658b22de125d6 100644 (file)
@@ -53,7 +53,7 @@ M: login-realm modify-form ( responder -- )
 \r
 \ successful-login DEBUG add-input-logging\r
 \r
-: logout ( -- )\r
+: logout ( -- response )\r
     permit-id get [ delete-permit ] when*\r
     URL" $realm" end-aside ;\r
 \r
index 95e93f2ee8b067be02aa980f57c43b9d61990c7c..b4bc574ae224e66bbfc30293ddb9351874b859c6 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2008 Slava Pestov
+! Copyright (c) 2008, 2009 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel math.order namespaces combinators.short-circuit
 html.forms
@@ -23,7 +23,7 @@ TUPLE: boilerplate < filter-responder template init ;
 M:: boilerplate call-responder* ( path responder -- )
     begin-form
     path responder call-next-method
-    responder init>> call
+    responder init>> call( -- )
     dup wrap-boilerplate? [
         clone [| body |
             [
index c591b848ec0f94eb0a29e7e8c4c035bd844dd96e..1d5aa43c7b18c99b3f1a0719d3da20c60a36becd 100644 (file)
@@ -4,7 +4,7 @@ http.server furnace furnace.utilities tools.test kernel
 namespaces accessors io.streams.string urls xml.writer ;
 TUPLE: funny-dispatcher < dispatcher ;
 
-: <funny-dispatcher> funny-dispatcher new-dispatcher ;
+: <funny-dispatcher> ( -- dispatcher ) funny-dispatcher new-dispatcher ;
 
 TUPLE: base-path-check-responder ;
 
index adafb215242dc85aee1849c832acf3ac75da4cad..37b2f40e82b5075f16aa2f6c876f1894b791a517 100644 (file)
@@ -17,7 +17,6 @@ USE: vocabs.loader
 "furnace.auth.providers.db" require
 "furnace.auth.providers.null" require
 "furnace.boilerplate" require
-"furnace.chloe-tags" require
 "furnace.conversations" require
 "furnace.db" require
 "furnace.json" require
index 01297288dc8fb4274320854ce9aaeec20f63191a..ff81d73f7f7fd21017a898d59210c800d529e8f6 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors combinators namespaces fry urls http
-http.server http.server.redirection http.server.responses
+USING: kernel accessors combinators namespaces fry urls urls.secure
+http http.server http.server.redirection http.server.responses
 http.server.remapping http.server.filters furnace.utilities ;
 IN: furnace.redirection
 
index e5666c269849d4e63bdaa6aad7739b6a25e97066..0eb00bac2796f7c415b7881eef4ee9fed72fb67c 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel http.server http.server.filters
 http.server.responses furnace.utilities ;
@@ -9,7 +9,7 @@ TUPLE: referrer-check < filter-responder quot ;
 C: <referrer-check> referrer-check
 
 M: referrer-check call-responder*
-    referrer over quot>> call
+    referrer over quot>> call( referrer -- ? )
     [ call-next-method ]
     [ 2drop 403 "Bad referrer" <trivial-response> ] if ;
 
index 14cdce3811b908e6ea111dbea459c053c74e3f70..b325c778cfa2ae8f8aac7d8adcde459e5fd2ec88 100644 (file)
@@ -6,7 +6,7 @@ io.streams.string io.files io.files.temp io.directories
 splitting destructors sequences db db.tuples db.sqlite\r
 continuations urls math.parser furnace furnace.utilities ;\r
 \r
-: with-session\r
+: with-session ( session quot -- )\r
     [\r
         [ [ save-session-after ] [ session set ] bi ] dip call\r
     ] with-destructors ; inline\r
@@ -22,7 +22,7 @@ M: foo call-responder*
     "x" [ 1+ ] schange\r
     "x" sget number>string "text/html" <content> ;\r
 \r
-: url-responder-mock-test\r
+: url-responder-mock-test ( -- )\r
     [\r
         <request>\r
             "GET" >>method\r
@@ -34,7 +34,7 @@ M: foo call-responder*
         [ write-response-body drop ] with-string-writer\r
     ] with-destructors ;\r
 \r
-: sessions-mock-test\r
+: sessions-mock-test ( -- )\r
     [\r
         <request>\r
             "GET" >>method\r
@@ -45,7 +45,7 @@ M: foo call-responder*
         [ write-response-body drop ] with-string-writer\r
     ] with-destructors ;\r
 \r
-: <exiting-action>\r
+: <exiting-action> ( -- action )\r
     <action>\r
         [ [ ] "text/plain" <content> exit-with ] >>display ;\r
 \r
index c0cb7dbced83176a25d1b5063ec4bf8870a19a80..a43466489cb6d3c23bcf8bd6944e444cec9da891 100755 (executable)
@@ -135,4 +135,4 @@ SYMBOL: exit-continuation
     exit-continuation get continue-with ;
 
 : with-exit-continuation ( quot -- value )
-    '[ exit-continuation set @ ] callcc1 exit-continuation off ;
+    '[ exit-continuation set @ ] callcc1 exit-continuation off ; inline
index 376ae5bed20aa0c212d8e825bd7270e19a03bd86..2088e468c64593800b8d869e335f6b618ceb6bfa 100644 (file)
@@ -58,7 +58,7 @@ HELP: npick
 "placed on the top of the stack."\r
 }\r
 { $examples\r
-  { $example "USING: kernel prettyprint generalizations ;" "1 2 3 4 4 npick .s clear" "1\n2\n3\n4\n1" }\r
+  { $example "USING: kernel prettyprint generalizations ;" "1 2 3 4 4 npick 5 narray ." "{ 1 2 3 4 1 }" }\r
   "Some core words expressed in terms of " { $link npick } ":"\r
     { $table\r
         { { $link dup } { $snippet "1 npick" } }\r
@@ -75,7 +75,7 @@ HELP: ndup
 "placed on the top of the stack."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 ndup .s clear" "1\n2\n3\n4\n1\n2\n3\n4" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 ndup 8 narray ." "{ 1 2 3 4 1 2 3 4 }" }\r
   "Some core words expressed in terms of " { $link ndup } ":"\r
     { $table\r
         { { $link dup } { $snippet "1 ndup" } }\r
@@ -91,7 +91,7 @@ HELP: nnip
 "for any number of items."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 3 nnip .s clear" "4" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 3 nnip ." "4" }\r
   "Some core words expressed in terms of " { $link nnip } ":"\r
     { $table\r
         { { $link nip } { $snippet "1 nnip" } }\r
@@ -106,7 +106,7 @@ HELP: ndrop
 "for any number of items."\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 3 ndrop .s clear" "1" }\r
+  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 3 ndrop ." "1" }\r
   "Some core words expressed in terms of " { $link ndrop } ":"\r
     { $table\r
         { { $link drop } { $snippet "1 ndrop" } }\r
@@ -121,7 +121,7 @@ HELP: nrot
 "number of items on the stack. "\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 nrot .s clear" "2\n3\n4\n1" }\r
+  { $example "USING: arrays generalizations kernel prettyprint ;" "1 2 3 4 4 nrot 4array ." "{ 2 3 4 1 }" }\r
   "Some core words expressed in terms of " { $link nrot } ":"\r
     { $table\r
         { { $link swap } { $snippet "1 nrot" } }\r
@@ -135,7 +135,7 @@ HELP: -nrot
 "number of items on the stack. "\r
 }\r
 { $examples\r
-  { $example "USING: prettyprint generalizations kernel ;" "1 2 3 4 4 -nrot .s clear" "4\n1\n2\n3" }\r
+  { $example "USING: arrays generalizations kernel prettyprint ;" "1 2 3 4 4 -nrot 4array ." "{ 4 1 2 3 }" }\r
   "Some core words expressed in terms of " { $link -nrot } ":"\r
     { $table\r
         { { $link swap } { $snippet "1 -nrot" } }\r
@@ -151,8 +151,8 @@ HELP: ndip
 "stack. The quotation can consume and produce any number of items."\r
 } \r
 { $examples\r
-  { $example "USING: generalizations kernel prettyprint kernel ;" "1 2 [ dup ] 1 ndip .s clear" "1\n1\n2" }\r
-  { $example "USING: generalizations kernel prettyprint kernel ;" "1 2 3 [ drop ] 2 ndip .s clear" "2\n3" }\r
+  { $example "USING: arrays generalizations kernel prettyprint ;" "1 2 [ dup ] 1 ndip 3array ." "{ 1 1 2 }" }\r
+  { $example "USING: arrays generalizations kernel prettyprint ;" "1 2 3 [ drop ] 2 ndip 2array ." "{ 2 3 }" }\r
   "Some core words expressed in terms of " { $link ndip } ":"\r
     { $table\r
         { { $link dip } { $snippet "1 ndip" } }\r
@@ -168,7 +168,7 @@ HELP: nslip
 "removed from the stack, the quotation called, and the items restored."\r
 } \r
 { $examples\r
-  { $example "USING: generalizations kernel prettyprint ;" "[ 99 ] 1 2 3 4 5 5 nslip .s clear" "99\n1\n2\n3\n4\n5" }\r
+  { $example "USING: generalizations kernel prettyprint ;" "[ 99 ] 1 2 3 4 5 5 nslip 6 narray ." "{ 99 1 2 3 4 5 }" }\r
   "Some core words expressed in terms of " { $link nslip } ":"\r
     { $table\r
         { { $link slip } { $snippet "1 nslip" } }\r
@@ -184,7 +184,7 @@ HELP: nkeep
 "saved, the quotation called, and the items restored."\r
 } \r
 { $examples\r
-  { $example "USING: generalizations kernel prettyprint ;" "1 2 3 4 5 [ drop drop drop drop drop 99 ] 5 nkeep .s clear" "99\n1\n2\n3\n4\n5" }\r
+  { $example "USING: generalizations kernel prettyprint ;" "1 2 3 4 5 [ drop drop drop drop drop 99 ] 5 nkeep 6 narray ." "{ 99 1 2 3 4 5 }" }\r
   "Some core words expressed in terms of " { $link nkeep } ":"\r
     { $table\r
         { { $link keep } { $snippet "1 nkeep" } }\r
index 1805f4bff9c729d57ee69cd9d2092915662e66c5..ca481cb900fc9645f068d25daf631539881c953a 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Matthew Willis.
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license
-USING: alien alien.syntax alien.destructors combinators system ;
+USING: alien alien.syntax alien.destructors combinators system
+alien.libraries ;
 IN: glib
 
 <<
index 1901f27a24507e2512d93a1f956aaaa0d2f05714..a44f8d7f8d462129605979ca2bec95cc98dc3a48 100644 (file)
@@ -1 +1,2 @@
 Slava Pestov
+Daniel Ehrenberg
index e4ad97abd0c7a3a33c3f157d5ee0f25ee432284b..50ffa65474c839a0aa71dde94741b0bcfff58a3c 100644 (file)
@@ -97,8 +97,7 @@ HELP: <clumps>
     { $example
         "USING: grouping sequences math prettyprint kernel ;"
         "IN: scratchpad"
-        ": share-price"
-        "    { 13/50 51/100 13/50 1/10 4/5 17/20 33/50 3/25 19/100 3/100 } ;"
+        "CONSTANT: share-price { 13/50 51/100 13/50 1/10 4/5 17/20 33/50 3/25 19/100 3/100 }"
         ""
         "share-price 4 <clumps> [ [ sum ] [ length ] bi / ] map ."
         "{ 113/400 167/400 201/400 241/400 243/400 91/200 1/4 }"
index 5f1f07273615c311fb2f2100810148216e875681..6f97c7c3d5412fd65606f39540a6edef2d9b5253 100644 (file)
@@ -4,7 +4,7 @@ IN: hash2.tests
 [ t ] [ 1 2 { 1 2 } 2= ] unit-test
 [ f ] [ 1 3 { 1 2 } 2= ] unit-test
 
-: sample-hash
+: sample-hash ( -- )
     5 <hash2>
     dup 2 3 "foo" roll set-hash2
     dup 4 2 "bar" roll set-hash2
diff --git a/basis/help/apropos/apropos-docs.factor b/basis/help/apropos/apropos-docs.factor
new file mode 100644 (file)
index 0000000..4d774a7
--- /dev/null
@@ -0,0 +1,8 @@
+IN: help.apropos
+USING: help.markup help.syntax strings help.tips ;
+
+HELP: apropos
+{ $values { "str" string } }
+{ $description "Lists all words, vocabularies and help articles whose name contains a subsequence equal to " { $snippet "str" } ". Results are ranked using a simple distance algorithm." } ;
+
+TIP: "Use " { $link apropos } " to search for words, vocabularies and help articles." ;
\ No newline at end of file
diff --git a/basis/help/apropos/apropos-tests.factor b/basis/help/apropos/apropos-tests.factor
new file mode 100644 (file)
index 0000000..3dbda47
--- /dev/null
@@ -0,0 +1,4 @@
+IN: help.apropos.tests
+USING: help.apropos tools.test ;
+
+[ ] [ "swp" apropos ] unit-test
diff --git a/basis/help/apropos/apropos.factor b/basis/help/apropos/apropos.factor
new file mode 100644 (file)
index 0000000..b241db4
--- /dev/null
@@ -0,0 +1,75 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs fry help.markup help.topics io
+kernel make math math.parser namespaces sequences sorting
+summary tools.completion tools.vocabs help.vocabs
+vocabs words unicode.case help ;
+IN: help.apropos
+
+: $completions ( seq -- )
+    dup [ word? ] all? [ words-table ] [
+        dup [ vocab-spec? ] all? [
+            $vocabs
+        ] [
+            [ <$pretty-link> 1array ] map $table
+        ] if
+    ] if ;
+
+TUPLE: more-completions seq ;
+
+CONSTANT: max-completions 5
+
+M: more-completions article-title
+    seq>> length number>string " results" append ;
+
+M: more-completions article-name
+    seq>> length max-completions - number>string " more results" append ;
+
+M: more-completions article-content
+    seq>> sort-values keys \ $completions prefix ;
+
+: (apropos) ( str candidates title -- element )
+    [
+        [ completions ] dip '[
+            _ 1array \ $heading prefix ,
+            [ max-completions short head keys \ $completions prefix , ]
+            [ dup length max-completions > [ more-completions boa <$link> , ] [ drop ] if ]
+            bi
+        ] unless-empty
+    ] { } make ;
+
+: word-candidates ( words -- candidates )
+    [ dup name>> >lower ] { } map>assoc ;
+
+: vocab-candidates ( -- candidates )
+    all-vocabs-seq [ dup vocab-name >lower ] { } map>assoc ;
+
+: help-candidates ( seq -- candidates )
+    [ [ >link ] [ article-title >lower ] bi ] { } map>assoc
+    sort-values ;
+
+: $apropos ( str -- )
+    first
+    [ all-words word-candidates "Words" (apropos) ]
+    [ vocab-candidates "Vocabularies" (apropos) ]
+    [ articles get keys help-candidates "Help articles" (apropos) ]
+    tri 3array print-element ;
+
+TUPLE: apropos search ;
+
+C: <apropos> apropos
+
+M: apropos article-title
+    search>> "Search results for “" "”" surround ;
+
+M: apropos article-name article-title ;
+
+M: apropos article-content
+    search>> 1array \ $apropos prefix ;
+
+M: apropos >link ;
+
+INSTANCE: apropos topic
+
+: apropos ( str -- )
+    <apropos> print-topic ;
index d6693cd94f823d1339abd117e1e14d4993f98940..867f3732098b8d855683b0f934624b3160e5651f 100644 (file)
@@ -117,20 +117,20 @@ $nl
 }
 { $references
     { "Since quotations are objects, they can be constructed and taken apart at will. You can write code that writes code. Arrays are just one of the various types of sequences, and the sequence operations such as " { $link each } " and " { $link map } " operate on all types of sequences. There are many more sequence iteration operations than the ones above, too." }
-    "dataflow"
+    "combinators"
     "sequences"
 } ;
 
-ARTICLE: "cookbook-variables" "Variables cookbook"
-"Before using a variable, you must define a symbol for it:"
-{ $code "SYMBOL: name" }
+ARTICLE: "cookbook-variables" "Dynamic variables cookbook"
 "A symbol is a word which pushes itself on the stack when executed. Try it:"
 { $example "SYMBOL: foo" "foo ." "foo" }
+"Before using a variable, you must define a symbol for it:"
+{ $code "SYMBOL: name" }
 "Symbols can be passed to the " { $link get } " and " { $link set } " words to read and write variable values:"
-{ $example "\"Slava\" name set" "name get print" "Slava" }
+{ $unchecked-example "\"Slava\" name set" "name get print" "Slava" }
 "If you set variables inside a " { $link with-scope } ", their values will be lost after leaving the scope:"
-{ $example
-    ": print-name name get print ;"
+{ $unchecked-example
+    ": print-name ( -- ) name get print ;"
     "\"Slava\" name set"
     "["
     "    \"Diana\" name set"
@@ -139,11 +139,8 @@ ARTICLE: "cookbook-variables" "Variables cookbook"
     "\"Here, the name is \" write  print-name"
     "There, the name is Diana\nHere, the name is Slava"
 }
-{ $curious
-    "Variables are dynamically-scoped in Factor."
-}
 { $references
-    "There is a lot more to be said about variables and namespaces."
+    "There is a lot more to be said about dynamically-scoped variables and namespaces."
     "namespaces"
 } ;
 
index 6ec35b23cede601de9ac6715ce7590b231ac163f..ae227fde89be9440957d96a2663c7955fdd3de1c 100644 (file)
@@ -11,10 +11,7 @@ HELP: article-parent
 
 HELP: help-path
 { $values { "topic" "an article name or a word" } { "seq" "a new sequence" } }
-{ $description "Outputs a sequence of all help articles which contain " { $snippet "topic" } " as a subsection, traversing all the way up to the root." }
-{ $examples
-    { $example "USING: help.crossref prettyprint ;" "\"sequences\" help-path ." "{ \"collections\" \"handbook-language-reference\" \"handbook\" }" }
-} ;
+{ $description "Outputs a sequence of all help articles which contain " { $snippet "topic" } " as a subsection, traversing all the way up to the root." } ;
 
 HELP: xref-article
 { $values { "topic" "an article name or a word" } }
index 47c3105436c7a00e06e5a43c5267332f247077f8..2e01330d73ba9b723c62ae89085666822c19f552 100644 (file)
@@ -4,7 +4,7 @@ definitions assocs sequences kernel namespaces parser arrays
 io.streams.string continuations debugger compiler.units eval ;
 
 [ ] [
-    "IN: help.crossref.tests USING: help.syntax help.markup ; : foo ; HELP: foo \"foo is great\" ; ARTICLE: \"foo\" \"Foo\" { $subsection foo } ;" eval
+    "IN: help.crossref.tests USING: help.syntax help.markup ; : foo ( -- ) ; HELP: foo \"foo is great\" ; ARTICLE: \"foo\" \"Foo\" { $subsection foo } ;" eval
 ] unit-test
 
 [ $subsection ] [
@@ -23,7 +23,7 @@ io.streams.string continuations debugger compiler.units eval ;
 ] unit-test
 
 [ ] [
-    "IN: help.crossref.tests USING: help.syntax help.markup ; : bar ; HELP: bar \"bar is great\" ; ARTICLE: \"bar\" \"Bar\" { $subsection bar } ;" eval
+    "IN: help.crossref.tests USING: help.syntax help.markup ; : bar ( -- ) ; HELP: bar \"bar is great\" ; ARTICLE: \"bar\" \"Bar\" { $subsection bar } ;" eval
 ] unit-test
 
 [ ] [
index 5d83afae8886d91bd3e8a483bd9eb7a3b84d64f9..7bb66eca02fa2e019e72a300ba3889e5c2ae5e9a 100644 (file)
@@ -7,7 +7,7 @@ IN: help.definitions.tests
 
 [
     [ 4 ] [
-        "IN: help.definitions.tests USING: help.syntax ; : hello ; HELP: hello \"test\" ; ARTICLE: \"hello\" \"world\" ; ARTICLE: \"hello2\" \"world\" ;" <string-reader> "foo"
+        "IN: help.definitions.tests USING: help.syntax ; : hello ( -- ) ; HELP: hello \"test\" ; ARTICLE: \"hello\" \"world\" ; ARTICLE: \"hello2\" \"world\" ;" <string-reader> "foo"
         parse-stream drop
 
         "foo" source-file definitions>> first assoc-size
@@ -20,7 +20,7 @@ IN: help.definitions.tests
     ] unit-test
 
     [ 2 ] [
-        "IN: help.definitions.tests USING: help.syntax ; : hello ; ARTICLE: \"hello\" \"world\" ;" <string-reader> "foo"
+        "IN: help.definitions.tests USING: help.syntax ; : hello ( -- ) ; ARTICLE: \"hello\" \"world\" ;" <string-reader> "foo"
         parse-stream drop
 
         "foo" source-file definitions>> first assoc-size
@@ -32,7 +32,7 @@ IN: help.definitions.tests
         "hello" "help.definitions.tests" lookup "help" word-prop
     ] unit-test
 
-    [ ] [ "IN: help.definitions.tests USING: help.syntax ; : xxx ; HELP: xxx ;" eval ] unit-test
+    [ ] [ "IN: help.definitions.tests USING: help.syntax ; : xxx ( -- ) ; HELP: xxx ;" eval ] unit-test
 
     [ ] [ "xxx" "help.definitions.tests" lookup print-topic ] unit-test
 
index f20732c7ee3a68bae35bad20ddc7a21b1706d774..0845264d61312c9068d80f3fd2a0f4f49bb03b6a 100644 (file)
@@ -4,8 +4,8 @@ prettyprint.backend prettyprint.custom kernel.private io generic
 math system strings sbufs vectors byte-arrays quotations
 io.streams.byte-array classes.builtin parser lexer
 classes.predicate classes.union classes.intersection
-classes.singleton classes.tuple tools.vocabs.browser math.parser
-accessors ;
+classes.singleton classes.tuple help.vocabs math.parser
+accessors definitions ;
 IN: help.handbook
 
 ARTICLE: "conventions" "Conventions"
@@ -49,13 +49,15 @@ $nl
     { "associative mapping" { "an object whose class implements the " { $link "assocs-protocol" } } }
     { "boolean"               { { $link t } " or " { $link f } } }
     { "class"                 { "a set of objects identified by a " { $emphasis "class word" } " together with a discriminating predicate. See " { $link "classes" } } }
-    { "definition specifier"  { "a " { $link word } ", " { $link method-spec } ", " { $link link } ", vocabulary specifier, or any other object whose class implements the " { $link "definition-protocol" } } }
+    { "combinator"            { "a word taking a quotation or another word as input; a higher-order function. See " { $link "combinators" } } }
+    { "definition specifier"  { "an instance of " { $link definition } " which implements the " { $link "definition-protocol" } } }
     { "generalized boolean"   { "an object interpreted as a boolean; a value of " { $link f } " denotes false and anything else denotes true" } }
     { "generic word"          { "a word whose behavior depends can be specialized on the class of one of its inputs. See " { $link "generic" } } }
     { "method"                { "a specialized behavior of a generic word on a class. See " { $link "generic" } } }
     { "object"                { "any datum which can be identified" } }
     { "ordering specifier"    { "see " { $link "order-specifiers" } } }
     { "pathname string"       { "an OS-specific pathname which identifies a file" } }
+    { "quotation"             { "an anonymous function; an instance of the " { $link quotation } " class. More generally, instances of the " { $link callable } " class can be used in many places documented to expect quotations" } }
     { "sequence" { "a sequence; see " { $link "sequence-protocol" } } }
     { "slot"                  { "a component of an object which can store a value" } }
     { "stack effect"          { "a pictorial representation of a word's inputs and outputs, for example " { $snippet "+ ( x y -- z )" } ". See " { $link "effects" } } }
@@ -70,7 +72,7 @@ ARTICLE: "tail-call-opt" "Tail-call optimization"
 $nl
 "Tail-call optimization allows iterative algorithms to be implemented in an efficient manner using recursion, without the need for any kind of primitive looping construct in the language. However, in practice, most iteration is performed via combinators such as " { $link while } ", " { $link each } ", " { $link map } ", " { $link assoc-each } ", and so on. The definitions of these combinators do bottom-out in recursive words, however." ;
 
-ARTICLE: "evaluator" "Evaluation semantics"
+ARTICLE: "evaluator" "Stack machine model"
 { $link "quotations" } " are evaluated sequentially from beginning to end. When the end is reached, the quotation returns to its caller. As each object in the quotation is evaluated in turn, an action is taken based on its type:"
 { $list
     { "a " { $link word } " - the word's definition quotation is called. See " { $link "words" } }
@@ -84,12 +86,13 @@ ARTICLE: "objects" "Objects"
 "An " { $emphasis "object" } " is any datum which may be identified. All values are objects in Factor. Each object carries type information, and types are checked at runtime; Factor is dynamically typed."
 { $subsection "equality" }
 { $subsection "math.order" }
-{ $subsection "destructors" }
 { $subsection "classes" }
 { $subsection "tuples" }
 { $subsection "generic" }
-{ $subsection "slots" }
-{ $subsection "mirrors" } ;
+"Advanced features:"
+{ $subsection "delegate" }
+{ $subsection "mirrors" }
+{ $subsection "slots" } ;
 
 ARTICLE: "numbers" "Numbers"
 { $subsection "arithmetic" }
@@ -118,9 +121,9 @@ ARTICLE: "collections" "Collections"
 "Fixed-length sequences:"
 { $subsection "arrays" }
 { $subsection "quotations" }
-"Fixed-length specialized sequences:"
 { $subsection "strings" }
 { $subsection "byte-arrays" }
+{ $subsection "specialized-arrays" }
 "Resizable sequences:"
 { $subsection "vectors" }
 { $subsection "byte-vectors" }
@@ -128,7 +131,8 @@ ARTICLE: "collections" "Collections"
 { $subsection "growable" }
 { $heading "Associative mappings" }
 { $subsection "assocs" }
-{ $subsection "namespaces" }
+{ $subsection "linked-assocs" }
+{ $subsection "biassocs" }
 { $subsection "refs" }
 "Implementations:"
 { $subsection "hashtables" }
@@ -140,30 +144,32 @@ ARTICLE: "collections" "Collections"
 { $subsection "dlists" }
 { $subsection "search-deques" }
 { $heading "Other collections" }
-{ $subsection "boxes" }
+{ $subsection "lists" }
+{ $subsection "disjoint-sets" }
+{ $subsection "interval-maps" }
 { $subsection "heaps" }
+{ $subsection "boxes" }
 { $subsection "graphs" }
 { $subsection "buffers" }
 "There are also many other vocabularies tagged " { $link T{ vocab-tag { name "collections" } } } " in the library." ;
 
-USING: io.encodings.utf8 io.encodings.utf16 io.encodings.binary io.encodings.ascii io.files ;
+USING: io.encodings.utf8 io.encodings.binary io.files ;
 
 ARTICLE: "encodings-introduction" "An introduction to encodings"
 "In order to express text in terms of binary, some sort of encoding has to be used. In a modern context, this is understood as a two-way mapping between Unicode code points (characters) and some amount of binary. Since English isn't the only language in the world, ASCII is not sufficient as a mapping from binary to Unicode; it can't even express em-dashes or curly quotes. Unicode was designed as a universal character set that could potentially represent everything." $nl
 "Not all encodings can represent all Unicode code points, but Unicode can represent basically everything that exists in modern encodings. Some encodings are language-specific, and some can represent everything in Unicode. Though the world is moving toward Unicode and UTF-8, the reality today is that there are several encodings which must be taken into account." $nl
-"Factor uses a system of encoding descriptors to denote encodings. Encoding descriptors are objects which describe encodings. Examples are " { $link utf8 } ", " { $link ascii } " and " { $link binary } ". Encoding descriptors can be passed around independently. Each encoding descriptor has some method for constructing an encoded or decoded stream, and the resulting stream has an encoding descriptor stored which has methods for reading or writing characters." $nl
+"Factor uses a system of encoding descriptors to denote encodings. Encoding descriptors are objects which describe encodings. Examples are " { $link utf8 } " and " { $link binary } ". Encoding descriptors can be passed around independently. Each encoding descriptor has some method for constructing an encoded or decoded stream, and the resulting stream has an encoding descriptor stored which has methods for reading or writing characters." $nl
 "Constructors for streams which deal with bytes usually take an encoding as an explicit parameter. For example, to open a text file for reading whose contents are in UTF-8, use the following"
 { $code "\"file.txt\" utf8 <file-reader>" }
 "If there is an error in the encoded stream, a replacement character (0xFFFD) will be inserted. To throw an exception upon error, use a strict encoding as follows"
 { $code "\"file.txt\" utf8 strict <file-reader>" }
 "In a similar way, encodings can be specified when opening a file for writing."
-{ $code "\"file.txt\" ascii <file-writer>" }
+{ $code "USE: io.encodings.ascii" "\"file.txt\" ascii <file-writer>" }
 "An encoding is also needed for some words that don't return streams, such as " { $link file-contents } ", for example"
-{ $code "\"file.txt\" utf16 file-contents" }
+{ $code "USE: io.encodings.utf16" "\"file.txt\" utf16 file-contents" }
 "Encoding descriptors are also used by " { $link "io.streams.byte-array" } " and taken by combinators like " { $link with-file-writer } " and " { $link with-byte-reader } " which deal with streams. It is " { $emphasis "not" } " used with " { $link "io.streams.string" } " because these deal with abstract text."
 $nl
-"When the " { $link binary } " encoding is used, a " { $link byte-array } " is expected for writing and returned for reading, since the stream deals with bytes. All other encodings deal with strings, since they are used to represent text."
-{ $see-also "stream-elements" } ;
+"When the " { $link binary } " encoding is used, a " { $link byte-array } " is expected for writing and returned for reading, since the stream deals with bytes. All other encodings deal with strings, since they are used to represent text." ;
 
 ARTICLE: "io" "Input and output"
 { $heading "Streams" }
@@ -240,62 +246,82 @@ ARTICLE: "class-index" "Class index"
 { $heading "Predicate classes" }
 { $index [ classes [ predicate-class? ] filter ] } ;
 
-ARTICLE: "program-org" "Program organization"
-{ $subsection "definitions" }
-{ $subsection "vocabularies" }
-{ $subsection "parser" }
-{ $subsection "vocabs.loader" }
-{ $subsection "source-files" } ;
-
 USING: help.cookbook help.tutorial ;
 
 ARTICLE: "handbook-language-reference" "Language reference"
+"Fundamentals:"
 { $subsection "conventions" }
 { $subsection "syntax" }
-{ $subsection "dataflow" }
-{ $subsection "objects" }
-{ $subsection "program-org" }
+{ $subsection "effects" }
+"Data types:"
+{ $subsection "booleans" }
 { $subsection "numbers" }
 { $subsection "collections" }
-{ $subsection "io" }
+"Evaluation semantics:"
+{ $subsection "evaluator" }
+{ $subsection "words" }
+{ $subsection "shuffle-words" }
+{ $subsection "combinators" }
+{ $subsection "errors" }
+{ $subsection "continuations" }
+"Named values:"
+{ $subsection "locals" }
+{ $subsection "namespaces" }
+{ $subsection "namespaces-global" }
+{ $subsection "values" }
+"Abstractions:"
+{ $subsection "objects" }
+{ $subsection "destructors" }
+{ $subsection "macros" }
+{ $subsection "fry" }
+"Program organization:"
+{ $subsection "vocabs.loader" }
 "Vocabularies tagged " { $link T{ vocab-tag { name "extensions" } } } " implement various additional language abstractions." ;
 
 ARTICLE: "handbook-environment-reference" "Environment reference"
+"Parse time and compile time:"
+{ $subsection "parser" }
+{ $subsection "definitions" }
+{ $subsection "vocabularies" }
+{ $subsection "source-files" }
+{ $subsection "compiler" }
+"Tools:"
 { $subsection "prettyprint" }
 { $subsection "tools" }
-{ $subsection "cli" }
-{ $subsection "rc-files" }
 { $subsection "help" }
 { $subsection "inference" }
-{ $subsection "compiler" }
-{ $subsection "system" }
 { $subsection "images" }
-{ $subsection "alien" }
+"VM:"
+{ $subsection "cli" }
+{ $subsection "rc-files" }
 { $subsection "init" }
-{ $subsection "layouts" }
-{ $see-also "program-org" } ;
+{ $subsection "system" }
+{ $subsection "layouts" } ;
 
 ARTICLE: "handbook-library-reference" "Library reference"
 "This index only includes articles from loaded vocabularies. To explore more vocabularies, see " { $link "vocab-index" } "."
 { $index [ "handbook" orphan-articles remove ] } ;
 
-ARTICLE: "handbook" "Factor documentation"
-"Welcome to Factor."
-$nl
-"Explore the code base:"
-{ $subsection "vocab-index" }
+ARTICLE: "handbook" "Factor handbook"
 "Learn the language:"
 { $subsection "cookbook" }
 { $subsection "first-program" }
+"Reference material:"
 { $subsection "handbook-language-reference" }
 { $subsection "handbook-environment-reference" }
+{ $subsection "io" }
 { $subsection "ui" }
+{ $subsection "ui-tools" }
+{ $subsection "unicode" }
+{ $subsection "alien" }
 { $subsection "handbook-library-reference" }
-"The below indices only include articles from loaded vocabularies. To explore more vocabularies, see " { $link "vocab-index" } "."
+"Explore loaded libraries:"
 { $subsection "article-index" }
 { $subsection "primitive-index" }
 { $subsection "error-index" }
 { $subsection "type-index" }
-{ $subsection "class-index" } ;
+{ $subsection "class-index" }
+"Explore the code base:"
+{ $subsection "vocab-index" } ;
 
 ABOUT: "handbook"
index 733199fc606b97f713a6600ff1ac6cd4b8401c66..be521eb93a6c2cc760926e49de9090320144f8e0 100644 (file)
@@ -69,12 +69,6 @@ ARTICLE: "element-types" "Element types"
 IN: help.markup
 ABOUT: "element-types"
 
-ARTICLE: "browsing-help" "Browsing documentation"
-"The easiest way to browse the help is from the help browser tool in the UI, however you can also display help topics in the listener. Help topics are identified by article name strings, or words. You can request a specific help topic:"
-{ $subsection help }
-"You can also display the main help article for a vocabulary:"
-{ $subsection about } ;
-
 ARTICLE: "writing-help" "Writing documentation"
 "By convention, documentation is written in files whose names end with " { $snippet "-docs.factor" } ". Vocabulary documentation should be placed in the same directory as the vocabulary source code; see " { $link "vocabs.loader" } "."
 $nl
@@ -127,6 +121,7 @@ ARTICLE: "help" "Help system"
 { $subsection "browsing-help" }
 { $subsection "writing-help" }
 { $subsection "help.lint" }
+{ $subsection "tips-of-the-day" }
 { $subsection "help-impl" } ;
 
 IN: help
@@ -147,11 +142,6 @@ HELP: help
 { $description
     "Displays a help topic."
 } ;
-HELP: about
-{ $values { "vocab" "a vocabulary specifier" } }
-{ $description
-    "Displays the main help article for the vocabulary. The main help article is set with the " { $link POSTPONE: ABOUT: } " parsing word."
-} ;
 
 HELP: :help
 { $description "Displays documentation for the most recent error." } ;
index 27a81f9948b1eb50ac1bf05c1cfef40dcdc649d4..d20e06b6c6009139cf76e09cd7c9d17ac293badc 100644 (file)
@@ -5,7 +5,7 @@ parser prettyprint sequences words words.symbol assocs
 definitions generic quotations effects slots continuations
 classes.tuple debugger combinators vocabs help.stylesheet
 help.topics help.crossref help.markup sorting classes
-vocabs.loader call ;
+vocabs.loader ;
 IN: help
 
 GENERIC: word-help* ( word -- content )
@@ -127,20 +127,11 @@ help-hook [ [ print-topic ] ] initialize
 : help ( topic -- )
     help-hook get call( topic -- ) ;
 
-: about ( vocab -- )
-    dup require
-    dup vocab [ ] [ no-vocab ] ?if
-    dup vocab-help [ help ] [
-        "The " write vocab-name write
-        " vocabulary does not define a main help article." print
-        "To define one, refer to \\ ABOUT: help" print
-    ] ?if ;
-
 : ($index) ( articles -- )
     sort-articles [ \ $subsection swap 2array ] map print-element ;
 
 : $index ( element -- )
-    first call [ ($index) ] unless-empty ;
+    first call( -- seq ) [ ($index) ] unless-empty ;
 
 : $about ( element -- )
     first vocab-help [ 1array $subsection ] when* ;
diff --git a/basis/help/home/authors.txt b/basis/help/home/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/help/home/home-docs.factor b/basis/help/home/home-docs.factor
new file mode 100644 (file)
index 0000000..e6db2d3
--- /dev/null
@@ -0,0 +1,22 @@
+IN: help.home
+USING: help.markup help.syntax ;
+
+ARTICLE: "help.home" "Factor documentation"
+"If this is your first time with Factor, you can start by writing " { $link "first-program" } "."
+{ $heading "Reference" }
+{ $list
+  { $link "handbook" }
+  { $link "vocab-index" }
+  { $link "ui-tools" }
+}
+{ $heading "Recently visited" }
+{ $table
+  { "Words" "Articles" "Vocabs" }
+  { { $recent recent-words } { $recent recent-articles } { $recent recent-vocabs } }
+}
+"The browser, completion popups and other tools use a common set of " { $link "definitions.icons" } "."
+{ $heading "Recent searches" }
+{ $recent-searches }
+"Use the search field in the top-right of the " { $link "ui-browser" } " window to search for words, vocabularies and help articles." ;
+
+ABOUT: "help.home"
\ No newline at end of file
diff --git a/basis/help/home/home.factor b/basis/help/home/home.factor
new file mode 100644 (file)
index 0000000..9cb3c6f
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays compiler.units fry hashtables help.topics io
+kernel math namespaces sequences sets help.vocabs
+help.apropos vocabs help.markup ;
+IN: help.home
+
+SYMBOLS: recent-words recent-articles recent-vocabs recent-searches ;
+
+CONSTANT: recent-count 10
+
+{ recent-words recent-articles recent-vocabs recent-searches }
+[ [ V{ } clone ] initialize ] each
+
+GENERIC: add-recent-where ( obj -- obj symbol )
+
+M: link add-recent-where recent-articles ;
+M: word-link add-recent-where recent-words ;
+M: vocab-spec add-recent-where recent-vocabs ;
+M: apropos add-recent-where recent-searches ;
+M: object add-recent-where f ;
+
+: $recent ( element -- )
+    first get reverse [ nl ] [ 1array $pretty-link ] interleave ;
+
+: $recent-searches ( element -- )
+    drop recent-searches get [ <$link> ] map $list ;
+
+: redisplay-recent-page ( -- )
+    "help.home" >link dup associate
+    notify-definition-observers ;
+
+: expire ( seq -- )
+    [ length recent-count - [ 0 > ] keep ] keep
+    '[ 0 _ _ delete-slice ] when ;
+
+: add-recent ( obj -- )
+    add-recent-where dup
+    [ get [ adjoin ] [ expire ] bi ] [ 2drop ] if
+    redisplay-recent-page ;
\ No newline at end of file
index cbeb8b362e26e423a7bd9677c27ded830003bec1..d880af5b555bab654f3768ca94340740cf30f22f 100644 (file)
@@ -3,7 +3,7 @@
 USING: io.encodings.utf8 io.encodings.ascii io.encodings.binary
 io.files io.files.temp io.directories html.streams help kernel
 assocs sequences make words accessors arrays help.topics vocabs
-tools.vocabs tools.vocabs.browser namespaces prettyprint io
+tools.vocabs help.vocabs namespaces prettyprint io
 vocabs.loader serialize fry memoize unicode.case math.order
 sorting debugger html xml.syntax xml.writer ;
 IN: help.html
@@ -60,7 +60,7 @@ M: topic url-of topic>filename ;
 : help>html ( topic -- xml )
     [ article-title ]
     [ drop help-stylesheet ]
-    [ [ help ] with-html-writer ]
+    [ [ print-topic ] with-html-writer ]
     tri simple-page ;
           
 : generate-help-file ( topic -- )
index 2281c295c394429fa0a9d57e5253e28497e4037c..7ec8c59ba6be75f0442004aed6d285527f3db086 100755 (executable)
@@ -7,20 +7,20 @@ combinators combinators.short-circuit splitting debugger
 hashtables sorting effects vocabs vocabs.loader assocs editors
 continuations classes.predicate macros math sets eval
 vocabs.parser words.symbol values grouping unicode.categories
-sequences.deep call ;
+sequences.deep ;
 IN: help.lint
 
 SYMBOL: vocabs-quot
 
 : check-example ( element -- )
-    [
-        rest [
+    '[
+        rest [
             but-last "\n" join
             [ (eval>string) ] call( code -- output )
             "\n" ?tail drop
         ] keep
         peek assert=
-    ] vocabs-quot get call ;
+    ] vocabs-quot get call( quot -- ) ;
 
 : check-examples ( element -- )
     \ $example swap elements [ check-example ] each ;
index 74bc45d36c507799a046616119a721c9c7316d93..9b928f3691cb84d7e15bf71b773b04eeb4f2d046 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: blahblah quux ;
 [ ] [ \ >>quux print-topic ] unit-test
 [ ] [ \ blahblah? print-topic ] unit-test
 
-: fooey "fooey" throw ;
+: fooey ( -- * ) "fooey" throw ;
 
 [ ] [ \ fooey print-topic ] unit-test
 
index ea64def75194a6ab606baf947f447b5a4625d23e..8b5edf38c13442c1c2c342ea020ae9cafdb72319 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors arrays definitions generic io kernel assocs
 hashtables namespaces make parser prettyprint sequences strings
 io.styles vectors words math sorting splitting classes slots fry
 sets vocabs help.stylesheet help.topics vocabs.loader quotations
-combinators call see ;
+combinators see present ;
 IN: help.markup
 
 PREDICATE: simple-element < array
@@ -140,6 +140,9 @@ ALIAS: $slot $snippet
 : $image ( element -- )
     [ [ "" ] dip first image associate format ] ($span) ;
 
+: <$image> ( path -- element )
+    1array \ $image prefix ;
+
 ! Some links
 : write-link ( string object -- )
     link-style get [ write-object ] with-style ;
@@ -276,7 +279,7 @@ M: f ($instance)
     $snippet ;
 
 : values-row ( seq -- seq )
-    unclip \ $snippet swap ?word-name 2array
+    unclip \ $snippet swap present 2array
     swap dup first word? [ \ $instance prefix ] when 2array ;
 
 : $values ( element -- )
index 9f98ba6d8d607949dcef701a3a758ef9d74a5fbd..1844d18d944c9ba56dc24e9aa61431e1a88590a9 100644 (file)
@@ -1,23 +1,19 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel parser sequences words help
 help.topics namespaces vocabs definitions compiler.units
 vocabs.parser ;
 IN: help.syntax
 
-: HELP:
+SYNTAX: HELP:
     scan-word bootstrap-word
-    dup set-word
-    dup >link save-location
-    \ ; parse-until >array swap set-word-help ; parsing
+    [ >link save-location ] [ [ \ ; parse-until >array ] dip set-word-help ] bi ;
 
-: ARTICLE:
+SYNTAX: ARTICLE:
     location [
-        \ ; parse-until >array [ first2 ] keep 2 tail <article>
+        \ ; parse-until >array [ first2 ] [ 2 tail ] bi <article>
         over add-article >link
-    ] dip remember-definition ; parsing
+    ] dip remember-definition ;
 
-: ABOUT:
-    in get vocab
-    dup changed-definition
-    scan-object >>help drop ; parsing
+SYNTAX: ABOUT:
+    in get vocab scan-object >>help changed-definition ;
diff --git a/basis/help/syntax/tags.txt b/basis/help/syntax/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/basis/help/tips/authors.txt b/basis/help/tips/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/help/tips/tips-docs.factor b/basis/help/tips/tips-docs.factor
new file mode 100644 (file)
index 0000000..030c546
--- /dev/null
@@ -0,0 +1,41 @@
+IN: help.tips
+USING: help.markup help.syntax debugger prettyprint see help help.vocabs
+help.apropos tools.time stack-checker editors memory ;
+
+TIP: "To look at the most recent error, run " { $link :error } ". To look at the most recent error's callstack, run " { $link :c } "." ;
+
+TIP: "Learn to use " { $link "dataflow-combinators" } "." ;
+
+TIP: "Learn to use " { $link "editor" } " to be able to jump to the source code for word definitions from the listener." ;
+
+TIP: "Check out " { $url "http://concatenative.org/wiki/view/Factor/FAQ" } " to get answers to frequently-asked questions." ;
+
+TIP: "Drop by the " { $snippet "#concatenative" } " IRC channel on " { $snippet "irc.freenode.net" } " some time." ;
+
+TIP: "You can write documentation for your own code using the " { $link "help" } "." ;
+
+TIP: "You can write graphical applications using the " { $link "ui" } "." ;
+
+TIP: "Power tools: " { $links see edit help about apropos time infer. } ;
+
+TIP: "Tips of the day implement the " { $link "definition-protocol" } " and new tips of the day can be defined using the " { $link POSTPONE: TIP: } " parsing word." ;
+
+TIP: "Try some simple demo applications, then look at the source code in " { $snippet "extra/" } ": " { $snippet "\"demos\" run" } ;
+
+TIP: "To save time on reloading big libraries such as the " { $vocab-link "furnace" } " web framework, save the image after loading them using the " { $link save } " word." ;
+
+HELP: TIP:
+{ $syntax "TIP: content ;" }
+{ $values { "content" "a markup element" } }
+{ $description "Defines a new tip of the day." } ;
+  
+ARTICLE: "all-tips-of-the-day" "All tips of the day"
+{ $tips-of-the-day } ;
+
+ARTICLE: "tips-of-the-day" "Tips of the day"
+"The " { $vocab-link "help.tips" } " vocabulary provides a facility for displaying tips of the day in the " { $link "ui-listener" } ". Tips are defined with a parsing word:"
+{ $subsection POSTPONE: TIP: }
+"All tips defined so far:"
+{ $subsection "all-tips-of-the-day" } ;
+
+ABOUT: "tips-of-the-day"
\ No newline at end of file
diff --git a/basis/help/tips/tips.factor b/basis/help/tips/tips.factor
new file mode 100644 (file)
index 0000000..4685b6c
--- /dev/null
@@ -0,0 +1,61 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: parser arrays namespaces sequences random help.markup help.stylesheet
+kernel io io.styles colors.constants definitions accessors ;
+IN: help.tips
+
+SYMBOL: tips
+
+tips [ V{ } clone ] initialize
+
+TUPLE: tip < identity-tuple content loc ;
+
+M: tip forget* tips get delq ;
+
+M: tip where loc>> ;
+
+M: tip set-where (>>loc) ;
+
+: <tip> ( content -- tip ) f tip boa ;
+
+: add-tip ( tip -- ) tips get push ;
+
+SYNTAX: TIP:
+    parse-definition >array <tip>
+    [ save-location ] [ add-tip ] bi ;
+
+: a-tip ( -- tip ) tips get random ;
+
+SYMBOL: tip-of-the-day-style
+
+H{
+    { page-color COLOR: lavender }
+    { border-width 5 }
+    { wrap-margin 500 }
+} tip-of-the-day-style set-global
+
+: $tip-title ( tip -- )
+    [
+        heading-style get [
+            [ "Tip of the day" ] dip write-object
+        ] with-style
+    ] ($block) ;
+
+: $tip-of-the-day ( element -- )
+    drop
+    [
+        tip-of-the-day-style get
+        [
+            last-element off
+            a-tip [ $tip-title ] [ content>> print-element nl ] bi
+            "— " print-element "all-tips-of-the-day" ($link)
+        ]
+        with-nesting
+    ] ($heading) ;
+
+: tip-of-the-day. ( -- ) { $tip-of-the-day } print-content nl ;
+
+: $tips-of-the-day ( element -- )
+    drop tips get [ nl nl ] [ content>> print-element ] interleave ;
+
+INSTANCE: tip definition
\ No newline at end of file
index 864b030126947b5f1d1b41441da555169c194359..a251849e8f87fa2507a15d4f2a91fa2f8864bbfd 100644 (file)
@@ -7,8 +7,12 @@ IN: help.topics
 
 TUPLE: link name ;
 
+INSTANCE: link definition
+
 MIXIN: topic
+
 INSTANCE: link topic
+
 INSTANCE: word topic
 
 GENERIC: >link ( obj -- obj )
index 7ec155881bc5f3a07b632a7a5230744074ab8d96..26812947c0c3880f2511038ab7443ae0274b2099 100644 (file)
@@ -62,7 +62,9 @@ ARTICLE: "first-program-test" "Testing your first program"
     ""
     ": palindrome? ( str -- ? ) dup reverse = ;"
 }
-"We will now test our new word in the listener. First, push a string on the stack:"
+"We will now test our new word in the listener. First we have add the palindrome vocabulary to the listener's vocabulary search path:"
+{ $code "USE: palindrome"}
+"Next, push a string on the stack:"
 { $code "\"hello\"" }
 "Note that the stack display in the listener now shows this string. Having supplied the input, we call our word:"
 { $code "palindrome?" }
@@ -132,6 +134,8 @@ $nl
 $nl
 "We modify " { $snippet "palindrome?" } " to first apply " { $snippet "normalize" } " to its input:"
 { $code ": palindrome? ( str -- ? ) normalize dup reverse = ;" }
+"Factor compiles the file from the top down. So, be sure to place the definition for " { $snippet "normalize" } " above the definition for " { $snippet "palindrome?" } "."
+$nl
 "Now if you press " { $command tool "common" refresh-all } ", the source file should reload without any errors. You can run unit tests again, and this time, they will all pass:"
 { $code "\"palindrome\" test" } ;
 
diff --git a/basis/help/vocabs/authors.txt b/basis/help/vocabs/authors.txt
new file mode 100755 (executable)
index 0000000..e1907c6
--- /dev/null
@@ -0,0 +1,2 @@
+Slava Pestov
+Eduardo Cavazos
diff --git a/basis/help/vocabs/summary.txt b/basis/help/vocabs/summary.txt
new file mode 100644 (file)
index 0000000..28b4850
--- /dev/null
@@ -0,0 +1 @@
+Browsing vocabularies
diff --git a/basis/help/vocabs/tags.txt b/basis/help/vocabs/tags.txt
new file mode 100644 (file)
index 0000000..ef1aab0
--- /dev/null
@@ -0,0 +1 @@
+tools
diff --git a/basis/help/vocabs/vocabs-docs.factor b/basis/help/vocabs/vocabs-docs.factor
new file mode 100644 (file)
index 0000000..cbedce2
--- /dev/null
@@ -0,0 +1,38 @@
+USING: help help.topics help.markup help.syntax io strings ;
+IN: help.vocabs
+
+ARTICLE: "vocab-tags" "Vocabulary tags"
+{ $all-tags } ;
+
+ARTICLE: "vocab-authors" "Vocabulary authors"
+{ $all-authors } ;
+
+ARTICLE: "vocab-index" "Vocabulary index"
+{ $subsection "vocab-tags" }
+{ $subsection "vocab-authors" }
+{ $vocab "" } ;
+
+HELP: words.
+{ $values { "vocab" "a vocabulary name" } }
+{ $description "Printings a listing of all the words in a vocabulary, categorized by type." } ;
+
+HELP: about
+{ $values { "vocab" "a vocabulary specifier" } }
+{ $description
+    "Displays the main help article for the vocabulary. The main help article is set with the " { $link POSTPONE: ABOUT: } " parsing word."
+} ;
+
+ARTICLE: "browsing-help" "Browsing documentation"
+"Help topics are instances of a mixin:"
+{ $subsection topic }
+"Most commonly, topics are article name strings, or words. You can display a specific help topic:"
+{ $subsection help }
+"You can also display the help for a vocabulary:"
+{ $subsection about }
+"To list a vocabulary's words only:"
+{ $subsection words. }
+{ $examples
+  { $code "\"evaluator\" help" }
+  { $code "\\ + help" }
+  { $code "\"io.files\" about" }
+} ;
\ No newline at end of file
diff --git a/basis/help/vocabs/vocabs-tests.factor b/basis/help/vocabs/vocabs-tests.factor
new file mode 100644 (file)
index 0000000..f03e0b3
--- /dev/null
@@ -0,0 +1,5 @@
+IN: help.vocabs.tests
+USING: help.vocabs tools.test help.markup help vocabs ;
+
+[ ] [ { $vocab "scratchpad" } print-content ] unit-test
+[ ] [ "classes" vocab print-topic ] unit-test
\ No newline at end of file
diff --git a/basis/help/vocabs/vocabs.factor b/basis/help/vocabs/vocabs.factor
new file mode 100644 (file)
index 0000000..a8c93fe
--- /dev/null
@@ -0,0 +1,308 @@
+! Copyright (C) 2007, 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs classes classes.builtin
+classes.intersection classes.mixin classes.predicate
+classes.singleton classes.tuple classes.union combinators
+definitions effects fry generic help help.markup help.stylesheet
+help.topics io io.files io.pathnames io.styles kernel macros
+make namespaces prettyprint sequences sets sorting summary
+tools.vocabs vocabs vocabs.loader words words.symbol definitions.icons ;
+IN: help.vocabs
+
+: about ( vocab -- )
+    [ require ] [ vocab help ] bi ;
+
+: $pretty-link ( element -- )
+    [ first definition-icon 1array $image " " print-element ]
+    [ $definition-link ]
+    bi ;
+
+: <$pretty-link> ( definition -- element )
+    1array \ $pretty-link prefix ;
+
+: vocab-row ( vocab -- row )
+    [ <$pretty-link> ] [ vocab-summary ] bi 2array ;
+
+: vocab-headings ( -- headings )
+    {
+        { $strong "Vocabulary" }
+        { $strong "Summary" }
+    } ;
+
+: root-heading ( root -- )
+    [ "Children from " prepend ] [ "Children" ] if*
+    $heading ;
+
+: $vocabs ( seq -- )
+    [ vocab-row ] map vocab-headings prefix $table ;
+
+: $vocab-roots ( assoc -- )
+    [
+        [ drop ] [ [ root-heading ] [ $vocabs ] bi* ] if-empty
+    ] assoc-each ;
+
+TUPLE: vocab-tag name ;
+
+INSTANCE: vocab-tag topic
+
+C: <vocab-tag> vocab-tag
+
+: $tags ( seq -- ) [ <vocab-tag> ] map $links ;
+
+TUPLE: vocab-author name ;
+
+INSTANCE: vocab-author topic
+
+C: <vocab-author> vocab-author
+
+: $authors ( seq -- ) [ <vocab-author> ] map $links ;
+
+: describe-help ( vocab -- )
+    [
+        dup vocab-help
+        [ "Documentation" $heading ($link) ]
+        [ "Summary" $heading vocab-summary print-element ]
+        ?if
+    ] unless-empty ;
+
+: describe-children ( vocab -- )
+    vocab-name all-child-vocabs $vocab-roots ;
+
+: files. ( seq -- )
+    snippet-style get [
+        code-style get [
+            [ nl ] [ [ string>> ] keep write-object ] interleave
+        ] with-nesting
+    ] with-style ;
+
+: describe-files ( vocab -- )
+    vocab-files [ <pathname> ] map [
+        "Files" $heading
+        [
+            files.
+        ] ($block)
+    ] unless-empty ;
+
+: describe-tuple-classes ( classes -- )
+    [
+        "Tuple classes" $subheading
+        [
+            [ <$pretty-link> ]
+            [ superclass <$pretty-link> ]
+            [ "slots" word-prop [ name>> ] map " " join <$snippet> ]
+            tri 3array
+        ] map
+        { { $strong "Class" } { $strong "Superclass" } { $strong "Slots" } } prefix
+        $table
+    ] unless-empty ;
+
+: describe-predicate-classes ( classes -- )
+    [
+        "Predicate classes" $subheading
+        [
+            [ <$pretty-link> ]
+            [ superclass <$pretty-link> ]
+            bi 2array
+        ] map
+        { { $strong "Class" } { $strong "Superclass" } } prefix
+        $table
+    ] unless-empty ;
+
+: (describe-classes) ( classes heading -- )
+    '[
+        _ $subheading
+        [ <$pretty-link> 1array ] map $table
+    ] unless-empty ;
+
+: describe-builtin-classes ( classes -- )
+    "Builtin classes" (describe-classes) ;
+
+: describe-singleton-classes ( classes -- )
+    "Singleton classes" (describe-classes) ;
+
+: describe-mixin-classes ( classes -- )
+    "Mixin classes" (describe-classes) ;
+
+: describe-union-classes ( classes -- )
+    "Union classes" (describe-classes) ;
+
+: describe-intersection-classes ( classes -- )
+    "Intersection classes" (describe-classes) ;
+
+: describe-classes ( classes -- )
+    [ builtin-class? ] partition
+    [ tuple-class? ] partition
+    [ singleton-class? ] partition
+    [ predicate-class? ] partition
+    [ mixin-class? ] partition
+    [ union-class? ] partition
+    [ intersection-class? ] filter
+    {
+        [ describe-builtin-classes ]
+        [ describe-tuple-classes ]
+        [ describe-singleton-classes ]
+        [ describe-predicate-classes ]
+        [ describe-mixin-classes ]
+        [ describe-union-classes ]
+        [ describe-intersection-classes ]
+    } spread ;
+
+: word-syntax ( word -- string/f )
+    \ $syntax swap word-help elements dup length 1 =
+    [ first second ] [ drop f ] if ;
+
+: describe-parsing ( words -- )
+    [
+        "Parsing words" $subheading
+        [
+            [ <$pretty-link> ]
+            [ word-syntax dup [ <$snippet> ] when ]
+            bi 2array
+        ] map
+        { { $strong "Word" } { $strong "Syntax" } } prefix
+        $table
+    ] unless-empty ;
+
+: word-row ( word -- element )
+    [ <$pretty-link> ]
+    [ stack-effect dup [ effect>string <$snippet> ] when ]
+    bi 2array ;
+
+: word-headings ( -- element )
+    { { $strong "Word" } { $strong "Stack effect" } } ;
+
+: words-table ( words -- )
+    [ word-row ] map word-headings prefix $table ;
+
+: (describe-words) ( words heading -- )
+    '[ _ $subheading words-table ] unless-empty ;
+
+: describe-generics ( words -- )
+    "Generic words" (describe-words) ;
+
+: describe-macros ( words -- )
+    "Macro words" (describe-words) ;
+
+: describe-primitives ( words -- )
+    "Primitives" (describe-words) ;
+
+: describe-compounds ( words -- )
+    "Ordinary words" (describe-words) ;
+
+: describe-predicates ( words -- )
+    "Class predicate words" (describe-words) ;
+
+: describe-symbols ( words -- )
+    [
+        "Symbol words" $subheading
+        [ <$pretty-link> 1array ] map $table
+    ] unless-empty ;
+
+: $words ( words -- )
+    [
+        "Words" $heading
+
+        natural-sort
+        [ [ class? ] filter describe-classes ]
+        [
+            [ [ class? ] [ symbol? ] bi and not ] filter
+            [ parsing-word? ] partition
+            [ generic? ] partition
+            [ macro? ] partition
+            [ symbol? ] partition
+            [ primitive? ] partition
+            [ predicate? ] partition swap
+            {
+                [ describe-parsing ]
+                [ describe-generics ]
+                [ describe-macros ]
+                [ describe-symbols ]
+                [ describe-primitives ]
+                [ describe-compounds ]
+                [ describe-predicates ]
+            } spread
+        ] bi
+    ] unless-empty ;
+
+: words. ( vocab -- )
+    last-element off
+    [ require ] [ words $words ] bi nl ;
+
+: describe-metadata ( vocab -- )
+    [
+        [ vocab-tags [ "Tags:" swap \ $tags prefix 2array , ] unless-empty ]
+        [ vocab-authors [ "Authors:" swap \ $authors prefix 2array , ] unless-empty ]
+        bi
+    ] { } make
+    [ "Meta-data" $heading $table ] unless-empty ;
+
+: $vocab ( element -- )
+    first {
+        [ describe-help ]
+        [ describe-metadata ]
+        [ words $words ]
+        [ describe-files ]
+        [ describe-children ]
+    } cleave ;
+
+: keyed-vocabs ( str quot -- seq )
+    [ all-vocabs ] 2dip '[ [ _ swap @ member? ] filter ] assoc-map ; inline
+
+: tagged ( tag -- assoc )
+    [ vocab-tags ] keyed-vocabs ;
+
+: authored ( author -- assoc )
+    [ vocab-authors ] keyed-vocabs ;
+
+: $tagged-vocabs ( element -- )
+    first tagged $vocab-roots ;
+
+: $authored-vocabs ( element -- )
+    first authored $vocab-roots ;
+
+: $all-tags ( element -- )
+    drop "Tags" $heading all-tags $tags ;
+
+: $all-authors ( element -- )
+    drop "Authors" $heading all-authors $authors ;
+
+INSTANCE: vocab topic
+
+INSTANCE: vocab-link topic
+
+M: vocab-spec article-title vocab-name " vocabulary" append ;
+
+M: vocab-spec article-name vocab-name ;
+
+M: vocab-spec article-content
+    vocab-name \ $vocab swap 2array ;
+
+M: vocab-spec article-parent drop "vocab-index" ;
+
+M: vocab-tag >link ;
+
+M: vocab-tag article-title
+    name>> "Vocabularies tagged “" "”" surround ;
+
+M: vocab-tag article-name name>> ;
+
+M: vocab-tag article-content
+    \ $tagged-vocabs swap name>> 2array ;
+
+M: vocab-tag article-parent drop "vocab-tags" ;
+
+M: vocab-tag summary article-title ;
+
+M: vocab-author >link ;
+
+M: vocab-author article-title
+    name>> "Vocabularies by " prepend ;
+
+M: vocab-author article-name name>> ;
+
+M: vocab-author article-content
+    \ $authored-vocabs swap name>> 2array ;
+
+M: vocab-author article-parent drop "vocab-authors" ;
+
+M: vocab-author summary article-title ;
index 4093666eb7fa59f3c864d0990fe655171e687ac1..2534e0121f984e8ae1aaa9e629fdc2502cb944f1 100644 (file)
@@ -25,7 +25,7 @@ M: object specializer-declaration class ;
     [ drop object eq? not ] assoc-filter
     [ [ t ] ] [
         [ swap specializer-predicate append ] { } assoc>map
-        unclip [ swap [ f ] \ if 3array append [ ] like ] reduce
+        [ ] [ swap [ f ] \ if 3array append [ ] like ] map-reduce
     ] if-empty ;
 
 : specializer-cases ( quot word -- default alist )
@@ -34,16 +34,18 @@ M: object specializer-declaration class ;
         [ specializer-declaration ] map '[ _ declare ] pick append
     ] { } map>assoc ;
 
+: specialize-quot ( quot specializer -- quot' )
+    specializer-cases alist>quot ;
+
 : method-declaration ( method -- quot )
     [ "method-generic" word-prop dispatch# object <array> ]
     [ "method-class" word-prop ]
     bi prefix ;
 
 : specialize-method ( quot method -- quot' )
-    method-declaration '[ _ declare ] prepend ;
-
-: specialize-quot ( quot specializer -- quot' )
-    specializer-cases alist>quot ;
+    [ method-declaration '[ _ declare ] prepend ]
+    [ "method-generic" word-prop "specializer" word-prop ] bi
+    [ specialize-quot ] when* ;
 
 : standard-method? ( method -- ? )
     dup method-body? [
@@ -52,19 +54,19 @@ M: object specializer-declaration class ;
 
 : specialized-def ( word -- quot )
     [ def>> ] keep
-    [ dup standard-method? [ specialize-method ] [ drop ] if ]
-    [ "specializer" word-prop [ specialize-quot ] when* ]
-    bi ;
+    dup generic? [ drop ] [
+        [ dup standard-method? [ specialize-method ] [ drop ] if ]
+        [ "specializer" word-prop [ specialize-quot ] when* ]
+        bi
+    ] if ;
 
 : specialized-length ( specializer -- n )
     dup [ array? ] all? [ first ] when length ;
 
-: HINTS:
+SYNTAX: HINTS:
     scan-object
-    dup method-spec? [ first2 method ] when
     [ redefined ]
     [ parse-definition "specializer" set-word-prop ] bi ;
-    parsing
 
 ! Default specializers
 { first first2 first3 first4 }
@@ -116,6 +118,6 @@ M: object specializer-declaration class ;
 
 \ >be { { bignum fixnum } { fixnum fixnum } } "specializer" set-word-prop
 
-\ hashtable \ at* method { { fixnum hashtable } { word hashtable } } "specializer" set-word-prop
+M\ hashtable at* { { fixnum object } { word object } } "specializer" set-word-prop
 
-\ hashtable \ set-at method { { object fixnum object } { object word object } } "specializer" set-word-prop
+M\ hashtable set-at { { object fixnum object } { object word object } } "specializer" set-word-prop
index 0b85455c2e8f8a7fcf92ca6171ebb1a0fdd9afaa..72ceea20a0155d875f112474eb0f65a10777355e 100644 (file)
@@ -163,7 +163,7 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ;
 
 [ ] [ "-foo\n-bar" "farkup" set-value ] unit-test
 
-[ "<ul><li>foo</li>\n<li>bar</li></ul>" ] [
+[ "<ul><li>foo</li><li>bar</li></ul>" ] [
     [ "farkup" T{ farkup } render ] with-string-writer
 ] unit-test
 
index d5c744beab540c65f160e252f314073212879daa..cc8b4f0a1595cc36566fae4b4dc08b5f2e1a5cd0 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov
+! Copyright (C) 2008, 2009 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors strings namespaces assocs hashtables io
 mirrors math fry sequences words continuations
@@ -96,7 +96,7 @@ C: <validation-error> validation-error
     >hashtable "validators" set-word-prop ;
 
 : validate ( value quot -- result )
-    [ <validation-error> ] recover ; inline
+    '[ _ call( value -- validated ) ] [ <validation-error> ] recover ;
 
 : validate-value ( name value quot -- )
     validate
index 249861b12a8b93e7c6125ec827705219b4a5eb81..835874cbb751030659993b8c186b8f4d4b64e36c 100644 (file)
@@ -61,6 +61,4 @@ M: funky url-of "http://www.funky-town.com/" swap town>> append ;
     [ H{ } [ ] with-nesting nl ] make-html-string
 ] unit-test
 
-[ ] [ [ { 1 2 3 } describe ] with-html-writer drop ] unit-test
-
-[ ] [ [ \ predicate-instance? def>> . ] with-html-writer drop ] unit-test
+[ ] [ [ { 1 2 3 } describe ] with-html-writer drop ] unit-test
\ No newline at end of file
index 86f86a8468e8b62bd4c88b312de78b842497a8c9..fd786d355dba983bd4a6a8b0bc1388849b4e9535 100644 (file)
@@ -5,7 +5,7 @@ splitting unicode.categories furnace accessors
 html.templates.chloe.compiler ;
 IN: html.templates.chloe.tests
 
-: run-template
+: run-template ( quot -- string )
     with-string-writer [ "\r\n\t" member? not ] filter
     "?>" split1 nip ; inline
 
@@ -37,7 +37,7 @@ IN: html.templates.chloe.tests
     ] run-template
 ] unit-test
 
-: test4-aux? t ;
+: test4-aux? ( -- ? ) t ;
 
 [ "True" ] [
     [
@@ -45,7 +45,7 @@ IN: html.templates.chloe.tests
     ] run-template
 ] unit-test
 
-: test5-aux? f ;
+: test5-aux? ( -- ? ) f ;
 
 [ "" ] [
     [
index da0d45a9d4f1489556896b4e093f11a54804ec31..1fe90b08d3d51f56afbd204214c2aa7809a61a9d 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors kernel sequences combinators kernel fry
 namespaces make classes.tuple assocs splitting words arrays io
 io.files io.files.info io.encodings.utf8 io.streams.string
 unicode.case mirrors math urls present multiline quotations xml
-logging call
+logging
 xml.data xml.writer xml.syntax strings
 html.forms
 html
index 3cb7523bdc204bf10acaf144b4c055308c4ba6fe..92e4a8dc494ea63d558f07cda1e4f4cc732e7653 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs namespaces make kernel sequences accessors
 combinators strings splitting io io.streams.string present
-xml.writer xml.data xml.entities html.forms call
+xml.writer xml.data xml.entities html.forms
 html.templates html.templates.chloe.syntax ;
 IN: html.templates.chloe.compiler
 
index 19f2019266f4fc142bf1962901f86b954bca6254..d69dc085371f28d0a7041f6432630e7a6ac82131 100644 (file)
@@ -25,8 +25,7 @@ M: tuple-class component-tag ( tag class -- )
     [ compile-component-attrs ] 2bi
     [ render ] [code] ;
 
-: COMPONENT:
+SYNTAX: COMPONENT:
     scan-word
     [ name>> ] [ '[ _ component-tag ] ] bi
     define-chloe-tag ;
-    parsing
index 7af37b65929831ace268e9437c31c1dd6d6ff1b8..7c47a44d9efee186f87e6c7ffff88b65e00b73b0 100644 (file)
@@ -15,8 +15,8 @@ tags [ H{ } clone ] initialize
 
 : define-chloe-tag ( name quot -- ) swap tags get set-at ;
 
-: CHLOE:
-    scan parse-definition define-chloe-tag ; parsing
+SYNTAX: CHLOE:
+    scan parse-definition define-chloe-tag ;
 
 CONSTANT: chloe-ns "http://factorcode.org/chloe/1.0"
 
index 78202d6460ac96460ba53858dee3d1de90e0eff8..21e9f8352d9119ba6c23edb760de9992022d5382 100644 (file)
@@ -3,7 +3,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations sequences kernel namespaces debugger
 combinators math quotations generic strings splitting accessors
-assocs fry vocabs.parser parser lexer io io.files call
+assocs fry vocabs.parser parser lexer io io.files
 io.streams.string io.encodings.utf8 html.templates ;
 IN: html.templates.fhtml
 
@@ -49,7 +49,7 @@ DEFER: <% delimiter
         drop
     ] if ;
 
-: %> lexer get parse-%> ; parsing
+SYNTAX: %> lexer get parse-%> ;
 
 : parse-template-lines ( lines -- quot )
     <template-lexer> [
@@ -65,7 +65,7 @@ DEFER: <% delimiter
     ] with-file-vocabs ;
 
 : eval-template ( string -- )
-    parse-template call ;
+    parse-template call( -- ) ;
 
 TUPLE: fhtml path ;
 
index 4a416e353fbf58baaa66c7418e84367e6a1a922f..aebae701ed07d4a85c78f3d6c9d6413e0bd0ac73 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel fry io io.encodings.utf8 io.files
 debugger prettyprint continuations namespaces boxes sequences
@@ -12,7 +12,7 @@ GENERIC: call-template* ( template -- )
 
 M: string call-template* write ;
 
-M: callable call-template* call ;
+M: callable call-template* call( -- ) ;
 
 M: xml call-template* write-xml ;
 
index 22d772d2b679df2a338ae3e02e7bd5a50d3c8310..f4764ff6f20ec1e6ac13252b6a6f54a1160ee69f 100644 (file)
@@ -6,7 +6,7 @@ math.order hashtables byte-arrays destructors
 io io.sockets io.streams.string io.files io.timeouts
 io.pathnames io.encodings io.encodings.string io.encodings.ascii
 io.encodings.utf8 io.encodings.8-bit io.encodings.binary io.crlf
-io.streams.duplex fry ascii urls urls.encoding present prettyprint 
+io.streams.duplex fry ascii urls urls.encoding present locals
 http http.parsers http.client.post-data ;
 IN: http.client
 
@@ -77,12 +77,13 @@ SYMBOL: redirects
 : redirect? ( response -- ? )
     code>> 300 399 between? ;
 
-: do-redirect ( quot: ( chunk -- ) response -- response )
+:: do-redirect ( quot: ( chunk -- ) response -- response )
     redirects inc
     redirects get max-redirects < [
         request get clone
-        swap "location" header redirect-url
-        "GET" >>method swap (with-http-request)
+        response "location" header redirect-url
+        response code>> 307 = [ "GET" >>method ] unless
+        quot (with-http-request)
     ] [ too-many-redirects ] if ; inline recursive
 
 : read-chunk-size ( -- n )
@@ -183,7 +184,7 @@ ERROR: download-failed response ;
     present file-name "?" split1 drop "/" ?tail drop ;
 
 : download-to ( url file -- )
-    binary [ [ write ] with-http-get drop ] with-file-writer ;
+    binary [ [ write ] with-http-get check-response drop ] with-file-writer ;
 
 : download ( url -- )
     dup download-name download-to ;
index 0d4282b1d7b8efd656e4a0c0fbedccf60121140f..5c73377cbe5fb3bed094dc128c823b9f194d031b 100644 (file)
@@ -1,8 +1,8 @@
-USING: http http.server http.client http.client.private tools.test multiline
-io.streams.string io.encodings.utf8 io.encodings.8-bit
-io.encodings.binary io.encodings.string kernel arrays splitting
-sequences assocs io.sockets db db.sqlite continuations urls
-hashtables accessors namespaces xml.data ;
+USING: http http.server http.client http.client.private tools.test
+multiline io.streams.string io.encodings.utf8 io.encodings.8-bit
+io.encodings.binary io.encodings.string io.encodings.ascii kernel
+arrays splitting sequences assocs io.sockets db db.sqlite
+continuations urls hashtables accessors namespaces xml.data ;
 IN: http.tests
 
 [ "text/plain" latin1 ] [ "text/plain" parse-content-type ] unit-test
@@ -13,7 +13,7 @@ IN: http.tests
 
 [ "application/octet-stream" binary ] [ "application/octet-stream" parse-content-type ] unit-test
 
-: lf>crlf "\n" split "\r\n" join ;
+: lf>crlf ( string -- string' ) "\n" split "\r\n" join ;
 
 STRING: read-request-test-1
 POST /bar HTTP/1.1
@@ -180,14 +180,14 @@ accessors namespaces threads
 http.server.responses http.server.redirection furnace.redirection
 http.server.dispatchers db.tuples ;
 
-: add-quit-action
+: add-quit-action ( responder -- responder )
     <action>
         [ stop-this-server "Goodbye" "text/html" <content> ] >>display
     "quit" add-responder ;
 
-: test-db-file "test.db" temp-file ;
+: test-db-file ( -- path ) "test.db" temp-file ;
 
-: test-db test-db-file <sqlite-db> ;
+: test-db ( -- db ) test-db-file <sqlite-db> ;
 
 [ test-db-file delete-file ] ignore-errors
 
@@ -268,7 +268,7 @@ test-db [
     test-httpd
 ] unit-test
 
-: 404? [ download-failed? ] [ response>> code>> 404 = ] bi and ;
+: 404? ( response -- ? ) [ download-failed? ] [ response>> code>> 404 = ] bi and ;
 
 ! This should give a 404 not an infinite redirect loop
 [ "http://localhost/d/blah" add-port http-get nip ] [ 404? ] must-fail-with
@@ -359,4 +359,44 @@ SYMBOL: a
 ! Test basic auth
 [ "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" ] [ <request> "Aladdin" "open sesame" set-basic-auth "Authorization" header ] unit-test
 
+! Test a corner case with static responder
+[ ] [
+    <dispatcher>
+        add-quit-action
+        "vocab:http/test/foo.html" <static> >>default
+    test-httpd
+] unit-test
+
+[ t ] [
+    "http://localhost/" add-port http-get nip
+    "vocab:http/test/foo.html" ascii file-contents =
+] unit-test
+
+[ ] [ "http://localhost/quit" add-port http-get 2drop ] unit-test
+
+! Check behavior of 307 redirect (reported by Chris Double)
+[ ] [
+    <dispatcher>
+        add-quit-action
+        <action>
+            [ "b" <temporary-redirect> ] >>submit
+        "a" add-responder
+        <action>
+            [
+                request get post-data>> data>> "data" =
+                [ "OK" "text/plain" <content> ] [ "OOPS" throw ] if
+            ] >>submit
+        "b" add-responder
+    test-httpd
+] unit-test
+
+[ "OK" ] [ "data" "http://localhost/a" add-port http-post nip ] unit-test
+
+! Check that download throws errors (reported by Chris Double)
+[
+    "resource:temp" [
+        "http://localhost/tweet_my_twat" add-port download
+    ] with-directory
+] must-fail
 
+[ ] [ "http://localhost/quit" add-port http-get 2drop ] unit-test
index bf58f5c238dd2c36c6d175c8a13f6d3de9e349e3..2b68edfb8e3f0f6e50873e21d5bd6426c9fc0884 100755 (executable)
@@ -5,8 +5,7 @@ sequences splitting sorting sets strings vectors hashtables
 quotations arrays byte-arrays math.parser calendar
 calendar.format present urls fry
 io io.encodings io.encodings.iana io.encodings.binary
-io.encodings.8-bit io.crlf
-unicode.case unicode.categories
+io.encodings.8-bit io.crlf ascii
 http.parsers
 base64 ;
 IN: http
@@ -215,11 +214,10 @@ TUPLE: post-data data params content-type content-encoding ;
 : parse-content-type-attributes ( string -- attributes )
     " " split harvest [
         "=" split1
-        [ >lower ] [ "\"" ?head drop "\"" ?tail drop ] bi*
+        "\"" ?head drop "\"" ?tail drop
     ] { } map>assoc ;
 
 : parse-content-type ( content-type -- type encoding )
     ";" split1
-    parse-content-type-attributes "charset" swap at
-    [ name>encoding ]
-    [ dup "text/" head? latin1 binary ? ] if* ;
+    parse-content-type-attributes "charset" swap at name>encoding
+    [ dup "text/" head? latin1 binary ? ] unless* ;
index f2f3deead248e3300c5df6ccaf047e8a819f139d..8b22b9a8852e672218f748889bb1c5200b0227ff 100755 (executable)
@@ -45,10 +45,13 @@ ERROR: no-boundary ;
     ";" split1 nip
     "=" split1 nip [ no-boundary ] unless* ;
 
+SYMBOL: upload-limit
+
 : read-multipart-data ( request -- mime-parts )
     [ "content-type" header ]
     [ "content-length" header string>number ] bi
-    unlimit-input
+    unlimited-input
+    upload-limit get stream-throws limit-input
     stream-eofs limit-input
     binary decode-input
     parse-multipart-form-data parse-multipart ;
@@ -132,15 +135,15 @@ M: response write-full-response ( request response -- )
         [ content-charset>> encode-output ]
         [ write-response-body ]
         bi
-    ] unless ;
+    ] unless drop ;
 
 M: raw-response write-response ( respose -- )
     write-response-line
     write-response-body
     drop ;
 
-M: raw-response write-full-response ( response -- )
-    write-response ;
+M: raw-response write-full-response ( request response -- )
+    nip write-response ;
 
 : post-request? ( -- ? ) request get method>> "POST" = ;
 
@@ -182,7 +185,7 @@ main-responder [ <404> <trivial-responder> ] initialize
     swap development? get [ make-http-error >>body ] [ drop ] if ;
 
 : do-response ( response -- )
-    [ request get swap write-full-response ]
+    '[ request get _ write-full-response ]
     [
         [ \ do-response log-error ]
         [
@@ -252,10 +255,13 @@ LOG: httpd-benchmark DEBUG
 
 TUPLE: http-server < threaded-server ;
 
+SYMBOL: request-limit
+
+64 1024 * request-limit set-global
+
 M: http-server handle-client*
-    drop
-    [
-        64 1024 * stream-throws limit-input
+    drop [
+        request-limit get stream-throws limit-input
         ?refresh-all
         [ read-request ] ?benchmark
         [ do-request ] ?benchmark
index bbad56a6f1122033318a5fafba26054ed4df3f04..b453e7ff107087541b7ae7b60d79ef8d6ef179e6 100644 (file)
@@ -20,7 +20,7 @@ HELP: enable-fhtml
 { $side-effects "responder" } ;
 
 ARTICLE: "http.server.static.extend" "Hooks for dynamic content"
-"The static responder can be extended for dynamic content by associating quotations with MIME types in the hashtable stored in the " { $slot "special" } " slot. The quotations have stack effect " { $snippet "( path -- )" } "."
+"The static responder can be extended for dynamic content by associating quotations with MIME types in the hashtable stored in the " { $slot "special" } " slot. The quotations have stack effect " { $snippet "( path -- response )" } "."
 $nl
 "A utility word uses the above feature to enable server-side " { $snippet ".fhtml" } " scripts, allowing a development style much like PHP:"
 { $subsection enable-fhtml }
index 5d5ad7d2b83419bfe8c3ae7cf99b75ef2c8d8548..f80a3cc7cde7338549bbedbae949cf1d354ac6f1 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.\r
+! Copyright (C) 2004, 2009 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: calendar kernel math math.order math.parser namespaces\r
 parser sequences strings assocs hashtables debugger mime.types\r
@@ -42,16 +42,18 @@ TUPLE: file-responder root hook special allow-listings ;
 \r
 : serve-static ( filename mime-type -- response )\r
     over modified-since?\r
-    [ file-responder get hook>> call ] [ 2drop <304> ] if ;\r
+    [ file-responder get hook>> call( filename mime-type -- response ) ]\r
+    [ 2drop <304> ]\r
+    if ;\r
 \r
 : serving-path ( filename -- filename )\r
-    [ file-responder get root>> trim-tail-separators "/" ] dip\r
-    "" or trim-head-separators 3append ;\r
+    [ file-responder get root>> trim-tail-separators ] dip\r
+    [ "/" swap trim-head-separators 3append ] unless-empty ;\r
 \r
 : serve-file ( filename -- response )\r
     dup mime-type\r
     dup file-responder get special>> at\r
-    [ call ] [ serve-static ] ?if ;\r
+    [ call( filename -- response ) ] [ serve-static ] ?if ;\r
 \r
 \ serve-file NOTICE add-input-logging\r
 \r
index d74c69ef1bee5a28156c17db11a0a9cb5804d57b..29ba3b9b80133ddc53a7ded0456796fb8cbfad89 100644 (file)
@@ -1,24 +1,44 @@
 USING: images.bitmap images.viewer io.encodings.binary
-io.files io.files.unique kernel tools.test images.loader ;
+io.files io.files.unique kernel tools.test images.loader
+literals sequences checksums.md5 checksums
+images.normalization ;
 IN: images.bitmap.tests
 
-: test-bitmap24 ( -- path )
-    "vocab:images/test-images/thiswayup24.bmp" ;
+CONSTANT: test-bitmap24 "vocab:images/test-images/thiswayup24.bmp"
 
-: test-bitmap8 ( -- path )
-    "vocab:images/test-images/rgb8bit.bmp" ;
+CONSTANT: test-bitmap8 "vocab:images/test-images/rgb8bit.bmp"
 
-: test-bitmap4 ( -- path )
-    "vocab:images/test-images/rgb4bit.bmp" ;
+CONSTANT: test-bitmap4 "vocab:images/test-images/rgb4bit.bmp"
 
-: test-bitmap1 ( -- path )
-    "vocab:images/test-images/1bit.bmp" ;
+CONSTANT: test-bitmap1 "vocab:images/test-images/1bit.bmp"
+
+CONSTANT: test-40 "vocab:images/test-images/40red24bit.bmp"
+CONSTANT: test-41 "vocab:images/test-images/41red24bit.bmp"
+CONSTANT: test-42 "vocab:images/test-images/42red24bit.bmp"
+CONSTANT: test-43 "vocab:images/test-images/43red24bit.bmp"
+
+{
+    $ test-bitmap8
+    $ test-bitmap24
+    "vocab:ui/render/test/reference.bmp"
+} [ [ ] swap [ load-image drop ] curry unit-test ] each
 
-[ t ]
-[
-    test-bitmap24
-    [ binary file-contents ] [ load-image ] bi
 
-    "test-bitmap24" unique-file
-    [ save-bitmap ] [ binary file-contents ] bi =
+: test-bitmap-save ( path -- ? )
+    [ md5 checksum-file ]
+    [ load-image normalize-image ] bi
+    "bitmap-save-test" unique-file
+    [ save-bitmap ]
+    [ md5 checksum-file ] bi = ;
+
+[
+    t   
+] [
+    {
+        $ test-40
+        $ test-41
+        $ test-42
+        $ test-43
+        $ test-bitmap24
+    } [ test-bitmap-save ] all?
 ] unit-test
index cf16df7d82b596cfec1132caae3abd8a9e784325..48095bb26bf99800da68e7252dbd170bb4c65721 100755 (executable)
@@ -3,17 +3,26 @@
 USING: accessors alien alien.c-types arrays byte-arrays columns
 combinators fry grouping io io.binary io.encodings.binary io.files
 kernel macros math math.bitwise math.functions namespaces sequences
-strings images endian summary ;
+strings images endian summary locals ;
 IN: images.bitmap
 
-TUPLE: bitmap-image < image
-magic size reserved offset header-length width
+: assert-sequence= ( a b -- )
+    2dup sequence= [ 2drop ] [ assert ] if ;
+
+: read2 ( -- n ) 2 read le> ;
+: read4 ( -- n ) 4 read le> ;
+: write2 ( n -- ) 2 >le write ;
+: write4 ( n -- ) 4 >le write ;
+
+TUPLE: bitmap-image < image ;
+
+! Used to construct the final bitmap-image
+
+TUPLE: loading-bitmap 
+size reserved offset header-length width
 height planes bit-count compression size-image
 x-pels y-pels color-used color-important rgb-quads color-index ;
 
-! Currently can only handle 24/32bit bitmaps.
-! Handles row-reversed bitmaps (their height is negative)
-
 ERROR: bitmap-magic magic ;
 
 M: bitmap-magic summary
@@ -21,40 +30,34 @@ M: bitmap-magic summary
 
 <PRIVATE
 
-: array-copy ( bitmap array -- bitmap array' )
-    over size-image>> abs memory>byte-array ;
-
 : 8bit>buffer ( bitmap -- array )
     [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
     [ color-index>> >array ] bi [ swap nth ] with map concat ;
 
 ERROR: bmp-not-supported n ;
 
-: raw-bitmap>buffer ( bitmap -- array )
+: reverse-lines ( byte-array width -- byte-array )
+    <sliced-groups> <reversed> concat ; inline
+
+: raw-bitmap>seq ( loading-bitmap -- array )
     dup bit-count>>
     {
         { 32 [ color-index>> ] }
-        { 24 [ color-index>> ] }
-        { 16 [ bmp-not-supported ] }
-        { 8 [ 8bit>buffer ] }
-        { 4 [ bmp-not-supported ] }
-        { 2 [ bmp-not-supported ] }
-        { 1 [ bmp-not-supported ] }
+        { 24 [ [ color-index>> ] [ width>> 3 * ] bi reverse-lines ] }
+        { 8 [ [ 8bit>buffer ] [ width>> 3 * ] bi reverse-lines ] }
+        [ bmp-not-supported ]
     } case >byte-array ;
 
-: read2 ( -- n ) 2 read le> ;
-: read4 ( -- n ) 4 read le> ;
-
-: parse-file-header ( bitmap -- bitmap )
-    2 read dup "BM" sequence= [ bitmap-magic ] unless >>magic
+: parse-file-header ( loading-bitmap -- loading-bitmap )
+    2 read "BM" assert-sequence=
     read4 >>size
     read4 >>reserved
     read4 >>offset ;
 
-: parse-bitmap-header ( bitmap -- bitmap )
+: parse-bitmap-header ( loading-bitmap -- loading-bitmap )
     read4 >>header-length
     read4 >>width
-    read4 >>height
+    read4 32 >signed >>height
     read2 >>planes
     read2 >>bit-count
     read4 >>compression
@@ -64,10 +67,10 @@ ERROR: bmp-not-supported n ;
     read4 >>color-used
     read4 >>color-important ;
 
-: rgb-quads-length ( bitmap -- n )
+: rgb-quads-length ( loading-bitmap -- n )
     [ offset>> 14 - ] [ header-length>> ] bi - ;
 
-: color-index-length ( bitmap -- n )
+: color-index-length ( loading-bitmap -- n )
     {
         [ width>> ]
         [ planes>> * ]
@@ -75,21 +78,39 @@ ERROR: bmp-not-supported n ;
         [ height>> abs * ]
     } cleave ;
 
-: parse-bitmap ( bitmap -- bitmap )
+: image-size ( loading-bitmap -- n )
+    [ [ width>> ] [ height>> ] bi * ] [ bit-count>> 8 /i ] bi * abs ;
+
+: bitmap-padding ( width -- n )
+    3 * 4 mod 4 swap - 4 mod ; inline
+
+:: fixup-color-index ( loading-bitmap -- loading-bitmap )
+    loading-bitmap width>> :> width
+    width 3 * :> width*3
+    loading-bitmap width>> bitmap-padding :> padding
+    loading-bitmap [ color-index>> length ] [ height>> abs ] bi /i :> stride
+    loading-bitmap
+    padding 0 > [
+        [
+            stride <sliced-groups>
+            [ width*3 head-slice ] map concat
+        ] change-color-index
+    ] when ;
+
+: parse-bitmap ( loading-bitmap -- loading-bitmap )
     dup rgb-quads-length read >>rgb-quads
-    dup color-index-length read >>color-index ;
+    dup color-index-length read >>color-index
+    fixup-color-index ;
 
-: load-bitmap-data ( path bitmap -- bitmap )
-    [ binary ] dip '[
-        _ parse-file-header parse-bitmap-header parse-bitmap
+: load-bitmap-data ( path -- loading-bitmap )
+    binary [
+        loading-bitmap new
+        parse-file-header parse-bitmap-header parse-bitmap
     ] with-file-reader ;
 
-: process-bitmap-data ( bitmap -- bitmap )
-    dup raw-bitmap>buffer >>bitmap ;
-
 ERROR: unknown-component-order bitmap ;
 
-: bitmap>component-order ( bitmap -- object )
+: bitmap>component-order ( loading-bitmap -- object )
     bit-count>> {
         { 32 [ BGRA ] }
         { 24 [ BGR ] }
@@ -97,61 +118,78 @@ ERROR: unknown-component-order bitmap ;
         [ unknown-component-order ]
     } case ;
 
-: fill-image-slots ( bitmap -- bitmap )
-    dup {
-        [ [ width>> ] [ height>> ] bi 2array >>dim ]
+: loading-bitmap>bitmap-image ( bitmap-image loading-bitmap -- bitmap-image )
+    {
+        [ raw-bitmap>seq >>bitmap ]
+        [ [ width>> ] [ height>> abs ] bi 2array >>dim ]
+        [ height>> 0 < [ t >>upside-down? ] when ]
         [ bitmap>component-order >>component-order ]
-        [ bitmap>> >>bitmap ]
     } cleave ;
 
-M: bitmap-image load-image* ( path bitmap -- bitmap )
-    load-bitmap-data process-bitmap-data
-    fill-image-slots ;
-
-MACRO: (nbits>bitmap) ( bits -- )
-    [ -3 shift ] keep '[
-        bitmap-image new
-            2over * _ * >>size-image
-            swap >>height
-            swap >>width
-            swap array-copy [ >>bitmap ] [ >>color-index ] bi
-            _ >>bit-count fill-image-slots
-            t >>upside-down?
-    ] ;
-
-: bgr>bitmap ( array height width -- bitmap )
-    24 (nbits>bitmap) ;
-
-: bgra>bitmap ( array height width -- bitmap )
-    32 (nbits>bitmap) ;
-
-: write2 ( n -- ) 2 >le write ;
-: write4 ( n -- ) 4 >le write ;
+M: bitmap-image load-image* ( path loading-bitmap -- bitmap )
+    swap load-bitmap-data loading-bitmap>bitmap-image ;
 
 PRIVATE>
 
-: save-bitmap ( bitmap path -- )
+: bitmap>color-index ( bitmap -- byte-array )
+    [
+        bitmap>>
+        4 <sliced-groups>
+        [ 3 head-slice <reversed> ] map
+        B{ } join
+    ] [
+        dim>> first dup bitmap-padding dup 0 > [
+            [ 3 * group ] dip '[ _ <byte-array> append ] map
+            B{ } join
+        ] [
+            2drop
+        ] if
+    ] bi ;
+
+: save-bitmap ( image path -- )
     binary [
         B{ CHAR: B CHAR: M } write
         [
-            color-index>> length 14 + 40 + write4
+            bitmap>color-index length 14 + 40 + write4
             0 write4
             54 write4
             40 write4
         ] [
             {
-                [ width>> write4 ]
-                [ height>> write4 ]
-                [ planes>> 1 or write2 ]
-                [ bit-count>> 24 or write2 ]
-                [ compression>> 0 or write4 ]
-                [ size-image>> write4 ]
-                [ x-pels>> 0 or write4 ]
-                [ y-pels>> 0 or write4 ]
-                [ color-used>> 0 or write4 ]
-                [ color-important>> 0 or write4 ]
-                [ rgb-quads>> write ]
-                [ color-index>> write ]
+                ! width height
+                [ dim>> first2 [ write4 ] bi@ ]
+
+                ! planes
+                [ drop 1 write2 ]
+
+                ! bit-count
+                [ drop 24 write2 ]
+
+                ! compression
+                [ drop 0 write4 ]
+
+                ! size-image
+                [ bitmap>color-index length write4 ]
+
+                ! x-pels
+                [ drop 0 write4 ]
+
+                ! y-pels
+                [ drop 0 write4 ]
+
+                ! color-used
+                [ drop 0 write4 ]
+
+                ! color-important
+                [ drop 0 write4 ]
+
+                ! rgb-quads
+                [
+                    [ bitmap>color-index ]
+                    [ dim>> first 3 * ]
+                    [ dim>> first bitmap-padding + ] tri
+                    reverse-lines write
+                ]
             } cleave
         ] bi
     ] with-file-writer ;
old mode 100644 (file)
new mode 100755 (executable)
index cb44825..178b91a
@@ -1,16 +1,17 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors grouping sequences combinators
-math specialized-arrays.direct.uint byte-arrays fry
-specialized-arrays.direct.ushort specialized-arrays.uint
-specialized-arrays.ushort specialized-arrays.float ;
+USING: combinators kernel accessors ;
 IN: images
 
-SINGLETONS: BGR RGB BGRA RGBA ABGR ARGB RGBX XRGB BGRX XBGR
+SINGLETONS: L LA BGR RGB BGRA RGBA ABGR ARGB RGBX XRGB BGRX XBGR
 R16G16B16 R32G32B32 R16G16B16A16 R32G32B32A32 ;
 
+UNION: alpha-channel BGRA RGBA ABGR ARGB R16G16B16A16 R32G32B32A32 ;
+
 : bytes-per-pixel ( component-order -- n )
     {
+        { L [ 1 ] }
+        { LA [ 2 ] }
         { BGR [ 3 ] }
         { RGB [ 3 ] }
         { BGRA [ 4 ] }
@@ -31,67 +32,6 @@ TUPLE: image dim component-order upside-down? bitmap ;
 
 : <image> ( -- image ) image new ; inline
 
-GENERIC: load-image* ( path tuple -- image )
-
-: add-dummy-alpha ( seq -- seq' )
-    3 <groups> [ 255 suffix ] map concat ;
-
-: normalize-floats ( byte-array -- byte-array )
-    byte-array>float-array [ 255.0 * >integer ] B{ } map-as ;
-
-GENERIC: normalize-component-order* ( image component-order -- image )
-
-: normalize-component-order ( image -- image )
-    dup component-order>> '[ _ normalize-component-order* ] change-bitmap ;
-
-M: RGBA normalize-component-order* drop ;
-
-M: R32G32B32A32 normalize-component-order*
-    drop normalize-floats ;
-
-M: R32G32B32 normalize-component-order*
-    drop normalize-floats add-dummy-alpha ;
-
-: RGB16>8 ( bitmap -- bitmap' )
-    byte-array>ushort-array [ -8 shift ] B{ } map-as ; inline
-
-M: R16G16B16A16 normalize-component-order*
-    drop RGB16>8 ;
+: has-alpha? ( image -- ? ) component-order>> alpha-channel? ;
 
-M: R16G16B16 normalize-component-order*
-    drop RGB16>8 add-dummy-alpha ;
-
-: BGR>RGB ( bitmap bytes-per-pixel -- pixels )
-    <groups> [ 3 cut [ reverse ] dip append ] map B{ } join ; inline
-
-M: BGRA normalize-component-order*
-    drop 4 BGR>RGB ;
-
-M: RGB normalize-component-order*
-    drop add-dummy-alpha ;
-
-M: BGR normalize-component-order*
-    drop 3 BGR>RGB add-dummy-alpha ;
-
-: ARGB>RGBA ( bitmap -- bitmap' )
-    4 <groups> [ unclip suffix ] map B{ } join ;
-
-M: ARGB normalize-component-order*
-    drop ARGB>RGBA ;
-
-M: ABGR normalize-component-order*
-    drop ARGB>RGBA 4 BGR>RGB ;
-
-: normalize-scan-line-order ( image -- image )
-    dup upside-down?>> [
-        dup dim>> first 4 * '[
-            _ <groups> reverse concat
-        ] change-bitmap
-        f >>upside-down?
-    ] when ;
-
-: normalize-image ( image -- image )
-    [ >byte-array ] change-bitmap
-    normalize-component-order
-    normalize-scan-line-order
-    RGBA >>component-order ;
+GENERIC: load-image* ( path tuple -- image )
index 6f2ae47c61591a5b7efb0eea0d689bd2a66a402e..fe33cc8f0055490d46fb37a911c0e7cd5d91d6db 100644 (file)
@@ -1,8 +1,7 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: constructors kernel splitting unicode.case combinators
-accessors images.bitmap images.tiff images io.backend
-io.pathnames ;
+accessors images.bitmap images.tiff images io.pathnames ;
 IN: images.loader
 
 ERROR: unknown-image-extension extension ;
@@ -16,4 +15,4 @@ ERROR: unknown-image-extension extension ;
     } case ;
 
 : load-image ( path -- image )
-    dup image-class new load-image* normalize-image ;
+    dup image-class new load-image* ;
index 0965a13ad66605fecc6d1934b50c131c9125581c..b02736297773efdc9428fe46c850f1976b5ec378 100755 (executable)
@@ -2,15 +2,18 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors constructors images io io.binary io.encodings.ascii
 io.encodings.binary io.encodings.string io.files io.files.info kernel
-sequences io.streams.limited ;
+sequences io.streams.limited fry combinators arrays math
+checksums checksums.crc32 ;
 IN: images.png
 
-TUPLE: png-image < image chunks ;
+TUPLE: png-image < image chunks
+width height bit-depth color-type compression-method
+filter-method interlace-method uncompressed ;
 
 CONSTRUCTOR: png-image ( -- image )
 V{ } clone >>chunks ;
 
-TUPLE: png-chunk length type data crc ;
+TUPLE: png-chunk length type data ;
 
 CONSTRUCTOR: png-chunk ( -- png-chunk ) ;
 
@@ -23,19 +26,47 @@ ERROR: bad-png-header header ;
         bad-png-header
     ] unless drop ;
 
+ERROR: bad-checksum ;
+
 : read-png-chunks ( image -- image )
     <png-chunk>
-    4 read be> >>length
-    4 read ascii decode >>type
-    dup length>> read >>data
-    4 read >>crc
+    4 read be> [ >>length ] [ 4 + ] bi
+    read dup crc32 checksum-bytes
+    4 read = [ bad-checksum ] unless
+    4 cut-slice
+    [ ascii decode >>type ]
+    [ B{ } like >>data ] bi*
     [ over chunks>> push ] 
     [ type>> ] bi "IEND" =
     [ read-png-chunks ] unless ;
 
+: find-chunk ( image string -- chunk )
+    [ chunks>> ] dip '[ type>> _ = ] find nip ;
+
+: parse-ihdr-chunk ( image -- image )
+    dup "IHDR" find-chunk data>> {
+        [ [ 0 4 ] dip subseq be> >>width ]
+        [ [ 4 8 ] dip subseq be> >>height ]
+        [ [ 8 ] dip nth >>bit-depth ]
+        [ [ 9 ] dip nth >>color-type ]
+        [ [ 10 ] dip nth >>compression-method ]
+        [ [ 11 ] dip nth >>filter-method ]
+        [ [ 12 ] dip nth >>interlace-method ]
+    } cleave ;
+
+: find-compressed-bytes ( image -- bytes )
+    chunks>> [ type>> "IDAT" = ] filter
+    [ data>> ] map concat ;
+
+: fill-image-data ( image -- image )
+    dup [ width>> ] [ height>> ] bi 2array >>dim ;
+
 : load-png ( path -- image )
-    [ binary <file-reader> ] [ file-info size>> ] bi stream-throws <limited-stream> [
+    [ binary <file-reader> ] [ file-info size>> ] bi
+    stream-throws <limited-stream> [
         <png-image>
         read-png-header
         read-png-chunks
+        parse-ihdr-chunk
+        fill-image-data
     ] with-input-stream ;
diff --git a/basis/images/tesselation/authors.txt b/basis/images/tesselation/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/images/tesselation/tesselation-tests.factor b/basis/images/tesselation/tesselation-tests.factor
new file mode 100644 (file)
index 0000000..2ac8e37
--- /dev/null
@@ -0,0 +1,46 @@
+USING: images accessors kernel tools.test literals math.ranges
+byte-arrays ;
+IN: images.tesselation
+
+! Check an invariant we depend on
+[ t ] [
+    <image> B{ 1 2 3 } >>bitmap dup clone [ bitmap>> ] bi@ eq?
+] unit-test
+
+[
+    {
+        {
+            T{ image f { 2 2 } L f B{ 1 2 5 6 } }
+            T{ image f { 2 2 } L f B{ 3 4 7 8 } }
+        }
+        {
+            T{ image f { 2 2 } L f B{ 9 10 13 14 } }
+            T{ image f { 2 2 } L f B{ 11 12 15 16 } }
+        }
+    }
+] [
+    <image>
+        1 16 [a,b] >byte-array >>bitmap
+        { 4 4 } >>dim
+        L >>component-order
+    { 2 2 } tesselate
+] unit-test
+
+[
+    {
+        {
+            T{ image f { 2 2 } L f B{ 1 2 4 5 } }
+            T{ image f { 1 2 } L f B{ 3 6 } }
+        }
+        {
+            T{ image f { 2 1 } L f B{ 7 8 } }
+            T{ image f { 1 1 } L f B{ 9 } }
+        }
+    }
+] [
+    <image>
+        1 9 [a,b] >byte-array >>bitmap
+        { 3 3 } >>dim
+        L >>component-order
+    { 2 2 } tesselate
+] unit-test
\ No newline at end of file
diff --git a/basis/images/tesselation/tesselation.factor b/basis/images/tesselation/tesselation.factor
new file mode 100644 (file)
index 0000000..694041a
--- /dev/null
@@ -0,0 +1,35 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: sequences kernel math grouping fry columns locals accessors
+images math math.vectors arrays ;
+IN: images.tesselation
+
+: group-rows ( bitmap bitmap-dim -- rows )
+    first <sliced-groups> ; inline
+
+: tesselate-rows ( bitmap-rows tess-dim -- bitmaps )
+    second <sliced-groups> ; inline
+
+: tesselate-columns ( bitmap-rows tess-dim -- bitmaps )
+    first '[ _ <sliced-groups> ] map flip ; inline
+
+: tesselate-bitmap ( bitmap bitmap-dim tess-dim -- bitmap-grid )
+    [ group-rows ] dip
+    [ tesselate-rows ] keep
+    '[ _ tesselate-columns ] map ;
+
+: tile-width ( tile-bitmap original-image -- width )
+    [ first length ] [ component-order>> bytes-per-pixel ] bi* /i ;
+
+: <tile-image> ( tile-bitmap original-image -- tile-image )
+    clone
+        swap
+        [ concat >>bitmap ]
+        [ [ over tile-width ] [ length ] bi 2array >>dim ] bi ;
+
+:: tesselate ( image tess-dim -- image-grid )
+    image component-order>> bytes-per-pixel :> bpp
+    image dim>> { bpp 1 } v* :> image-dim'
+    tess-dim { bpp 1 } v* :> tess-dim'
+    image bitmap>> image-dim' tess-dim' tesselate-bitmap
+    [ [ image <tile-image> ] map ] map ;
\ No newline at end of file
diff --git a/basis/images/test-images/40red24bit.bmp b/basis/images/test-images/40red24bit.bmp
new file mode 100644 (file)
index 0000000..5e69455
Binary files /dev/null and b/basis/images/test-images/40red24bit.bmp differ
diff --git a/basis/images/test-images/41red24bit.bmp b/basis/images/test-images/41red24bit.bmp
new file mode 100644 (file)
index 0000000..6599dcc
Binary files /dev/null and b/basis/images/test-images/41red24bit.bmp differ
diff --git a/basis/images/test-images/42red24bit.bmp b/basis/images/test-images/42red24bit.bmp
new file mode 100644 (file)
index 0000000..e95a4f7
Binary files /dev/null and b/basis/images/test-images/42red24bit.bmp differ
diff --git a/basis/images/test-images/43red24bit.bmp b/basis/images/test-images/43red24bit.bmp
new file mode 100644 (file)
index 0000000..d88f2d4
Binary files /dev/null and b/basis/images/test-images/43red24bit.bmp differ
diff --git a/basis/images/test-images/elephants.tiff b/basis/images/test-images/elephants.tiff
new file mode 100644 (file)
index 0000000..f462a0c
Binary files /dev/null and b/basis/images/test-images/elephants.tiff differ
index 2ea1b08e208e98079455b7e3c0ccbb34b934122e..6bf1ea2ff115175c3f28b0746092399812d9d627 100755 (executable)
@@ -463,6 +463,7 @@ ERROR: unknown-component-order ifd ;
         { { 16 16 16 } [ 2 seq>native-endianness ] }
         { { 8 8 8 8 } [ ] }
         { { 8 8 8 } [ ] }
+        { 8 [ ] }
         [ unknown-component-order ]
     } case >>bitmap ;
 
@@ -474,29 +475,27 @@ ERROR: unknown-component-order ifd ;
         { { 16 16 16 } [ R16G16B16 ] }
         { { 8 8 8 8 } [ RGBA ] }
         { { 8 8 8 } [ RGB ] }
+        { 8 [ LA ] }
         [ unknown-component-order ]
     } case ;
 
+: normalize-alpha-data ( seq -- byte-array )
+    B{ } like dup
+    byte-array>float-array
+    4 <sliced-groups>
+    [
+        dup fourth dup 0 = [
+            2drop
+        ] [
+            [ 3 head-slice ] dip '[ _ / ] change-each
+        ] if
+    ] each ;
+
 : handle-alpha-data ( ifd -- ifd )
     dup extra-samples find-tag {
-        { extra-samples-associated-alpha-data [
-            [
-                B{ } like dup
-                byte-array>float-array
-                4 <sliced-groups>
-                [
-                    dup fourth dup 0 = [
-                        2drop
-                    ] [
-                        [ 3 head-slice ] dip '[ _ / ] change-each
-                    ] if
-                ] each
-            ] change-bitmap
-        ] }
-        { extra-samples-unspecified-alpha-data [
-        ] }
-        { extra-samples-unassociated-alpha-data [
-        ] }
+        { extra-samples-associated-alpha-data [ ] }
+        { extra-samples-unspecified-alpha-data [ ] }
+        { extra-samples-unassociated-alpha-data [ ] }
         [ bad-extra-samples ]
     } case ;
 
index 5c859f8947dcdca655a99bec9c4aba763b3b76c7..1de65fa91f8febc1f5002002cb8867f2dda5fd1a 100644 (file)
@@ -38,6 +38,6 @@ MACRO: interpolate ( string -- )
 : interpolate-locals ( string -- quot )
     [ search [ ] ] (interpolate) ;
 
-: I[
+SYNTAX: I[
     "]I" parse-multiline-string
-    interpolate-locals over push-all ; parsing
+    interpolate-locals over push-all ;
diff --git a/basis/interpolate/tags.txt b/basis/interpolate/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index de184585462f553fcf8ce2be277a8dcf751d3ab5..0d5e471bffd8c48620a57b9115ca1f0ebd61807e 100644 (file)
@@ -1,22 +1,32 @@
-USING: help.markup help.syntax ;\r
+! Copyright (C) 2008, 2009 Daniel Ehrenberg.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: help.markup help.syntax assocs kernel sequences ;\r
 IN: interval-maps\r
 \r
 HELP: interval-at*\r
-{ $values { "key" "an object" } { "map" "an interval map" } { "value" "the value for the key, or f" } { "?" "whether the key is present" } }\r
+{ $values { "key" object } { "map" interval-map } { "value" "the value for the key, or f" } { "?" "whether the key is present" } }\r
 { $description "Looks up a key in an interval map, returning the corresponding value if the item is in an interval in the map, and a boolean flag. The operation takes O(log n) time." } ;\r
 \r
 HELP: interval-at\r
-{ $values { "key" "an object" } { "map" "an interval map" } { "value" "the value for the key, or f" } }\r
+{ $values { "key" object } { "map" interval-map } { "value" "the value for the key, or f" } }\r
 { $description "Looks up a key in an interval map, returning the value of the corresponding interval, or f if the interval is not present in the map." } ;\r
 \r
 HELP: interval-key?\r
-{ $values { "key" "an object" } { "map" "an interval map" } { "?" "a boolean" } }\r
+{ $values { "key" object } { "map" interval-map } { "?" "a boolean" } }\r
 { $description "Tests whether an object is in an interval in the interval map, returning t if the object is present." } ;\r
 \r
 HELP: <interval-map>\r
-{ $values { "specification" "an assoc" } { "map" "an interval map" } }\r
+{ $values { "specification" assoc } { "map" interval-map } }\r
 { $description "From a specification, produce an interval tree. The specification is an assoc where the keys are intervals, or pairs of numbers to represent intervals, or individual numbers to represent singleton intervals. The values are the values int he interval map. Construction time is O(n log n)." } ;\r
 \r
+HELP: interval-values\r
+{ $values { "map" interval-map } { "values" sequence } }\r
+{ $description "Constructs a list of all of the values that interval map keys are associated with. This list may contain duplicates." } ;\r
+\r
+HELP: coalesce\r
+{ $values { "alist" "an association list with integer keys" } { "specification" { "array of the format used by " { $link <interval-map> } } } }\r
+{ $description "Finds ranges used in the given alist, coalescing them into a single range." } ;\r
+\r
 ARTICLE: "interval-maps" "Interval maps"\r
 "The " { $vocab-link "interval-maps" } " vocabulary implements a data structure, similar to assocs, where a set of closed intervals of keys are associated with values. As such, interval maps do not conform to the assoc protocol, because intervals of floats, for example, can be used, and it is impossible to get a list of keys in between."\r
 $nl\r
@@ -24,7 +34,9 @@ $nl
 { $subsection interval-at* }\r
 { $subsection interval-at }\r
 { $subsection interval-key? }\r
+{ $subsection interval-values }\r
 "Use the following to construct interval maps"\r
-{ $subsection <interval-map> } ;\r
+{ $subsection <interval-map> }\r
+{ $subsection coalesce } ;\r
 \r
 ABOUT: "interval-maps"\r
index 63a5740845ef03117df61006a834c27b2f26a40e..22283deecb5971a7c0a9caa3c2ac89c076f7def0 100644 (file)
@@ -8,17 +8,21 @@ TUPLE: interval-map array ;
 \r
 <PRIVATE\r
 \r
+ALIAS: start first\r
+ALIAS: end second\r
+ALIAS: value third\r
+\r
 : find-interval ( key interval-map -- interval-node )\r
-    [ first <=> ] with search nip ;\r
+    array>> [ start <=> ] with search nip ;\r
 \r
 : interval-contains? ( key interval-node -- ? )\r
-    first2 between? ;\r
+    [ start ] [ end ] bi between? ;\r
 \r
 : all-intervals ( sequence -- intervals )\r
     [ [ dup number? [ dup 2array ] when ] dip ] { } assoc-map-as ;\r
 \r
 : disjoint? ( node1 node2 -- ? )\r
-    [ second ] [ first ] bi* < ;\r
+    [ end ] [ start ] bi* < ;\r
 \r
 : ensure-disjoint ( intervals -- intervals )\r
     dup [ disjoint? ] monotonic?\r
@@ -30,14 +34,17 @@ TUPLE: interval-map array ;
 PRIVATE>\r
 \r
 : interval-at* ( key map -- value ? )\r
-    [ drop ] [ array>> find-interval ] 2bi\r
+    [ drop ] [ find-interval ] 2bi\r
     [ nip ] [ interval-contains? ] 2bi\r
-    [ third t ] [ drop f f ] if ;\r
+    [ value t ] [ drop f f ] if ;\r
 \r
 : interval-at ( key map -- value ) interval-at* drop ;\r
 \r
 : interval-key? ( key map -- ? ) interval-at* nip ;\r
 \r
+: interval-values ( map -- values )\r
+    array>> [ value ] map ;\r
+\r
 : <interval-map> ( specification -- map )\r
     all-intervals [ [ first second ] compare ] sort\r
     >intervals ensure-disjoint interval-map boa ;\r
index 1006e45e77c57ee3fa0d473707e3c5f232cf5b48..3a86703cafb1a49ffc12c2bb8ad09b66e17449b5 100755 (executable)
@@ -122,7 +122,7 @@ M: math-inverse inverse
 
 M: pop-inverse inverse
     [ "pop-length" word-prop cut-slice swap >quotation ]
-    [ "pop-inverse" word-prop ] bi compose call ;
+    [ "pop-inverse" word-prop ] bi compose call( -- quot ) ;
 
 : (undo) ( revquot -- )
     [ unclip-slice inverse % (undo) ] unless-empty ;
index 2e94d7a2df0fea1e76333bde26c29273f132f58e..ed054d79582010892db2e842375bd57a01cb4f95 100644 (file)
@@ -5,7 +5,7 @@ io.streams.duplex destructors make io.launcher ;
 IN: io.backend.unix.tests
 
 ! Unix domain stream sockets
-: socket-server "unix-domain-socket-test" temp-file ;
+: socket-server ( -- path ) "unix-domain-socket-test" temp-file ;
 
 [
     [ socket-server delete-file ] ignore-errors
@@ -33,8 +33,8 @@ yield
     ] { } make
 ] unit-test
 
-: datagram-server "unix-domain-datagram-test" temp-file ;
-: datagram-client "unix-domain-datagram-test-2" temp-file ;
+: datagram-server ( -- path ) "unix-domain-datagram-test" temp-file ;
+: datagram-client ( -- path ) "unix-domain-datagram-test-2" temp-file ;
 
 ! Unix domain datagram sockets
 [ datagram-server delete-file ] ignore-errors
@@ -104,7 +104,7 @@ datagram-client <local> <datagram>
 [ ] [ "d" get dispose ] unit-test
 
 ! Test error behavior
-: another-datagram "unix-domain-datagram-test-3" temp-file ;
+: another-datagram ( -- path ) "unix-domain-datagram-test-3" temp-file ;
 
 [ another-datagram delete-file ] ignore-errors
 
index ba1b9cdbe11c1c0bf21d76d26bc529d0eee52b5d..5281ca9c2b4440d500c0f56d62262c0ae1e4e449 100644 (file)
@@ -8,3 +8,13 @@ IN: io.directories.search.tests
         current-temporary-directory get [ ] find-all-files
     ] with-unique-directory drop [ natural-sort ] bi@ =
 ] unit-test
+
+[ f ] [
+    { "omg you shoudnt have a directory called this" "or this" }
+    t
+    [ "asdfasdfasdfasdfasdf" tail? ] find-in-directories
+] unit-test
+
+[ f ] [
+    { } t [ "asdfasdfasdfasdfasdf" tail? ] find-in-directories
+] unit-test
index ee8fd129a7313239ce0982d62a89777037b5d6d4..6db83ebca6b43e5f4a23768d95426a6f8635d144 100755 (executable)
@@ -61,13 +61,13 @@ PRIVATE>
 ERROR: file-not-found ;
 
 : find-in-directories ( directories bfs? quot: ( obj -- ? ) -- path'/f )
-    [
-        '[ _ _ find-file [ file-not-found ] unless* ] attempt-all
+    '[
+        [ _ _ find-file [ file-not-found ] unless* ] attempt-all
     ] [
         drop f
-    ] recover ;
+    ] recover ; inline
 
 : find-all-in-directories ( directories bfs? quot: ( obj -- ? ) -- paths/f )
-    '[ _ _ find-all-files ] map concat ;
+    '[ _ _ find-all-files ] map concat ; inline
 
 os windows? [ "io.directories.search.windows" require ] when
index deb1a7121f024d467eea01336474daf1492c769f..1654cb8b833a17d39a9c206c0df59ba9f35fccb0 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io io.encodings kernel math io.encodings.private io.encodings.iana ;
+USING: io io.encodings kernel math io.encodings.private ;
 IN: io.encodings.ascii
 
 <PRIVATE
@@ -19,6 +19,4 @@ M: ascii encode-char
     128 encode-if< ;
 
 M: ascii decode-char
-    128 decode-if< ;
-
-ascii "ANSI_X3.4-1968" register-encoding
+    128 decode-if< ;
\ No newline at end of file
index e20580876e27578e027dd53b240a586d45bb8ff8..bf882fcfd02ac4def4eaa47bff8cb91677bcd6d4 100644 (file)
@@ -63,6 +63,6 @@ SYMBOL: euc-table
 
 PRIVATE>
 
-: EUC:
+SYNTAX: EUC:
     ! EUC: euc-kr "vocab:io/encodings/korean/cp949.txt"
-    CREATE-CLASS scan-object define-euc ; parsing
+    CREATE-CLASS scan-object define-euc ;
index c565d79ef5d58294780b4a48c72ee8d3ccf66d2e..628bceac6290e445b840a0c42748e07d7c641f67 100644 (file)
@@ -9,24 +9,15 @@ ARTICLE: "io.encodings.iana" "IANA-registered encoding names"
 { $subsection name>encoding }
 { $subsection encoding>name }
 "To let a new encoding be used with the above words, use the following:"
-{ $subsection register-encoding }
-"Exceptions when encodings or names are not found:"
-{ $subsection missing-encoding }
-{ $subsection missing-name } ;
-
-HELP: missing-encoding
-{ $error-description "The error called from " { $link name>encoding } " when there is no encoding descriptor registered corresponding to the given name." } ;
-
-HELP: missing-name
-{ $error-description "The error called from " { $link encoding>name } " when there is no name registered corresponding to the given encoding." } ;
+{ $subsection register-encoding } ;
 
 HELP: name>encoding
 { $values { "name" "an encoding name" } { "encoding" "an encoding descriptor" } }
-{ $description "Given an IANA-registered encoding name, find the encoding descriptor that represents it, or " { $code f } " if it is not found (either not implemented in Factor or not registered)." } ;
+{ $description "Given an IANA-registered encoding name, find the encoding descriptor that represents it, or " { $snippet "f" } " if it is not found (either not implemented in Factor or not registered)." } ;
 
 HELP: encoding>name
 { $values { "encoding" "an encoding descriptor" } { "name" "an encoding name" } }
-{ $description "Given an encoding descriptor, return the preferred IANA name." } ;
+{ $description "Given an encoding descriptor, return the preferred IANA name. If no name is found, returns " { $snippet "f" } "." } ;
 
 { name>encoding encoding>name } related-words
 
index 3175e624cea2f95d7e5686a0d7191f0d1dae1ea9..67b849b2b24a3b4f9dadc67a23b9b3f86f10db2d 100644 (file)
@@ -19,10 +19,10 @@ ebcdic-fisea "EBCDIC-FI-SE-A" register-encoding
     "csEBCDICFISEA" n>e-table get delete-at
     ebcdic-fisea e>n-table get delete-at
 ] unit-test
-[ "EBCDIC-FI-SE-A" name>encoding ] must-fail
-[ "csEBCDICFISEA" name>encoding ] must-fail
-[ ebcdic-fisea encoding>name ] must-fail
+[ f ] [ "EBCDIC-FI-SE-A" name>encoding ] unit-test
+[ f ] [ "csEBCDICFISEA" name>encoding ] unit-test
+[ f ] [ ebcdic-fisea encoding>name ] unit-test
 
 [ ebcdic-fisea "foobar" register-encoding ] must-fail
-[ "foobar" name>encoding ] must-fail
-[ ebcdic-fisea encoding>name ] must-fail
+[ f ] [ "foobar" name>encoding ] unit-test
+[ f ] [ ebcdic-fisea encoding>name ] unit-test
index a8555ac3393bc74d70d633eed2765e04d69e263a..899bedfbc63c162cb3dcb361d2f783b81c2ea8bb 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel strings values io.files assocs
-splitting sequences io namespaces sets io.encodings.utf8 ;
+splitting sequences io namespaces sets
+io.encodings.ascii io.encodings.utf8 ;
 IN: io.encodings.iana
 
 <PRIVATE
@@ -10,15 +11,11 @@ SYMBOL: e>n-table
 SYMBOL: aliases
 PRIVATE>
 
-ERROR: missing-encoding name ;
-
 : name>encoding ( name -- encoding )
-    dup n>e-table get-global at [ ] [ missing-encoding ] ?if ;
-
-ERROR: missing-name encoding ;
+    n>e-table get-global at ;
 
 : encoding>name ( encoding -- name )
-    dup e>n-table get-global at [ ] [ missing-name ] ?if ;
+    e>n-table get-global at ;
 
 <PRIVATE
 : parse-iana ( file -- synonym-set )
@@ -56,3 +53,5 @@ e>n-table [ initial-e>n ] initialize
             [ n>e-table get-global set-at ] with each
         ] [ "Bad encoding registration" throw ] if*
     ] [ swap e>n-table get-global set-at ] 2bi ;
+
+ascii "ANSI_X3.4-1968" register-encoding
diff --git a/basis/io/encodings/iso2022/201.txt b/basis/io/encodings/iso2022/201.txt
new file mode 100644 (file)
index 0000000..5525a68
--- /dev/null
@@ -0,0 +1,208 @@
+#
+#      Name:             JIS X 0201 (1976) to Unicode 1.1 Table
+#      Unicode version:  1.1
+#      Table version:    0.9
+#      Table format:     Format A
+#      Date:             8 March 1994
+#
+#      Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#      This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#      No claims are made as to fitness for any particular purpose.  No
+#      warranties of any kind are expressed or implied.  The recipient
+#      agrees to determine applicability of information provided.  If this
+#      file has been provided on magnetic media by Unicode, Inc., the sole
+#      remedy for any claim will be exchange of defective media within 90
+#      days of receipt.
+#
+#      Recipient is granted the right to make copies in any form for
+#      internal distribution and to freely use the information supplied
+#      in the creation of products supporting Unicode.  Unicode, Inc.
+#      specifically excludes the right to re-distribute this file directly
+#      to third parties or other organizations whether for profit or not.
+#
+#      General notes:
+#
+#
+# This table contains one set of mappings from JIS X 0201 into Unicode.
+# Note that these data are *possible* mappings only and may not be the
+# same as those used by actual products, nor may they be the best suited
+# for all uses.  For more information on the mappings between various code
+# pages incorporating the repertoire of JIS X 0201 and Unicode, consult the
+# VENDORS mapping data.  Normative information on the mapping between
+# JIS X 0201 and Unicode may be found in the Unihan.txt file in the
+# latest Unicode Character Database.
+#
+# If you have carefully considered the fact that the mappings in
+# this table are only one possible set of mappings between JIS X 0201 and
+# Unicode and have no normative status, but still feel that you
+# have located an error in the table that requires fixing, you may
+# report any such error to errata@unicode.org.
+#
+#
+#      Format:  Three tab-separated columns
+#              Column #1 is the shift JIS code (in hex as 0xXX)
+#              Column #2 is the Unicode (in hex as 0xXXXX)
+#              Column #3 the Unicode (ISO 10646) name (follows a comment sign)
+#
+#      The entries are in JIS order
+#
+#
+0x20   0x0020  # SPACE
+0x21   0x0021  # EXCLAMATION MARK
+0x22   0x0022  # QUOTATION MARK
+0x23   0x0023  # NUMBER SIGN
+0x24   0x0024  # DOLLAR SIGN
+0x25   0x0025  # PERCENT SIGN
+0x26   0x0026  # AMPERSAND
+0x27   0x0027  # APOSTROPHE
+0x28   0x0028  # LEFT PARENTHESIS
+0x29   0x0029  # RIGHT PARENTHESIS
+0x2A   0x002A  # ASTERISK
+0x2B   0x002B  # PLUS SIGN
+0x2C   0x002C  # COMMA
+0x2D   0x002D  # HYPHEN-MINUS
+0x2E   0x002E  # FULL STOP
+0x2F   0x002F  # SOLIDUS
+0x30   0x0030  # DIGIT ZERO
+0x31   0x0031  # DIGIT ONE
+0x32   0x0032  # DIGIT TWO
+0x33   0x0033  # DIGIT THREE
+0x34   0x0034  # DIGIT FOUR
+0x35   0x0035  # DIGIT FIVE
+0x36   0x0036  # DIGIT SIX
+0x37   0x0037  # DIGIT SEVEN
+0x38   0x0038  # DIGIT EIGHT
+0x39   0x0039  # DIGIT NINE
+0x3A   0x003A  # COLON
+0x3B   0x003B  # SEMICOLON
+0x3C   0x003C  # LESS-THAN SIGN
+0x3D   0x003D  # EQUALS SIGN
+0x3E   0x003E  # GREATER-THAN SIGN
+0x3F   0x003F  # QUESTION MARK
+0x40   0x0040  # COMMERCIAL AT
+0x41   0x0041  # LATIN CAPITAL LETTER A
+0x42   0x0042  # LATIN CAPITAL LETTER B
+0x43   0x0043  # LATIN CAPITAL LETTER C
+0x44   0x0044  # LATIN CAPITAL LETTER D
+0x45   0x0045  # LATIN CAPITAL LETTER E
+0x46   0x0046  # LATIN CAPITAL LETTER F
+0x47   0x0047  # LATIN CAPITAL LETTER G
+0x48   0x0048  # LATIN CAPITAL LETTER H
+0x49   0x0049  # LATIN CAPITAL LETTER I
+0x4A   0x004A  # LATIN CAPITAL LETTER J
+0x4B   0x004B  # LATIN CAPITAL LETTER K
+0x4C   0x004C  # LATIN CAPITAL LETTER L
+0x4D   0x004D  # LATIN CAPITAL LETTER M
+0x4E   0x004E  # LATIN CAPITAL LETTER N
+0x4F   0x004F  # LATIN CAPITAL LETTER O
+0x50   0x0050  # LATIN CAPITAL LETTER P
+0x51   0x0051  # LATIN CAPITAL LETTER Q
+0x52   0x0052  # LATIN CAPITAL LETTER R
+0x53   0x0053  # LATIN CAPITAL LETTER S
+0x54   0x0054  # LATIN CAPITAL LETTER T
+0x55   0x0055  # LATIN CAPITAL LETTER U
+0x56   0x0056  # LATIN CAPITAL LETTER V
+0x57   0x0057  # LATIN CAPITAL LETTER W
+0x58   0x0058  # LATIN CAPITAL LETTER X
+0x59   0x0059  # LATIN CAPITAL LETTER Y
+0x5A   0x005A  # LATIN CAPITAL LETTER Z
+0x5B   0x005B  # LEFT SQUARE BRACKET
+0x5C   0x00A5  # YEN SIGN
+0x5D   0x005D  # RIGHT SQUARE BRACKET
+0x5E   0x005E  # CIRCUMFLEX ACCENT
+0x5F   0x005F  # LOW LINE
+0x60   0x0060  # GRAVE ACCENT
+0x61   0x0061  # LATIN SMALL LETTER A
+0x62   0x0062  # LATIN SMALL LETTER B
+0x63   0x0063  # LATIN SMALL LETTER C
+0x64   0x0064  # LATIN SMALL LETTER D
+0x65   0x0065  # LATIN SMALL LETTER E
+0x66   0x0066  # LATIN SMALL LETTER F
+0x67   0x0067  # LATIN SMALL LETTER G
+0x68   0x0068  # LATIN SMALL LETTER H
+0x69   0x0069  # LATIN SMALL LETTER I
+0x6A   0x006A  # LATIN SMALL LETTER J
+0x6B   0x006B  # LATIN SMALL LETTER K
+0x6C   0x006C  # LATIN SMALL LETTER L
+0x6D   0x006D  # LATIN SMALL LETTER M
+0x6E   0x006E  # LATIN SMALL LETTER N
+0x6F   0x006F  # LATIN SMALL LETTER O
+0x70   0x0070  # LATIN SMALL LETTER P
+0x71   0x0071  # LATIN SMALL LETTER Q
+0x72   0x0072  # LATIN SMALL LETTER R
+0x73   0x0073  # LATIN SMALL LETTER S
+0x74   0x0074  # LATIN SMALL LETTER T
+0x75   0x0075  # LATIN SMALL LETTER U
+0x76   0x0076  # LATIN SMALL LETTER V
+0x77   0x0077  # LATIN SMALL LETTER W
+0x78   0x0078  # LATIN SMALL LETTER X
+0x79   0x0079  # LATIN SMALL LETTER Y
+0x7A   0x007A  # LATIN SMALL LETTER Z
+0x7B   0x007B  # LEFT CURLY BRACKET
+0x7C   0x007C  # VERTICAL LINE
+0x7D   0x007D  # RIGHT CURLY BRACKET
+0x7E   0x203E  # OVERLINE
+0xA1   0xFF61  # HALFWIDTH IDEOGRAPHIC FULL STOP
+0xA2   0xFF62  # HALFWIDTH LEFT CORNER BRACKET
+0xA3   0xFF63  # HALFWIDTH RIGHT CORNER BRACKET
+0xA4   0xFF64  # HALFWIDTH IDEOGRAPHIC COMMA
+0xA5   0xFF65  # HALFWIDTH KATAKANA MIDDLE DOT
+0xA6   0xFF66  # HALFWIDTH KATAKANA LETTER WO
+0xA7   0xFF67  # HALFWIDTH KATAKANA LETTER SMALL A
+0xA8   0xFF68  # HALFWIDTH KATAKANA LETTER SMALL I
+0xA9   0xFF69  # HALFWIDTH KATAKANA LETTER SMALL U
+0xAA   0xFF6A  # HALFWIDTH KATAKANA LETTER SMALL E
+0xAB   0xFF6B  # HALFWIDTH KATAKANA LETTER SMALL O
+0xAC   0xFF6C  # HALFWIDTH KATAKANA LETTER SMALL YA
+0xAD   0xFF6D  # HALFWIDTH KATAKANA LETTER SMALL YU
+0xAE   0xFF6E  # HALFWIDTH KATAKANA LETTER SMALL YO
+0xAF   0xFF6F  # HALFWIDTH KATAKANA LETTER SMALL TU
+0xB0   0xFF70  # HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xB1   0xFF71  # HALFWIDTH KATAKANA LETTER A
+0xB2   0xFF72  # HALFWIDTH KATAKANA LETTER I
+0xB3   0xFF73  # HALFWIDTH KATAKANA LETTER U
+0xB4   0xFF74  # HALFWIDTH KATAKANA LETTER E
+0xB5   0xFF75  # HALFWIDTH KATAKANA LETTER O
+0xB6   0xFF76  # HALFWIDTH KATAKANA LETTER KA
+0xB7   0xFF77  # HALFWIDTH KATAKANA LETTER KI
+0xB8   0xFF78  # HALFWIDTH KATAKANA LETTER KU
+0xB9   0xFF79  # HALFWIDTH KATAKANA LETTER KE
+0xBA   0xFF7A  # HALFWIDTH KATAKANA LETTER KO
+0xBB   0xFF7B  # HALFWIDTH KATAKANA LETTER SA
+0xBC   0xFF7C  # HALFWIDTH KATAKANA LETTER SI
+0xBD   0xFF7D  # HALFWIDTH KATAKANA LETTER SU
+0xBE   0xFF7E  # HALFWIDTH KATAKANA LETTER SE
+0xBF   0xFF7F  # HALFWIDTH KATAKANA LETTER SO
+0xC0   0xFF80  # HALFWIDTH KATAKANA LETTER TA
+0xC1   0xFF81  # HALFWIDTH KATAKANA LETTER TI
+0xC2   0xFF82  # HALFWIDTH KATAKANA LETTER TU
+0xC3   0xFF83  # HALFWIDTH KATAKANA LETTER TE
+0xC4   0xFF84  # HALFWIDTH KATAKANA LETTER TO
+0xC5   0xFF85  # HALFWIDTH KATAKANA LETTER NA
+0xC6   0xFF86  # HALFWIDTH KATAKANA LETTER NI
+0xC7   0xFF87  # HALFWIDTH KATAKANA LETTER NU
+0xC8   0xFF88  # HALFWIDTH KATAKANA LETTER NE
+0xC9   0xFF89  # HALFWIDTH KATAKANA LETTER NO
+0xCA   0xFF8A  # HALFWIDTH KATAKANA LETTER HA
+0xCB   0xFF8B  # HALFWIDTH KATAKANA LETTER HI
+0xCC   0xFF8C  # HALFWIDTH KATAKANA LETTER HU
+0xCD   0xFF8D  # HALFWIDTH KATAKANA LETTER HE
+0xCE   0xFF8E  # HALFWIDTH KATAKANA LETTER HO
+0xCF   0xFF8F  # HALFWIDTH KATAKANA LETTER MA
+0xD0   0xFF90  # HALFWIDTH KATAKANA LETTER MI
+0xD1   0xFF91  # HALFWIDTH KATAKANA LETTER MU
+0xD2   0xFF92  # HALFWIDTH KATAKANA LETTER ME
+0xD3   0xFF93  # HALFWIDTH KATAKANA LETTER MO
+0xD4   0xFF94  # HALFWIDTH KATAKANA LETTER YA
+0xD5   0xFF95  # HALFWIDTH KATAKANA LETTER YU
+0xD6   0xFF96  # HALFWIDTH KATAKANA LETTER YO
+0xD7   0xFF97  # HALFWIDTH KATAKANA LETTER RA
+0xD8   0xFF98  # HALFWIDTH KATAKANA LETTER RI
+0xD9   0xFF99  # HALFWIDTH KATAKANA LETTER RU
+0xDA   0xFF9A  # HALFWIDTH KATAKANA LETTER RE
+0xDB   0xFF9B  # HALFWIDTH KATAKANA LETTER RO
+0xDC   0xFF9C  # HALFWIDTH KATAKANA LETTER WA
+0xDD   0xFF9D  # HALFWIDTH KATAKANA LETTER N
+0xDE   0xFF9E  # HALFWIDTH KATAKANA VOICED SOUND MARK
+0xDF   0xFF9F  # HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
diff --git a/basis/io/encodings/iso2022/208.txt b/basis/io/encodings/iso2022/208.txt
new file mode 100644 (file)
index 0000000..61e780f
--- /dev/null
@@ -0,0 +1,6953 @@
+#
+#      Name:             JIS X 0208 (1990) to Unicode
+#      Unicode version:  1.1
+#      Table version:    0.9
+#      Table format:     Format A
+#      Date:             8 March 1994
+#
+#      Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#      This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#      No claims are made as to fitness for any particular purpose.  No
+#      warranties of any kind are expressed or implied.  The recipient
+#      agrees to determine applicability of information provided.  If this
+#      file has been provided on magnetic media by Unicode, Inc., the sole
+#      remedy for any claim will be exchange of defective media within 90
+#      days of receipt.
+#
+#      Recipient is granted the right to make copies in any form for
+#      internal distribution and to freely use the information supplied
+#      in the creation of products supporting Unicode.  Unicode, Inc.
+#      specifically excludes the right to re-distribute this file directly
+#      to third parties or other organizations whether for profit or not.
+#
+#      General notes:
+#
+#
+# This table contains one set of mappings from JIS X 0208 (1990) into Unicode.
+# Note that these data are *possible* mappings only and may not be the
+# same as those used by actual products, nor may they be the best suited
+# for all uses.  For more information on the mappings between various code
+# pages incorporating the repertoire of JIS X 0208 (1990) and Unicode, consult the
+# VENDORS mapping data.  Normative information on the mapping between
+# JIS X 0208 (1990) and Unicode may be found in the Unihan.txt file in the
+# latest Unicode Character Database.
+#
+# If you have carefully considered the fact that the mappings in
+# this table are only one possible set of mappings between JIS X 0208 (1990)
+# and Unicode and have no normative status, but still feel that you
+# have located an error in the table that requires fixing, you may
+# report any such error to errata@unicode.org.
+#
+#
+#      Format:  Four tab-separated columns
+#               Column #1 is the shift-JIS code (in hex)
+#                  --> OMITTED!
+#               Column #2 is the JIS X 0208 code (in hex as 0xXXXX)
+#               Column #3 is the Unicode (in hex as 0xXXXX)
+#               Column #4 the Unicode name (follows a comment sign, '#')
+#                      The official names for Unicode characters U+4E00
+#                      to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#                      where XXXX is the code point.  Including all these
+#                      names in this file increases its size substantially
+#                      and needlessly.  The token "<CJK>" is used for the
+#                      name of these characters.  If necessary, it can be
+#                      expanded algorithmically by a parser or editor.
+#
+#      The entries are in JIS X 0208 order
+#
+#      The following algorithms can be used to change the hex form
+#              of JIS 0208 to other standard forms:
+#
+#              To change hex to EUC form, add 0x8080
+#              To change hex to kuten form, first subtract 0x2020.  Then
+#                      the high and low bytes correspond to the ku and ten of
+#                      the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
+#                      0x7426 -> 0x5406 -> 8406
+#
+#   The kanji mappings are a normative part of ISO/IEC 10646.  The
+#       non-kanji mappings are provisional, pending definition of
+#       official mappings by Japanese standards bodies
+#
+#      Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#
+0x2121 0x3000  # IDEOGRAPHIC SPACE
+0x2122 0x3001  # IDEOGRAPHIC COMMA
+0x2123 0x3002  # IDEOGRAPHIC FULL STOP
+0x2124 0xFF0C  # FULLWIDTH COMMA
+0x2125 0xFF0E  # FULLWIDTH FULL STOP
+0x2126 0x30FB  # KATAKANA MIDDLE DOT
+0x2127 0xFF1A  # FULLWIDTH COLON
+0x2128 0xFF1B  # FULLWIDTH SEMICOLON
+0x2129 0xFF1F  # FULLWIDTH QUESTION MARK
+0x212A 0xFF01  # FULLWIDTH EXCLAMATION MARK
+0x212B 0x309B  # KATAKANA-HIRAGANA VOICED SOUND MARK
+0x212C 0x309C  # KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+0x212D 0x00B4  # ACUTE ACCENT
+0x212E 0xFF40  # FULLWIDTH GRAVE ACCENT
+0x212F 0x00A8  # DIAERESIS
+0x2130 0xFF3E  # FULLWIDTH CIRCUMFLEX ACCENT
+0x2131 0xFFE3  # FULLWIDTH MACRON
+0x2132 0xFF3F  # FULLWIDTH LOW LINE
+0x2133 0x30FD  # KATAKANA ITERATION MARK
+0x2134 0x30FE  # KATAKANA VOICED ITERATION MARK
+0x2135 0x309D  # HIRAGANA ITERATION MARK
+0x2136 0x309E  # HIRAGANA VOICED ITERATION MARK
+0x2137 0x3003  # DITTO MARK
+0x2138 0x4EDD  # <CJK>
+0x2139 0x3005  # IDEOGRAPHIC ITERATION MARK
+0x213A 0x3006  # IDEOGRAPHIC CLOSING MARK
+0x213B 0x3007  # IDEOGRAPHIC NUMBER ZERO
+0x213C 0x30FC  # KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0x213D 0x2015  # HORIZONTAL BAR
+0x213E 0x2010  # HYPHEN
+0x213F 0xFF0F  # FULLWIDTH SOLIDUS
+0x2140 0x005C  # REVERSE SOLIDUS
+0x2141 0x301C  # WAVE DASH
+0x2142 0x2016  # DOUBLE VERTICAL LINE
+0x2143 0xFF5C  # FULLWIDTH VERTICAL LINE
+0x2144 0x2026  # HORIZONTAL ELLIPSIS
+0x2145 0x2025  # TWO DOT LEADER
+0x2146 0x2018  # LEFT SINGLE QUOTATION MARK
+0x2147 0x2019  # RIGHT SINGLE QUOTATION MARK
+0x2148 0x201C  # LEFT DOUBLE QUOTATION MARK
+0x2149 0x201D  # RIGHT DOUBLE QUOTATION MARK
+0x214A 0xFF08  # FULLWIDTH LEFT PARENTHESIS
+0x214B 0xFF09  # FULLWIDTH RIGHT PARENTHESIS
+0x214C 0x3014  # LEFT TORTOISE SHELL BRACKET
+0x214D 0x3015  # RIGHT TORTOISE SHELL BRACKET
+0x214E 0xFF3B  # FULLWIDTH LEFT SQUARE BRACKET
+0x214F 0xFF3D  # FULLWIDTH RIGHT SQUARE BRACKET
+0x2150 0xFF5B  # FULLWIDTH LEFT CURLY BRACKET
+0x2151 0xFF5D  # FULLWIDTH RIGHT CURLY BRACKET
+0x2152 0x3008  # LEFT ANGLE BRACKET
+0x2153 0x3009  # RIGHT ANGLE BRACKET
+0x2154 0x300A  # LEFT DOUBLE ANGLE BRACKET
+0x2155 0x300B  # RIGHT DOUBLE ANGLE BRACKET
+0x2156 0x300C  # LEFT CORNER BRACKET
+0x2157 0x300D  # RIGHT CORNER BRACKET
+0x2158 0x300E  # LEFT WHITE CORNER BRACKET
+0x2159 0x300F  # RIGHT WHITE CORNER BRACKET
+0x215A 0x3010  # LEFT BLACK LENTICULAR BRACKET
+0x215B 0x3011  # RIGHT BLACK LENTICULAR BRACKET
+0x215C 0xFF0B  # FULLWIDTH PLUS SIGN
+0x215D 0x2212  # MINUS SIGN
+0x215E 0x00B1  # PLUS-MINUS SIGN
+0x215F 0x00D7  # MULTIPLICATION SIGN
+0x2160 0x00F7  # DIVISION SIGN
+0x2161 0xFF1D  # FULLWIDTH EQUALS SIGN
+0x2162 0x2260  # NOT EQUAL TO
+0x2163 0xFF1C  # FULLWIDTH LESS-THAN SIGN
+0x2164 0xFF1E  # FULLWIDTH GREATER-THAN SIGN
+0x2165 0x2266  # LESS-THAN OVER EQUAL TO
+0x2166 0x2267  # GREATER-THAN OVER EQUAL TO
+0x2167 0x221E  # INFINITY
+0x2168 0x2234  # THEREFORE
+0x2169 0x2642  # MALE SIGN
+0x216A 0x2640  # FEMALE SIGN
+0x216B 0x00B0  # DEGREE SIGN
+0x216C 0x2032  # PRIME
+0x216D 0x2033  # DOUBLE PRIME
+0x216E 0x2103  # DEGREE CELSIUS
+0x216F 0xFFE5  # FULLWIDTH YEN SIGN
+0x2170 0xFF04  # FULLWIDTH DOLLAR SIGN
+0x2171 0x00A2  # CENT SIGN
+0x2172 0x00A3  # POUND SIGN
+0x2173 0xFF05  # FULLWIDTH PERCENT SIGN
+0x2174 0xFF03  # FULLWIDTH NUMBER SIGN
+0x2175 0xFF06  # FULLWIDTH AMPERSAND
+0x2176 0xFF0A  # FULLWIDTH ASTERISK
+0x2177 0xFF20  # FULLWIDTH COMMERCIAL AT
+0x2178 0x00A7  # SECTION SIGN
+0x2179 0x2606  # WHITE STAR
+0x217A 0x2605  # BLACK STAR
+0x217B 0x25CB  # WHITE CIRCLE
+0x217C 0x25CF  # BLACK CIRCLE
+0x217D 0x25CE  # BULLSEYE
+0x217E 0x25C7  # WHITE DIAMOND
+0x2221 0x25C6  # BLACK DIAMOND
+0x2222 0x25A1  # WHITE SQUARE
+0x2223 0x25A0  # BLACK SQUARE
+0x2224 0x25B3  # WHITE UP-POINTING TRIANGLE
+0x2225 0x25B2  # BLACK UP-POINTING TRIANGLE
+0x2226 0x25BD  # WHITE DOWN-POINTING TRIANGLE
+0x2227 0x25BC  # BLACK DOWN-POINTING TRIANGLE
+0x2228 0x203B  # REFERENCE MARK
+0x2229 0x3012  # POSTAL MARK
+0x222A 0x2192  # RIGHTWARDS ARROW
+0x222B 0x2190  # LEFTWARDS ARROW
+0x222C 0x2191  # UPWARDS ARROW
+0x222D 0x2193  # DOWNWARDS ARROW
+0x222E 0x3013  # GETA MARK
+0x223A 0x2208  # ELEMENT OF
+0x223B 0x220B  # CONTAINS AS MEMBER
+0x223C 0x2286  # SUBSET OF OR EQUAL TO
+0x223D 0x2287  # SUPERSET OF OR EQUAL TO
+0x223E 0x2282  # SUBSET OF
+0x223F 0x2283  # SUPERSET OF
+0x2240 0x222A  # UNION
+0x2241 0x2229  # INTERSECTION
+0x224A 0x2227  # LOGICAL AND
+0x224B 0x2228  # LOGICAL OR
+0x224C 0x00AC  # NOT SIGN
+0x224D 0x21D2  # RIGHTWARDS DOUBLE ARROW
+0x224E 0x21D4  # LEFT RIGHT DOUBLE ARROW
+0x224F 0x2200  # FOR ALL
+0x2250 0x2203  # THERE EXISTS
+0x225C 0x2220  # ANGLE
+0x225D 0x22A5  # UP TACK
+0x225E 0x2312  # ARC
+0x225F 0x2202  # PARTIAL DIFFERENTIAL
+0x2260 0x2207  # NABLA
+0x2261 0x2261  # IDENTICAL TO
+0x2262 0x2252  # APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0x2263 0x226A  # MUCH LESS-THAN
+0x2264 0x226B  # MUCH GREATER-THAN
+0x2265 0x221A  # SQUARE ROOT
+0x2266 0x223D  # REVERSED TILDE
+0x2267 0x221D  # PROPORTIONAL TO
+0x2268 0x2235  # BECAUSE
+0x2269 0x222B  # INTEGRAL
+0x226A 0x222C  # DOUBLE INTEGRAL
+0x2272 0x212B  # ANGSTROM SIGN
+0x2273 0x2030  # PER MILLE SIGN
+0x2274 0x266F  # MUSIC SHARP SIGN
+0x2275 0x266D  # MUSIC FLAT SIGN
+0x2276 0x266A  # EIGHTH NOTE
+0x2277 0x2020  # DAGGER
+0x2278 0x2021  # DOUBLE DAGGER
+0x2279 0x00B6  # PILCROW SIGN
+0x227E 0x25EF  # LARGE CIRCLE
+0x2330 0xFF10  # FULLWIDTH DIGIT ZERO
+0x2331 0xFF11  # FULLWIDTH DIGIT ONE
+0x2332 0xFF12  # FULLWIDTH DIGIT TWO
+0x2333 0xFF13  # FULLWIDTH DIGIT THREE
+0x2334 0xFF14  # FULLWIDTH DIGIT FOUR
+0x2335 0xFF15  # FULLWIDTH DIGIT FIVE
+0x2336 0xFF16  # FULLWIDTH DIGIT SIX
+0x2337 0xFF17  # FULLWIDTH DIGIT SEVEN
+0x2338 0xFF18  # FULLWIDTH DIGIT EIGHT
+0x2339 0xFF19  # FULLWIDTH DIGIT NINE
+0x2341 0xFF21  # FULLWIDTH LATIN CAPITAL LETTER A
+0x2342 0xFF22  # FULLWIDTH LATIN CAPITAL LETTER B
+0x2343 0xFF23  # FULLWIDTH LATIN CAPITAL LETTER C
+0x2344 0xFF24  # FULLWIDTH LATIN CAPITAL LETTER D
+0x2345 0xFF25  # FULLWIDTH LATIN CAPITAL LETTER E
+0x2346 0xFF26  # FULLWIDTH LATIN CAPITAL LETTER F
+0x2347 0xFF27  # FULLWIDTH LATIN CAPITAL LETTER G
+0x2348 0xFF28  # FULLWIDTH LATIN CAPITAL LETTER H
+0x2349 0xFF29  # FULLWIDTH LATIN CAPITAL LETTER I
+0x234A 0xFF2A  # FULLWIDTH LATIN CAPITAL LETTER J
+0x234B 0xFF2B  # FULLWIDTH LATIN CAPITAL LETTER K
+0x234C 0xFF2C  # FULLWIDTH LATIN CAPITAL LETTER L
+0x234D 0xFF2D  # FULLWIDTH LATIN CAPITAL LETTER M
+0x234E 0xFF2E  # FULLWIDTH LATIN CAPITAL LETTER N
+0x234F 0xFF2F  # FULLWIDTH LATIN CAPITAL LETTER O
+0x2350 0xFF30  # FULLWIDTH LATIN CAPITAL LETTER P
+0x2351 0xFF31  # FULLWIDTH LATIN CAPITAL LETTER Q
+0x2352 0xFF32  # FULLWIDTH LATIN CAPITAL LETTER R
+0x2353 0xFF33  # FULLWIDTH LATIN CAPITAL LETTER S
+0x2354 0xFF34  # FULLWIDTH LATIN CAPITAL LETTER T
+0x2355 0xFF35  # FULLWIDTH LATIN CAPITAL LETTER U
+0x2356 0xFF36  # FULLWIDTH LATIN CAPITAL LETTER V
+0x2357 0xFF37  # FULLWIDTH LATIN CAPITAL LETTER W
+0x2358 0xFF38  # FULLWIDTH LATIN CAPITAL LETTER X
+0x2359 0xFF39  # FULLWIDTH LATIN CAPITAL LETTER Y
+0x235A 0xFF3A  # FULLWIDTH LATIN CAPITAL LETTER Z
+0x2361 0xFF41  # FULLWIDTH LATIN SMALL LETTER A
+0x2362 0xFF42  # FULLWIDTH LATIN SMALL LETTER B
+0x2363 0xFF43  # FULLWIDTH LATIN SMALL LETTER C
+0x2364 0xFF44  # FULLWIDTH LATIN SMALL LETTER D
+0x2365 0xFF45  # FULLWIDTH LATIN SMALL LETTER E
+0x2366 0xFF46  # FULLWIDTH LATIN SMALL LETTER F
+0x2367 0xFF47  # FULLWIDTH LATIN SMALL LETTER G
+0x2368 0xFF48  # FULLWIDTH LATIN SMALL LETTER H
+0x2369 0xFF49  # FULLWIDTH LATIN SMALL LETTER I
+0x236A 0xFF4A  # FULLWIDTH LATIN SMALL LETTER J
+0x236B 0xFF4B  # FULLWIDTH LATIN SMALL LETTER K
+0x236C 0xFF4C  # FULLWIDTH LATIN SMALL LETTER L
+0x236D 0xFF4D  # FULLWIDTH LATIN SMALL LETTER M
+0x236E 0xFF4E  # FULLWIDTH LATIN SMALL LETTER N
+0x236F 0xFF4F  # FULLWIDTH LATIN SMALL LETTER O
+0x2370 0xFF50  # FULLWIDTH LATIN SMALL LETTER P
+0x2371 0xFF51  # FULLWIDTH LATIN SMALL LETTER Q
+0x2372 0xFF52  # FULLWIDTH LATIN SMALL LETTER R
+0x2373 0xFF53  # FULLWIDTH LATIN SMALL LETTER S
+0x2374 0xFF54  # FULLWIDTH LATIN SMALL LETTER T
+0x2375 0xFF55  # FULLWIDTH LATIN SMALL LETTER U
+0x2376 0xFF56  # FULLWIDTH LATIN SMALL LETTER V
+0x2377 0xFF57  # FULLWIDTH LATIN SMALL LETTER W
+0x2378 0xFF58  # FULLWIDTH LATIN SMALL LETTER X
+0x2379 0xFF59  # FULLWIDTH LATIN SMALL LETTER Y
+0x237A 0xFF5A  # FULLWIDTH LATIN SMALL LETTER Z
+0x2421 0x3041  # HIRAGANA LETTER SMALL A
+0x2422 0x3042  # HIRAGANA LETTER A
+0x2423 0x3043  # HIRAGANA LETTER SMALL I
+0x2424 0x3044  # HIRAGANA LETTER I
+0x2425 0x3045  # HIRAGANA LETTER SMALL U
+0x2426 0x3046  # HIRAGANA LETTER U
+0x2427 0x3047  # HIRAGANA LETTER SMALL E
+0x2428 0x3048  # HIRAGANA LETTER E
+0x2429 0x3049  # HIRAGANA LETTER SMALL O
+0x242A 0x304A  # HIRAGANA LETTER O
+0x242B 0x304B  # HIRAGANA LETTER KA
+0x242C 0x304C  # HIRAGANA LETTER GA
+0x242D 0x304D  # HIRAGANA LETTER KI
+0x242E 0x304E  # HIRAGANA LETTER GI
+0x242F 0x304F  # HIRAGANA LETTER KU
+0x2430 0x3050  # HIRAGANA LETTER GU
+0x2431 0x3051  # HIRAGANA LETTER KE
+0x2432 0x3052  # HIRAGANA LETTER GE
+0x2433 0x3053  # HIRAGANA LETTER KO
+0x2434 0x3054  # HIRAGANA LETTER GO
+0x2435 0x3055  # HIRAGANA LETTER SA
+0x2436 0x3056  # HIRAGANA LETTER ZA
+0x2437 0x3057  # HIRAGANA LETTER SI
+0x2438 0x3058  # HIRAGANA LETTER ZI
+0x2439 0x3059  # HIRAGANA LETTER SU
+0x243A 0x305A  # HIRAGANA LETTER ZU
+0x243B 0x305B  # HIRAGANA LETTER SE
+0x243C 0x305C  # HIRAGANA LETTER ZE
+0x243D 0x305D  # HIRAGANA LETTER SO
+0x243E 0x305E  # HIRAGANA LETTER ZO
+0x243F 0x305F  # HIRAGANA LETTER TA
+0x2440 0x3060  # HIRAGANA LETTER DA
+0x2441 0x3061  # HIRAGANA LETTER TI
+0x2442 0x3062  # HIRAGANA LETTER DI
+0x2443 0x3063  # HIRAGANA LETTER SMALL TU
+0x2444 0x3064  # HIRAGANA LETTER TU
+0x2445 0x3065  # HIRAGANA LETTER DU
+0x2446 0x3066  # HIRAGANA LETTER TE
+0x2447 0x3067  # HIRAGANA LETTER DE
+0x2448 0x3068  # HIRAGANA LETTER TO
+0x2449 0x3069  # HIRAGANA LETTER DO
+0x244A 0x306A  # HIRAGANA LETTER NA
+0x244B 0x306B  # HIRAGANA LETTER NI
+0x244C 0x306C  # HIRAGANA LETTER NU
+0x244D 0x306D  # HIRAGANA LETTER NE
+0x244E 0x306E  # HIRAGANA LETTER NO
+0x244F 0x306F  # HIRAGANA LETTER HA
+0x2450 0x3070  # HIRAGANA LETTER BA
+0x2451 0x3071  # HIRAGANA LETTER PA
+0x2452 0x3072  # HIRAGANA LETTER HI
+0x2453 0x3073  # HIRAGANA LETTER BI
+0x2454 0x3074  # HIRAGANA LETTER PI
+0x2455 0x3075  # HIRAGANA LETTER HU
+0x2456 0x3076  # HIRAGANA LETTER BU
+0x2457 0x3077  # HIRAGANA LETTER PU
+0x2458 0x3078  # HIRAGANA LETTER HE
+0x2459 0x3079  # HIRAGANA LETTER BE
+0x245A 0x307A  # HIRAGANA LETTER PE
+0x245B 0x307B  # HIRAGANA LETTER HO
+0x245C 0x307C  # HIRAGANA LETTER BO
+0x245D 0x307D  # HIRAGANA LETTER PO
+0x245E 0x307E  # HIRAGANA LETTER MA
+0x245F 0x307F  # HIRAGANA LETTER MI
+0x2460 0x3080  # HIRAGANA LETTER MU
+0x2461 0x3081  # HIRAGANA LETTER ME
+0x2462 0x3082  # HIRAGANA LETTER MO
+0x2463 0x3083  # HIRAGANA LETTER SMALL YA
+0x2464 0x3084  # HIRAGANA LETTER YA
+0x2465 0x3085  # HIRAGANA LETTER SMALL YU
+0x2466 0x3086  # HIRAGANA LETTER YU
+0x2467 0x3087  # HIRAGANA LETTER SMALL YO
+0x2468 0x3088  # HIRAGANA LETTER YO
+0x2469 0x3089  # HIRAGANA LETTER RA
+0x246A 0x308A  # HIRAGANA LETTER RI
+0x246B 0x308B  # HIRAGANA LETTER RU
+0x246C 0x308C  # HIRAGANA LETTER RE
+0x246D 0x308D  # HIRAGANA LETTER RO
+0x246E 0x308E  # HIRAGANA LETTER SMALL WA
+0x246F 0x308F  # HIRAGANA LETTER WA
+0x2470 0x3090  # HIRAGANA LETTER WI
+0x2471 0x3091  # HIRAGANA LETTER WE
+0x2472 0x3092  # HIRAGANA LETTER WO
+0x2473 0x3093  # HIRAGANA LETTER N
+0x2521 0x30A1  # KATAKANA LETTER SMALL A
+0x2522 0x30A2  # KATAKANA LETTER A
+0x2523 0x30A3  # KATAKANA LETTER SMALL I
+0x2524 0x30A4  # KATAKANA LETTER I
+0x2525 0x30A5  # KATAKANA LETTER SMALL U
+0x2526 0x30A6  # KATAKANA LETTER U
+0x2527 0x30A7  # KATAKANA LETTER SMALL E
+0x2528 0x30A8  # KATAKANA LETTER E
+0x2529 0x30A9  # KATAKANA LETTER SMALL O
+0x252A 0x30AA  # KATAKANA LETTER O
+0x252B 0x30AB  # KATAKANA LETTER KA
+0x252C 0x30AC  # KATAKANA LETTER GA
+0x252D 0x30AD  # KATAKANA LETTER KI
+0x252E 0x30AE  # KATAKANA LETTER GI
+0x252F 0x30AF  # KATAKANA LETTER KU
+0x2530 0x30B0  # KATAKANA LETTER GU
+0x2531 0x30B1  # KATAKANA LETTER KE
+0x2532 0x30B2  # KATAKANA LETTER GE
+0x2533 0x30B3  # KATAKANA LETTER KO
+0x2534 0x30B4  # KATAKANA LETTER GO
+0x2535 0x30B5  # KATAKANA LETTER SA
+0x2536 0x30B6  # KATAKANA LETTER ZA
+0x2537 0x30B7  # KATAKANA LETTER SI
+0x2538 0x30B8  # KATAKANA LETTER ZI
+0x2539 0x30B9  # KATAKANA LETTER SU
+0x253A 0x30BA  # KATAKANA LETTER ZU
+0x253B 0x30BB  # KATAKANA LETTER SE
+0x253C 0x30BC  # KATAKANA LETTER ZE
+0x253D 0x30BD  # KATAKANA LETTER SO
+0x253E 0x30BE  # KATAKANA LETTER ZO
+0x253F 0x30BF  # KATAKANA LETTER TA
+0x2540 0x30C0  # KATAKANA LETTER DA
+0x2541 0x30C1  # KATAKANA LETTER TI
+0x2542 0x30C2  # KATAKANA LETTER DI
+0x2543 0x30C3  # KATAKANA LETTER SMALL TU
+0x2544 0x30C4  # KATAKANA LETTER TU
+0x2545 0x30C5  # KATAKANA LETTER DU
+0x2546 0x30C6  # KATAKANA LETTER TE
+0x2547 0x30C7  # KATAKANA LETTER DE
+0x2548 0x30C8  # KATAKANA LETTER TO
+0x2549 0x30C9  # KATAKANA LETTER DO
+0x254A 0x30CA  # KATAKANA LETTER NA
+0x254B 0x30CB  # KATAKANA LETTER NI
+0x254C 0x30CC  # KATAKANA LETTER NU
+0x254D 0x30CD  # KATAKANA LETTER NE
+0x254E 0x30CE  # KATAKANA LETTER NO
+0x254F 0x30CF  # KATAKANA LETTER HA
+0x2550 0x30D0  # KATAKANA LETTER BA
+0x2551 0x30D1  # KATAKANA LETTER PA
+0x2552 0x30D2  # KATAKANA LETTER HI
+0x2553 0x30D3  # KATAKANA LETTER BI
+0x2554 0x30D4  # KATAKANA LETTER PI
+0x2555 0x30D5  # KATAKANA LETTER HU
+0x2556 0x30D6  # KATAKANA LETTER BU
+0x2557 0x30D7  # KATAKANA LETTER PU
+0x2558 0x30D8  # KATAKANA LETTER HE
+0x2559 0x30D9  # KATAKANA LETTER BE
+0x255A 0x30DA  # KATAKANA LETTER PE
+0x255B 0x30DB  # KATAKANA LETTER HO
+0x255C 0x30DC  # KATAKANA LETTER BO
+0x255D 0x30DD  # KATAKANA LETTER PO
+0x255E 0x30DE  # KATAKANA LETTER MA
+0x255F 0x30DF  # KATAKANA LETTER MI
+0x2560 0x30E0  # KATAKANA LETTER MU
+0x2561 0x30E1  # KATAKANA LETTER ME
+0x2562 0x30E2  # KATAKANA LETTER MO
+0x2563 0x30E3  # KATAKANA LETTER SMALL YA
+0x2564 0x30E4  # KATAKANA LETTER YA
+0x2565 0x30E5  # KATAKANA LETTER SMALL YU
+0x2566 0x30E6  # KATAKANA LETTER YU
+0x2567 0x30E7  # KATAKANA LETTER SMALL YO
+0x2568 0x30E8  # KATAKANA LETTER YO
+0x2569 0x30E9  # KATAKANA LETTER RA
+0x256A 0x30EA  # KATAKANA LETTER RI
+0x256B 0x30EB  # KATAKANA LETTER RU
+0x256C 0x30EC  # KATAKANA LETTER RE
+0x256D 0x30ED  # KATAKANA LETTER RO
+0x256E 0x30EE  # KATAKANA LETTER SMALL WA
+0x256F 0x30EF  # KATAKANA LETTER WA
+0x2570 0x30F0  # KATAKANA LETTER WI
+0x2571 0x30F1  # KATAKANA LETTER WE
+0x2572 0x30F2  # KATAKANA LETTER WO
+0x2573 0x30F3  # KATAKANA LETTER N
+0x2574 0x30F4  # KATAKANA LETTER VU
+0x2575 0x30F5  # KATAKANA LETTER SMALL KA
+0x2576 0x30F6  # KATAKANA LETTER SMALL KE
+0x2621 0x0391  # GREEK CAPITAL LETTER ALPHA
+0x2622 0x0392  # GREEK CAPITAL LETTER BETA
+0x2623 0x0393  # GREEK CAPITAL LETTER GAMMA
+0x2624 0x0394  # GREEK CAPITAL LETTER DELTA
+0x2625 0x0395  # GREEK CAPITAL LETTER EPSILON
+0x2626 0x0396  # GREEK CAPITAL LETTER ZETA
+0x2627 0x0397  # GREEK CAPITAL LETTER ETA
+0x2628 0x0398  # GREEK CAPITAL LETTER THETA
+0x2629 0x0399  # GREEK CAPITAL LETTER IOTA
+0x262A 0x039A  # GREEK CAPITAL LETTER KAPPA
+0x262B 0x039B  # GREEK CAPITAL LETTER LAMDA
+0x262C 0x039C  # GREEK CAPITAL LETTER MU
+0x262D 0x039D  # GREEK CAPITAL LETTER NU
+0x262E 0x039E  # GREEK CAPITAL LETTER XI
+0x262F 0x039F  # GREEK CAPITAL LETTER OMICRON
+0x2630 0x03A0  # GREEK CAPITAL LETTER PI
+0x2631 0x03A1  # GREEK CAPITAL LETTER RHO
+0x2632 0x03A3  # GREEK CAPITAL LETTER SIGMA
+0x2633 0x03A4  # GREEK CAPITAL LETTER TAU
+0x2634 0x03A5  # GREEK CAPITAL LETTER UPSILON
+0x2635 0x03A6  # GREEK CAPITAL LETTER PHI
+0x2636 0x03A7  # GREEK CAPITAL LETTER CHI
+0x2637 0x03A8  # GREEK CAPITAL LETTER PSI
+0x2638 0x03A9  # GREEK CAPITAL LETTER OMEGA
+0x2641 0x03B1  # GREEK SMALL LETTER ALPHA
+0x2642 0x03B2  # GREEK SMALL LETTER BETA
+0x2643 0x03B3  # GREEK SMALL LETTER GAMMA
+0x2644 0x03B4  # GREEK SMALL LETTER DELTA
+0x2645 0x03B5  # GREEK SMALL LETTER EPSILON
+0x2646 0x03B6  # GREEK SMALL LETTER ZETA
+0x2647 0x03B7  # GREEK SMALL LETTER ETA
+0x2648 0x03B8  # GREEK SMALL LETTER THETA
+0x2649 0x03B9  # GREEK SMALL LETTER IOTA
+0x264A 0x03BA  # GREEK SMALL LETTER KAPPA
+0x264B 0x03BB  # GREEK SMALL LETTER LAMDA
+0x264C 0x03BC  # GREEK SMALL LETTER MU
+0x264D 0x03BD  # GREEK SMALL LETTER NU
+0x264E 0x03BE  # GREEK SMALL LETTER XI
+0x264F 0x03BF  # GREEK SMALL LETTER OMICRON
+0x2650 0x03C0  # GREEK SMALL LETTER PI
+0x2651 0x03C1  # GREEK SMALL LETTER RHO
+0x2652 0x03C3  # GREEK SMALL LETTER SIGMA
+0x2653 0x03C4  # GREEK SMALL LETTER TAU
+0x2654 0x03C5  # GREEK SMALL LETTER UPSILON
+0x2655 0x03C6  # GREEK SMALL LETTER PHI
+0x2656 0x03C7  # GREEK SMALL LETTER CHI
+0x2657 0x03C8  # GREEK SMALL LETTER PSI
+0x2658 0x03C9  # GREEK SMALL LETTER OMEGA
+0x2721 0x0410  # CYRILLIC CAPITAL LETTER A
+0x2722 0x0411  # CYRILLIC CAPITAL LETTER BE
+0x2723 0x0412  # CYRILLIC CAPITAL LETTER VE
+0x2724 0x0413  # CYRILLIC CAPITAL LETTER GHE
+0x2725 0x0414  # CYRILLIC CAPITAL LETTER DE
+0x2726 0x0415  # CYRILLIC CAPITAL LETTER IE
+0x2727 0x0401  # CYRILLIC CAPITAL LETTER IO
+0x2728 0x0416  # CYRILLIC CAPITAL LETTER ZHE
+0x2729 0x0417  # CYRILLIC CAPITAL LETTER ZE
+0x272A 0x0418  # CYRILLIC CAPITAL LETTER I
+0x272B 0x0419  # CYRILLIC CAPITAL LETTER SHORT I
+0x272C 0x041A  # CYRILLIC CAPITAL LETTER KA
+0x272D 0x041B  # CYRILLIC CAPITAL LETTER EL
+0x272E 0x041C  # CYRILLIC CAPITAL LETTER EM
+0x272F 0x041D  # CYRILLIC CAPITAL LETTER EN
+0x2730 0x041E  # CYRILLIC CAPITAL LETTER O
+0x2731 0x041F  # CYRILLIC CAPITAL LETTER PE
+0x2732 0x0420  # CYRILLIC CAPITAL LETTER ER
+0x2733 0x0421  # CYRILLIC CAPITAL LETTER ES
+0x2734 0x0422  # CYRILLIC CAPITAL LETTER TE
+0x2735 0x0423  # CYRILLIC CAPITAL LETTER U
+0x2736 0x0424  # CYRILLIC CAPITAL LETTER EF
+0x2737 0x0425  # CYRILLIC CAPITAL LETTER HA
+0x2738 0x0426  # CYRILLIC CAPITAL LETTER TSE
+0x2739 0x0427  # CYRILLIC CAPITAL LETTER CHE
+0x273A 0x0428  # CYRILLIC CAPITAL LETTER SHA
+0x273B 0x0429  # CYRILLIC CAPITAL LETTER SHCHA
+0x273C 0x042A  # CYRILLIC CAPITAL LETTER HARD SIGN
+0x273D 0x042B  # CYRILLIC CAPITAL LETTER YERU
+0x273E 0x042C  # CYRILLIC CAPITAL LETTER SOFT SIGN
+0x273F 0x042D  # CYRILLIC CAPITAL LETTER E
+0x2740 0x042E  # CYRILLIC CAPITAL LETTER YU
+0x2741 0x042F  # CYRILLIC CAPITAL LETTER YA
+0x2751 0x0430  # CYRILLIC SMALL LETTER A
+0x2752 0x0431  # CYRILLIC SMALL LETTER BE
+0x2753 0x0432  # CYRILLIC SMALL LETTER VE
+0x2754 0x0433  # CYRILLIC SMALL LETTER GHE
+0x2755 0x0434  # CYRILLIC SMALL LETTER DE
+0x2756 0x0435  # CYRILLIC SMALL LETTER IE
+0x2757 0x0451  # CYRILLIC SMALL LETTER IO
+0x2758 0x0436  # CYRILLIC SMALL LETTER ZHE
+0x2759 0x0437  # CYRILLIC SMALL LETTER ZE
+0x275A 0x0438  # CYRILLIC SMALL LETTER I
+0x275B 0x0439  # CYRILLIC SMALL LETTER SHORT I
+0x275C 0x043A  # CYRILLIC SMALL LETTER KA
+0x275D 0x043B  # CYRILLIC SMALL LETTER EL
+0x275E 0x043C  # CYRILLIC SMALL LETTER EM
+0x275F 0x043D  # CYRILLIC SMALL LETTER EN
+0x2760 0x043E  # CYRILLIC SMALL LETTER O
+0x2761 0x043F  # CYRILLIC SMALL LETTER PE
+0x2762 0x0440  # CYRILLIC SMALL LETTER ER
+0x2763 0x0441  # CYRILLIC SMALL LETTER ES
+0x2764 0x0442  # CYRILLIC SMALL LETTER TE
+0x2765 0x0443  # CYRILLIC SMALL LETTER U
+0x2766 0x0444  # CYRILLIC SMALL LETTER EF
+0x2767 0x0445  # CYRILLIC SMALL LETTER HA
+0x2768 0x0446  # CYRILLIC SMALL LETTER TSE
+0x2769 0x0447  # CYRILLIC SMALL LETTER CHE
+0x276A 0x0448  # CYRILLIC SMALL LETTER SHA
+0x276B 0x0449  # CYRILLIC SMALL LETTER SHCHA
+0x276C 0x044A  # CYRILLIC SMALL LETTER HARD SIGN
+0x276D 0x044B  # CYRILLIC SMALL LETTER YERU
+0x276E 0x044C  # CYRILLIC SMALL LETTER SOFT SIGN
+0x276F 0x044D  # CYRILLIC SMALL LETTER E
+0x2770 0x044E  # CYRILLIC SMALL LETTER YU
+0x2771 0x044F  # CYRILLIC SMALL LETTER YA
+0x2821 0x2500  # BOX DRAWINGS LIGHT HORIZONTAL
+0x2822 0x2502  # BOX DRAWINGS LIGHT VERTICAL
+0x2823 0x250C  # BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x2824 0x2510  # BOX DRAWINGS LIGHT DOWN AND LEFT
+0x2825 0x2518  # BOX DRAWINGS LIGHT UP AND LEFT
+0x2826 0x2514  # BOX DRAWINGS LIGHT UP AND RIGHT
+0x2827 0x251C  # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x2828 0x252C  # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x2829 0x2524  # BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x282A 0x2534  # BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x282B 0x253C  # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x282C 0x2501  # BOX DRAWINGS HEAVY HORIZONTAL
+0x282D 0x2503  # BOX DRAWINGS HEAVY VERTICAL
+0x282E 0x250F  # BOX DRAWINGS HEAVY DOWN AND RIGHT
+0x282F 0x2513  # BOX DRAWINGS HEAVY DOWN AND LEFT
+0x2830 0x251B  # BOX DRAWINGS HEAVY UP AND LEFT
+0x2831 0x2517  # BOX DRAWINGS HEAVY UP AND RIGHT
+0x2832 0x2523  # BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0x2833 0x2533  # BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0x2834 0x252B  # BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0x2835 0x253B  # BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0x2836 0x254B  # BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0x2837 0x2520  # BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0x2838 0x252F  # BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0x2839 0x2528  # BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0x283A 0x2537  # BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0x283B 0x253F  # BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0x283C 0x251D  # BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0x283D 0x2530  # BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0x283E 0x2525  # BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0x283F 0x2538  # BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0x2840 0x2542  # BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0x3021 0x4E9C  # <CJK>
+0x3022 0x5516  # <CJK>
+0x3023 0x5A03  # <CJK>
+0x3024 0x963F  # <CJK>
+0x3025 0x54C0  # <CJK>
+0x3026 0x611B  # <CJK>
+0x3027 0x6328  # <CJK>
+0x3028 0x59F6  # <CJK>
+0x3029 0x9022  # <CJK>
+0x302A 0x8475  # <CJK>
+0x302B 0x831C  # <CJK>
+0x302C 0x7A50  # <CJK>
+0x302D 0x60AA  # <CJK>
+0x302E 0x63E1  # <CJK>
+0x302F 0x6E25  # <CJK>
+0x3030 0x65ED  # <CJK>
+0x3031 0x8466  # <CJK>
+0x3032 0x82A6  # <CJK>
+0x3033 0x9BF5  # <CJK>
+0x3034 0x6893  # <CJK>
+0x3035 0x5727  # <CJK>
+0x3036 0x65A1  # <CJK>
+0x3037 0x6271  # <CJK>
+0x3038 0x5B9B  # <CJK>
+0x3039 0x59D0  # <CJK>
+0x303A 0x867B  # <CJK>
+0x303B 0x98F4  # <CJK>
+0x303C 0x7D62  # <CJK>
+0x303D 0x7DBE  # <CJK>
+0x303E 0x9B8E  # <CJK>
+0x303F 0x6216  # <CJK>
+0x3040 0x7C9F  # <CJK>
+0x3041 0x88B7  # <CJK>
+0x3042 0x5B89  # <CJK>
+0x3043 0x5EB5  # <CJK>
+0x3044 0x6309  # <CJK>
+0x3045 0x6697  # <CJK>
+0x3046 0x6848  # <CJK>
+0x3047 0x95C7  # <CJK>
+0x3048 0x978D  # <CJK>
+0x3049 0x674F  # <CJK>
+0x304A 0x4EE5  # <CJK>
+0x304B 0x4F0A  # <CJK>
+0x304C 0x4F4D  # <CJK>
+0x304D 0x4F9D  # <CJK>
+0x304E 0x5049  # <CJK>
+0x304F 0x56F2  # <CJK>
+0x3050 0x5937  # <CJK>
+0x3051 0x59D4  # <CJK>
+0x3052 0x5A01  # <CJK>
+0x3053 0x5C09  # <CJK>
+0x3054 0x60DF  # <CJK>
+0x3055 0x610F  # <CJK>
+0x3056 0x6170  # <CJK>
+0x3057 0x6613  # <CJK>
+0x3058 0x6905  # <CJK>
+0x3059 0x70BA  # <CJK>
+0x305A 0x754F  # <CJK>
+0x305B 0x7570  # <CJK>
+0x305C 0x79FB  # <CJK>
+0x305D 0x7DAD  # <CJK>
+0x305E 0x7DEF  # <CJK>
+0x305F 0x80C3  # <CJK>
+0x3060 0x840E  # <CJK>
+0x3061 0x8863  # <CJK>
+0x3062 0x8B02  # <CJK>
+0x3063 0x9055  # <CJK>
+0x3064 0x907A  # <CJK>
+0x3065 0x533B  # <CJK>
+0x3066 0x4E95  # <CJK>
+0x3067 0x4EA5  # <CJK>
+0x3068 0x57DF  # <CJK>
+0x3069 0x80B2  # <CJK>
+0x306A 0x90C1  # <CJK>
+0x306B 0x78EF  # <CJK>
+0x306C 0x4E00  # <CJK>
+0x306D 0x58F1  # <CJK>
+0x306E 0x6EA2  # <CJK>
+0x306F 0x9038  # <CJK>
+0x3070 0x7A32  # <CJK>
+0x3071 0x8328  # <CJK>
+0x3072 0x828B  # <CJK>
+0x3073 0x9C2F  # <CJK>
+0x3074 0x5141  # <CJK>
+0x3075 0x5370  # <CJK>
+0x3076 0x54BD  # <CJK>
+0x3077 0x54E1  # <CJK>
+0x3078 0x56E0  # <CJK>
+0x3079 0x59FB  # <CJK>
+0x307A 0x5F15  # <CJK>
+0x307B 0x98F2  # <CJK>
+0x307C 0x6DEB  # <CJK>
+0x307D 0x80E4  # <CJK>
+0x307E 0x852D  # <CJK>
+0x3121 0x9662  # <CJK>
+0x3122 0x9670  # <CJK>
+0x3123 0x96A0  # <CJK>
+0x3124 0x97FB  # <CJK>
+0x3125 0x540B  # <CJK>
+0x3126 0x53F3  # <CJK>
+0x3127 0x5B87  # <CJK>
+0x3128 0x70CF  # <CJK>
+0x3129 0x7FBD  # <CJK>
+0x312A 0x8FC2  # <CJK>
+0x312B 0x96E8  # <CJK>
+0x312C 0x536F  # <CJK>
+0x312D 0x9D5C  # <CJK>
+0x312E 0x7ABA  # <CJK>
+0x312F 0x4E11  # <CJK>
+0x3130 0x7893  # <CJK>
+0x3131 0x81FC  # <CJK>
+0x3132 0x6E26  # <CJK>
+0x3133 0x5618  # <CJK>
+0x3134 0x5504  # <CJK>
+0x3135 0x6B1D  # <CJK>
+0x3136 0x851A  # <CJK>
+0x3137 0x9C3B  # <CJK>
+0x3138 0x59E5  # <CJK>
+0x3139 0x53A9  # <CJK>
+0x313A 0x6D66  # <CJK>
+0x313B 0x74DC  # <CJK>
+0x313C 0x958F  # <CJK>
+0x313D 0x5642  # <CJK>
+0x313E 0x4E91  # <CJK>
+0x313F 0x904B  # <CJK>
+0x3140 0x96F2  # <CJK>
+0x3141 0x834F  # <CJK>
+0x3142 0x990C  # <CJK>
+0x3143 0x53E1  # <CJK>
+0x3144 0x55B6  # <CJK>
+0x3145 0x5B30  # <CJK>
+0x3146 0x5F71  # <CJK>
+0x3147 0x6620  # <CJK>
+0x3148 0x66F3  # <CJK>
+0x3149 0x6804  # <CJK>
+0x314A 0x6C38  # <CJK>
+0x314B 0x6CF3  # <CJK>
+0x314C 0x6D29  # <CJK>
+0x314D 0x745B  # <CJK>
+0x314E 0x76C8  # <CJK>
+0x314F 0x7A4E  # <CJK>
+0x3150 0x9834  # <CJK>
+0x3151 0x82F1  # <CJK>
+0x3152 0x885B  # <CJK>
+0x3153 0x8A60  # <CJK>
+0x3154 0x92ED  # <CJK>
+0x3155 0x6DB2  # <CJK>
+0x3156 0x75AB  # <CJK>
+0x3157 0x76CA  # <CJK>
+0x3158 0x99C5  # <CJK>
+0x3159 0x60A6  # <CJK>
+0x315A 0x8B01  # <CJK>
+0x315B 0x8D8A  # <CJK>
+0x315C 0x95B2  # <CJK>
+0x315D 0x698E  # <CJK>
+0x315E 0x53AD  # <CJK>
+0x315F 0x5186  # <CJK>
+0x3160 0x5712  # <CJK>
+0x3161 0x5830  # <CJK>
+0x3162 0x5944  # <CJK>
+0x3163 0x5BB4  # <CJK>
+0x3164 0x5EF6  # <CJK>
+0x3165 0x6028  # <CJK>
+0x3166 0x63A9  # <CJK>
+0x3167 0x63F4  # <CJK>
+0x3168 0x6CBF  # <CJK>
+0x3169 0x6F14  # <CJK>
+0x316A 0x708E  # <CJK>
+0x316B 0x7114  # <CJK>
+0x316C 0x7159  # <CJK>
+0x316D 0x71D5  # <CJK>
+0x316E 0x733F  # <CJK>
+0x316F 0x7E01  # <CJK>
+0x3170 0x8276  # <CJK>
+0x3171 0x82D1  # <CJK>
+0x3172 0x8597  # <CJK>
+0x3173 0x9060  # <CJK>
+0x3174 0x925B  # <CJK>
+0x3175 0x9D1B  # <CJK>
+0x3176 0x5869  # <CJK>
+0x3177 0x65BC  # <CJK>
+0x3178 0x6C5A  # <CJK>
+0x3179 0x7525  # <CJK>
+0x317A 0x51F9  # <CJK>
+0x317B 0x592E  # <CJK>
+0x317C 0x5965  # <CJK>
+0x317D 0x5F80  # <CJK>
+0x317E 0x5FDC  # <CJK>
+0x3221 0x62BC  # <CJK>
+0x3222 0x65FA  # <CJK>
+0x3223 0x6A2A  # <CJK>
+0x3224 0x6B27  # <CJK>
+0x3225 0x6BB4  # <CJK>
+0x3226 0x738B  # <CJK>
+0x3227 0x7FC1  # <CJK>
+0x3228 0x8956  # <CJK>
+0x3229 0x9D2C  # <CJK>
+0x322A 0x9D0E  # <CJK>
+0x322B 0x9EC4  # <CJK>
+0x322C 0x5CA1  # <CJK>
+0x322D 0x6C96  # <CJK>
+0x322E 0x837B  # <CJK>
+0x322F 0x5104  # <CJK>
+0x3230 0x5C4B  # <CJK>
+0x3231 0x61B6  # <CJK>
+0x3232 0x81C6  # <CJK>
+0x3233 0x6876  # <CJK>
+0x3234 0x7261  # <CJK>
+0x3235 0x4E59  # <CJK>
+0x3236 0x4FFA  # <CJK>
+0x3237 0x5378  # <CJK>
+0x3238 0x6069  # <CJK>
+0x3239 0x6E29  # <CJK>
+0x323A 0x7A4F  # <CJK>
+0x323B 0x97F3  # <CJK>
+0x323C 0x4E0B  # <CJK>
+0x323D 0x5316  # <CJK>
+0x323E 0x4EEE  # <CJK>
+0x323F 0x4F55  # <CJK>
+0x3240 0x4F3D  # <CJK>
+0x3241 0x4FA1  # <CJK>
+0x3242 0x4F73  # <CJK>
+0x3243 0x52A0  # <CJK>
+0x3244 0x53EF  # <CJK>
+0x3245 0x5609  # <CJK>
+0x3246 0x590F  # <CJK>
+0x3247 0x5AC1  # <CJK>
+0x3248 0x5BB6  # <CJK>
+0x3249 0x5BE1  # <CJK>
+0x324A 0x79D1  # <CJK>
+0x324B 0x6687  # <CJK>
+0x324C 0x679C  # <CJK>
+0x324D 0x67B6  # <CJK>
+0x324E 0x6B4C  # <CJK>
+0x324F 0x6CB3  # <CJK>
+0x3250 0x706B  # <CJK>
+0x3251 0x73C2  # <CJK>
+0x3252 0x798D  # <CJK>
+0x3253 0x79BE  # <CJK>
+0x3254 0x7A3C  # <CJK>
+0x3255 0x7B87  # <CJK>
+0x3256 0x82B1  # <CJK>
+0x3257 0x82DB  # <CJK>
+0x3258 0x8304  # <CJK>
+0x3259 0x8377  # <CJK>
+0x325A 0x83EF  # <CJK>
+0x325B 0x83D3  # <CJK>
+0x325C 0x8766  # <CJK>
+0x325D 0x8AB2  # <CJK>
+0x325E 0x5629  # <CJK>
+0x325F 0x8CA8  # <CJK>
+0x3260 0x8FE6  # <CJK>
+0x3261 0x904E  # <CJK>
+0x3262 0x971E  # <CJK>
+0x3263 0x868A  # <CJK>
+0x3264 0x4FC4  # <CJK>
+0x3265 0x5CE8  # <CJK>
+0x3266 0x6211  # <CJK>
+0x3267 0x7259  # <CJK>
+0x3268 0x753B  # <CJK>
+0x3269 0x81E5  # <CJK>
+0x326A 0x82BD  # <CJK>
+0x326B 0x86FE  # <CJK>
+0x326C 0x8CC0  # <CJK>
+0x326D 0x96C5  # <CJK>
+0x326E 0x9913  # <CJK>
+0x326F 0x99D5  # <CJK>
+0x3270 0x4ECB  # <CJK>
+0x3271 0x4F1A  # <CJK>
+0x3272 0x89E3  # <CJK>
+0x3273 0x56DE  # <CJK>
+0x3274 0x584A  # <CJK>
+0x3275 0x58CA  # <CJK>
+0x3276 0x5EFB  # <CJK>
+0x3277 0x5FEB  # <CJK>
+0x3278 0x602A  # <CJK>
+0x3279 0x6094  # <CJK>
+0x327A 0x6062  # <CJK>
+0x327B 0x61D0  # <CJK>
+0x327C 0x6212  # <CJK>
+0x327D 0x62D0  # <CJK>
+0x327E 0x6539  # <CJK>
+0x3321 0x9B41  # <CJK>
+0x3322 0x6666  # <CJK>
+0x3323 0x68B0  # <CJK>
+0x3324 0x6D77  # <CJK>
+0x3325 0x7070  # <CJK>
+0x3326 0x754C  # <CJK>
+0x3327 0x7686  # <CJK>
+0x3328 0x7D75  # <CJK>
+0x3329 0x82A5  # <CJK>
+0x332A 0x87F9  # <CJK>
+0x332B 0x958B  # <CJK>
+0x332C 0x968E  # <CJK>
+0x332D 0x8C9D  # <CJK>
+0x332E 0x51F1  # <CJK>
+0x332F 0x52BE  # <CJK>
+0x3330 0x5916  # <CJK>
+0x3331 0x54B3  # <CJK>
+0x3332 0x5BB3  # <CJK>
+0x3333 0x5D16  # <CJK>
+0x3334 0x6168  # <CJK>
+0x3335 0x6982  # <CJK>
+0x3336 0x6DAF  # <CJK>
+0x3337 0x788D  # <CJK>
+0x3338 0x84CB  # <CJK>
+0x3339 0x8857  # <CJK>
+0x333A 0x8A72  # <CJK>
+0x333B 0x93A7  # <CJK>
+0x333C 0x9AB8  # <CJK>
+0x333D 0x6D6C  # <CJK>
+0x333E 0x99A8  # <CJK>
+0x333F 0x86D9  # <CJK>
+0x3340 0x57A3  # <CJK>
+0x3341 0x67FF  # <CJK>
+0x3342 0x86CE  # <CJK>
+0x3343 0x920E  # <CJK>
+0x3344 0x5283  # <CJK>
+0x3345 0x5687  # <CJK>
+0x3346 0x5404  # <CJK>
+0x3347 0x5ED3  # <CJK>
+0x3348 0x62E1  # <CJK>
+0x3349 0x64B9  # <CJK>
+0x334A 0x683C  # <CJK>
+0x334B 0x6838  # <CJK>
+0x334C 0x6BBB  # <CJK>
+0x334D 0x7372  # <CJK>
+0x334E 0x78BA  # <CJK>
+0x334F 0x7A6B  # <CJK>
+0x3350 0x899A  # <CJK>
+0x3351 0x89D2  # <CJK>
+0x3352 0x8D6B  # <CJK>
+0x3353 0x8F03  # <CJK>
+0x3354 0x90ED  # <CJK>
+0x3355 0x95A3  # <CJK>
+0x3356 0x9694  # <CJK>
+0x3357 0x9769  # <CJK>
+0x3358 0x5B66  # <CJK>
+0x3359 0x5CB3  # <CJK>
+0x335A 0x697D  # <CJK>
+0x335B 0x984D  # <CJK>
+0x335C 0x984E  # <CJK>
+0x335D 0x639B  # <CJK>
+0x335E 0x7B20  # <CJK>
+0x335F 0x6A2B  # <CJK>
+0x3360 0x6A7F  # <CJK>
+0x3361 0x68B6  # <CJK>
+0x3362 0x9C0D  # <CJK>
+0x3363 0x6F5F  # <CJK>
+0x3364 0x5272  # <CJK>
+0x3365 0x559D  # <CJK>
+0x3366 0x6070  # <CJK>
+0x3367 0x62EC  # <CJK>
+0x3368 0x6D3B  # <CJK>
+0x3369 0x6E07  # <CJK>
+0x336A 0x6ED1  # <CJK>
+0x336B 0x845B  # <CJK>
+0x336C 0x8910  # <CJK>
+0x336D 0x8F44  # <CJK>
+0x336E 0x4E14  # <CJK>
+0x336F 0x9C39  # <CJK>
+0x3370 0x53F6  # <CJK>
+0x3371 0x691B  # <CJK>
+0x3372 0x6A3A  # <CJK>
+0x3373 0x9784  # <CJK>
+0x3374 0x682A  # <CJK>
+0x3375 0x515C  # <CJK>
+0x3376 0x7AC3  # <CJK>
+0x3377 0x84B2  # <CJK>
+0x3378 0x91DC  # <CJK>
+0x3379 0x938C  # <CJK>
+0x337A 0x565B  # <CJK>
+0x337B 0x9D28  # <CJK>
+0x337C 0x6822  # <CJK>
+0x337D 0x8305  # <CJK>
+0x337E 0x8431  # <CJK>
+0x3421 0x7CA5  # <CJK>
+0x3422 0x5208  # <CJK>
+0x3423 0x82C5  # <CJK>
+0x3424 0x74E6  # <CJK>
+0x3425 0x4E7E  # <CJK>
+0x3426 0x4F83  # <CJK>
+0x3427 0x51A0  # <CJK>
+0x3428 0x5BD2  # <CJK>
+0x3429 0x520A  # <CJK>
+0x342A 0x52D8  # <CJK>
+0x342B 0x52E7  # <CJK>
+0x342C 0x5DFB  # <CJK>
+0x342D 0x559A  # <CJK>
+0x342E 0x582A  # <CJK>
+0x342F 0x59E6  # <CJK>
+0x3430 0x5B8C  # <CJK>
+0x3431 0x5B98  # <CJK>
+0x3432 0x5BDB  # <CJK>
+0x3433 0x5E72  # <CJK>
+0x3434 0x5E79  # <CJK>
+0x3435 0x60A3  # <CJK>
+0x3436 0x611F  # <CJK>
+0x3437 0x6163  # <CJK>
+0x3438 0x61BE  # <CJK>
+0x3439 0x63DB  # <CJK>
+0x343A 0x6562  # <CJK>
+0x343B 0x67D1  # <CJK>
+0x343C 0x6853  # <CJK>
+0x343D 0x68FA  # <CJK>
+0x343E 0x6B3E  # <CJK>
+0x343F 0x6B53  # <CJK>
+0x3440 0x6C57  # <CJK>
+0x3441 0x6F22  # <CJK>
+0x3442 0x6F97  # <CJK>
+0x3443 0x6F45  # <CJK>
+0x3444 0x74B0  # <CJK>
+0x3445 0x7518  # <CJK>
+0x3446 0x76E3  # <CJK>
+0x3447 0x770B  # <CJK>
+0x3448 0x7AFF  # <CJK>
+0x3449 0x7BA1  # <CJK>
+0x344A 0x7C21  # <CJK>
+0x344B 0x7DE9  # <CJK>
+0x344C 0x7F36  # <CJK>
+0x344D 0x7FF0  # <CJK>
+0x344E 0x809D  # <CJK>
+0x344F 0x8266  # <CJK>
+0x3450 0x839E  # <CJK>
+0x3451 0x89B3  # <CJK>
+0x3452 0x8ACC  # <CJK>
+0x3453 0x8CAB  # <CJK>
+0x3454 0x9084  # <CJK>
+0x3455 0x9451  # <CJK>
+0x3456 0x9593  # <CJK>
+0x3457 0x9591  # <CJK>
+0x3458 0x95A2  # <CJK>
+0x3459 0x9665  # <CJK>
+0x345A 0x97D3  # <CJK>
+0x345B 0x9928  # <CJK>
+0x345C 0x8218  # <CJK>
+0x345D 0x4E38  # <CJK>
+0x345E 0x542B  # <CJK>
+0x345F 0x5CB8  # <CJK>
+0x3460 0x5DCC  # <CJK>
+0x3461 0x73A9  # <CJK>
+0x3462 0x764C  # <CJK>
+0x3463 0x773C  # <CJK>
+0x3464 0x5CA9  # <CJK>
+0x3465 0x7FEB  # <CJK>
+0x3466 0x8D0B  # <CJK>
+0x3467 0x96C1  # <CJK>
+0x3468 0x9811  # <CJK>
+0x3469 0x9854  # <CJK>
+0x346A 0x9858  # <CJK>
+0x346B 0x4F01  # <CJK>
+0x346C 0x4F0E  # <CJK>
+0x346D 0x5371  # <CJK>
+0x346E 0x559C  # <CJK>
+0x346F 0x5668  # <CJK>
+0x3470 0x57FA  # <CJK>
+0x3471 0x5947  # <CJK>
+0x3472 0x5B09  # <CJK>
+0x3473 0x5BC4  # <CJK>
+0x3474 0x5C90  # <CJK>
+0x3475 0x5E0C  # <CJK>
+0x3476 0x5E7E  # <CJK>
+0x3477 0x5FCC  # <CJK>
+0x3478 0x63EE  # <CJK>
+0x3479 0x673A  # <CJK>
+0x347A 0x65D7  # <CJK>
+0x347B 0x65E2  # <CJK>
+0x347C 0x671F  # <CJK>
+0x347D 0x68CB  # <CJK>
+0x347E 0x68C4  # <CJK>
+0x3521 0x6A5F  # <CJK>
+0x3522 0x5E30  # <CJK>
+0x3523 0x6BC5  # <CJK>
+0x3524 0x6C17  # <CJK>
+0x3525 0x6C7D  # <CJK>
+0x3526 0x757F  # <CJK>
+0x3527 0x7948  # <CJK>
+0x3528 0x5B63  # <CJK>
+0x3529 0x7A00  # <CJK>
+0x352A 0x7D00  # <CJK>
+0x352B 0x5FBD  # <CJK>
+0x352C 0x898F  # <CJK>
+0x352D 0x8A18  # <CJK>
+0x352E 0x8CB4  # <CJK>
+0x352F 0x8D77  # <CJK>
+0x3530 0x8ECC  # <CJK>
+0x3531 0x8F1D  # <CJK>
+0x3532 0x98E2  # <CJK>
+0x3533 0x9A0E  # <CJK>
+0x3534 0x9B3C  # <CJK>
+0x3535 0x4E80  # <CJK>
+0x3536 0x507D  # <CJK>
+0x3537 0x5100  # <CJK>
+0x3538 0x5993  # <CJK>
+0x3539 0x5B9C  # <CJK>
+0x353A 0x622F  # <CJK>
+0x353B 0x6280  # <CJK>
+0x353C 0x64EC  # <CJK>
+0x353D 0x6B3A  # <CJK>
+0x353E 0x72A0  # <CJK>
+0x353F 0x7591  # <CJK>
+0x3540 0x7947  # <CJK>
+0x3541 0x7FA9  # <CJK>
+0x3542 0x87FB  # <CJK>
+0x3543 0x8ABC  # <CJK>
+0x3544 0x8B70  # <CJK>
+0x3545 0x63AC  # <CJK>
+0x3546 0x83CA  # <CJK>
+0x3547 0x97A0  # <CJK>
+0x3548 0x5409  # <CJK>
+0x3549 0x5403  # <CJK>
+0x354A 0x55AB  # <CJK>
+0x354B 0x6854  # <CJK>
+0x354C 0x6A58  # <CJK>
+0x354D 0x8A70  # <CJK>
+0x354E 0x7827  # <CJK>
+0x354F 0x6775  # <CJK>
+0x3550 0x9ECD  # <CJK>
+0x3551 0x5374  # <CJK>
+0x3552 0x5BA2  # <CJK>
+0x3553 0x811A  # <CJK>
+0x3554 0x8650  # <CJK>
+0x3555 0x9006  # <CJK>
+0x3556 0x4E18  # <CJK>
+0x3557 0x4E45  # <CJK>
+0x3558 0x4EC7  # <CJK>
+0x3559 0x4F11  # <CJK>
+0x355A 0x53CA  # <CJK>
+0x355B 0x5438  # <CJK>
+0x355C 0x5BAE  # <CJK>
+0x355D 0x5F13  # <CJK>
+0x355E 0x6025  # <CJK>
+0x355F 0x6551  # <CJK>
+0x3560 0x673D  # <CJK>
+0x3561 0x6C42  # <CJK>
+0x3562 0x6C72  # <CJK>
+0x3563 0x6CE3  # <CJK>
+0x3564 0x7078  # <CJK>
+0x3565 0x7403  # <CJK>
+0x3566 0x7A76  # <CJK>
+0x3567 0x7AAE  # <CJK>
+0x3568 0x7B08  # <CJK>
+0x3569 0x7D1A  # <CJK>
+0x356A 0x7CFE  # <CJK>
+0x356B 0x7D66  # <CJK>
+0x356C 0x65E7  # <CJK>
+0x356D 0x725B  # <CJK>
+0x356E 0x53BB  # <CJK>
+0x356F 0x5C45  # <CJK>
+0x3570 0x5DE8  # <CJK>
+0x3571 0x62D2  # <CJK>
+0x3572 0x62E0  # <CJK>
+0x3573 0x6319  # <CJK>
+0x3574 0x6E20  # <CJK>
+0x3575 0x865A  # <CJK>
+0x3576 0x8A31  # <CJK>
+0x3577 0x8DDD  # <CJK>
+0x3578 0x92F8  # <CJK>
+0x3579 0x6F01  # <CJK>
+0x357A 0x79A6  # <CJK>
+0x357B 0x9B5A  # <CJK>
+0x357C 0x4EA8  # <CJK>
+0x357D 0x4EAB  # <CJK>
+0x357E 0x4EAC  # <CJK>
+0x3621 0x4F9B  # <CJK>
+0x3622 0x4FA0  # <CJK>
+0x3623 0x50D1  # <CJK>
+0x3624 0x5147  # <CJK>
+0x3625 0x7AF6  # <CJK>
+0x3626 0x5171  # <CJK>
+0x3627 0x51F6  # <CJK>
+0x3628 0x5354  # <CJK>
+0x3629 0x5321  # <CJK>
+0x362A 0x537F  # <CJK>
+0x362B 0x53EB  # <CJK>
+0x362C 0x55AC  # <CJK>
+0x362D 0x5883  # <CJK>
+0x362E 0x5CE1  # <CJK>
+0x362F 0x5F37  # <CJK>
+0x3630 0x5F4A  # <CJK>
+0x3631 0x602F  # <CJK>
+0x3632 0x6050  # <CJK>
+0x3633 0x606D  # <CJK>
+0x3634 0x631F  # <CJK>
+0x3635 0x6559  # <CJK>
+0x3636 0x6A4B  # <CJK>
+0x3637 0x6CC1  # <CJK>
+0x3638 0x72C2  # <CJK>
+0x3639 0x72ED  # <CJK>
+0x363A 0x77EF  # <CJK>
+0x363B 0x80F8  # <CJK>
+0x363C 0x8105  # <CJK>
+0x363D 0x8208  # <CJK>
+0x363E 0x854E  # <CJK>
+0x363F 0x90F7  # <CJK>
+0x3640 0x93E1  # <CJK>
+0x3641 0x97FF  # <CJK>
+0x3642 0x9957  # <CJK>
+0x3643 0x9A5A  # <CJK>
+0x3644 0x4EF0  # <CJK>
+0x3645 0x51DD  # <CJK>
+0x3646 0x5C2D  # <CJK>
+0x3647 0x6681  # <CJK>
+0x3648 0x696D  # <CJK>
+0x3649 0x5C40  # <CJK>
+0x364A 0x66F2  # <CJK>
+0x364B 0x6975  # <CJK>
+0x364C 0x7389  # <CJK>
+0x364D 0x6850  # <CJK>
+0x364E 0x7C81  # <CJK>
+0x364F 0x50C5  # <CJK>
+0x3650 0x52E4  # <CJK>
+0x3651 0x5747  # <CJK>
+0x3652 0x5DFE  # <CJK>
+0x3653 0x9326  # <CJK>
+0x3654 0x65A4  # <CJK>
+0x3655 0x6B23  # <CJK>
+0x3656 0x6B3D  # <CJK>
+0x3657 0x7434  # <CJK>
+0x3658 0x7981  # <CJK>
+0x3659 0x79BD  # <CJK>
+0x365A 0x7B4B  # <CJK>
+0x365B 0x7DCA  # <CJK>
+0x365C 0x82B9  # <CJK>
+0x365D 0x83CC  # <CJK>
+0x365E 0x887F  # <CJK>
+0x365F 0x895F  # <CJK>
+0x3660 0x8B39  # <CJK>
+0x3661 0x8FD1  # <CJK>
+0x3662 0x91D1  # <CJK>
+0x3663 0x541F  # <CJK>
+0x3664 0x9280  # <CJK>
+0x3665 0x4E5D  # <CJK>
+0x3666 0x5036  # <CJK>
+0x3667 0x53E5  # <CJK>
+0x3668 0x533A  # <CJK>
+0x3669 0x72D7  # <CJK>
+0x366A 0x7396  # <CJK>
+0x366B 0x77E9  # <CJK>
+0x366C 0x82E6  # <CJK>
+0x366D 0x8EAF  # <CJK>
+0x366E 0x99C6  # <CJK>
+0x366F 0x99C8  # <CJK>
+0x3670 0x99D2  # <CJK>
+0x3671 0x5177  # <CJK>
+0x3672 0x611A  # <CJK>
+0x3673 0x865E  # <CJK>
+0x3674 0x55B0  # <CJK>
+0x3675 0x7A7A  # <CJK>
+0x3676 0x5076  # <CJK>
+0x3677 0x5BD3  # <CJK>
+0x3678 0x9047  # <CJK>
+0x3679 0x9685  # <CJK>
+0x367A 0x4E32  # <CJK>
+0x367B 0x6ADB  # <CJK>
+0x367C 0x91E7  # <CJK>
+0x367D 0x5C51  # <CJK>
+0x367E 0x5C48  # <CJK>
+0x3721 0x6398  # <CJK>
+0x3722 0x7A9F  # <CJK>
+0x3723 0x6C93  # <CJK>
+0x3724 0x9774  # <CJK>
+0x3725 0x8F61  # <CJK>
+0x3726 0x7AAA  # <CJK>
+0x3727 0x718A  # <CJK>
+0x3728 0x9688  # <CJK>
+0x3729 0x7C82  # <CJK>
+0x372A 0x6817  # <CJK>
+0x372B 0x7E70  # <CJK>
+0x372C 0x6851  # <CJK>
+0x372D 0x936C  # <CJK>
+0x372E 0x52F2  # <CJK>
+0x372F 0x541B  # <CJK>
+0x3730 0x85AB  # <CJK>
+0x3731 0x8A13  # <CJK>
+0x3732 0x7FA4  # <CJK>
+0x3733 0x8ECD  # <CJK>
+0x3734 0x90E1  # <CJK>
+0x3735 0x5366  # <CJK>
+0x3736 0x8888  # <CJK>
+0x3737 0x7941  # <CJK>
+0x3738 0x4FC2  # <CJK>
+0x3739 0x50BE  # <CJK>
+0x373A 0x5211  # <CJK>
+0x373B 0x5144  # <CJK>
+0x373C 0x5553  # <CJK>
+0x373D 0x572D  # <CJK>
+0x373E 0x73EA  # <CJK>
+0x373F 0x578B  # <CJK>
+0x3740 0x5951  # <CJK>
+0x3741 0x5F62  # <CJK>
+0x3742 0x5F84  # <CJK>
+0x3743 0x6075  # <CJK>
+0x3744 0x6176  # <CJK>
+0x3745 0x6167  # <CJK>
+0x3746 0x61A9  # <CJK>
+0x3747 0x63B2  # <CJK>
+0x3748 0x643A  # <CJK>
+0x3749 0x656C  # <CJK>
+0x374A 0x666F  # <CJK>
+0x374B 0x6842  # <CJK>
+0x374C 0x6E13  # <CJK>
+0x374D 0x7566  # <CJK>
+0x374E 0x7A3D  # <CJK>
+0x374F 0x7CFB  # <CJK>
+0x3750 0x7D4C  # <CJK>
+0x3751 0x7D99  # <CJK>
+0x3752 0x7E4B  # <CJK>
+0x3753 0x7F6B  # <CJK>
+0x3754 0x830E  # <CJK>
+0x3755 0x834A  # <CJK>
+0x3756 0x86CD  # <CJK>
+0x3757 0x8A08  # <CJK>
+0x3758 0x8A63  # <CJK>
+0x3759 0x8B66  # <CJK>
+0x375A 0x8EFD  # <CJK>
+0x375B 0x981A  # <CJK>
+0x375C 0x9D8F  # <CJK>
+0x375D 0x82B8  # <CJK>
+0x375E 0x8FCE  # <CJK>
+0x375F 0x9BE8  # <CJK>
+0x3760 0x5287  # <CJK>
+0x3761 0x621F  # <CJK>
+0x3762 0x6483  # <CJK>
+0x3763 0x6FC0  # <CJK>
+0x3764 0x9699  # <CJK>
+0x3765 0x6841  # <CJK>
+0x3766 0x5091  # <CJK>
+0x3767 0x6B20  # <CJK>
+0x3768 0x6C7A  # <CJK>
+0x3769 0x6F54  # <CJK>
+0x376A 0x7A74  # <CJK>
+0x376B 0x7D50  # <CJK>
+0x376C 0x8840  # <CJK>
+0x376D 0x8A23  # <CJK>
+0x376E 0x6708  # <CJK>
+0x376F 0x4EF6  # <CJK>
+0x3770 0x5039  # <CJK>
+0x3771 0x5026  # <CJK>
+0x3772 0x5065  # <CJK>
+0x3773 0x517C  # <CJK>
+0x3774 0x5238  # <CJK>
+0x3775 0x5263  # <CJK>
+0x3776 0x55A7  # <CJK>
+0x3777 0x570F  # <CJK>
+0x3778 0x5805  # <CJK>
+0x3779 0x5ACC  # <CJK>
+0x377A 0x5EFA  # <CJK>
+0x377B 0x61B2  # <CJK>
+0x377C 0x61F8  # <CJK>
+0x377D 0x62F3  # <CJK>
+0x377E 0x6372  # <CJK>
+0x3821 0x691C  # <CJK>
+0x3822 0x6A29  # <CJK>
+0x3823 0x727D  # <CJK>
+0x3824 0x72AC  # <CJK>
+0x3825 0x732E  # <CJK>
+0x3826 0x7814  # <CJK>
+0x3827 0x786F  # <CJK>
+0x3828 0x7D79  # <CJK>
+0x3829 0x770C  # <CJK>
+0x382A 0x80A9  # <CJK>
+0x382B 0x898B  # <CJK>
+0x382C 0x8B19  # <CJK>
+0x382D 0x8CE2  # <CJK>
+0x382E 0x8ED2  # <CJK>
+0x382F 0x9063  # <CJK>
+0x3830 0x9375  # <CJK>
+0x3831 0x967A  # <CJK>
+0x3832 0x9855  # <CJK>
+0x3833 0x9A13  # <CJK>
+0x3834 0x9E78  # <CJK>
+0x3835 0x5143  # <CJK>
+0x3836 0x539F  # <CJK>
+0x3837 0x53B3  # <CJK>
+0x3838 0x5E7B  # <CJK>
+0x3839 0x5F26  # <CJK>
+0x383A 0x6E1B  # <CJK>
+0x383B 0x6E90  # <CJK>
+0x383C 0x7384  # <CJK>
+0x383D 0x73FE  # <CJK>
+0x383E 0x7D43  # <CJK>
+0x383F 0x8237  # <CJK>
+0x3840 0x8A00  # <CJK>
+0x3841 0x8AFA  # <CJK>
+0x3842 0x9650  # <CJK>
+0x3843 0x4E4E  # <CJK>
+0x3844 0x500B  # <CJK>
+0x3845 0x53E4  # <CJK>
+0x3846 0x547C  # <CJK>
+0x3847 0x56FA  # <CJK>
+0x3848 0x59D1  # <CJK>
+0x3849 0x5B64  # <CJK>
+0x384A 0x5DF1  # <CJK>
+0x384B 0x5EAB  # <CJK>
+0x384C 0x5F27  # <CJK>
+0x384D 0x6238  # <CJK>
+0x384E 0x6545  # <CJK>
+0x384F 0x67AF  # <CJK>
+0x3850 0x6E56  # <CJK>
+0x3851 0x72D0  # <CJK>
+0x3852 0x7CCA  # <CJK>
+0x3853 0x88B4  # <CJK>
+0x3854 0x80A1  # <CJK>
+0x3855 0x80E1  # <CJK>
+0x3856 0x83F0  # <CJK>
+0x3857 0x864E  # <CJK>
+0x3858 0x8A87  # <CJK>
+0x3859 0x8DE8  # <CJK>
+0x385A 0x9237  # <CJK>
+0x385B 0x96C7  # <CJK>
+0x385C 0x9867  # <CJK>
+0x385D 0x9F13  # <CJK>
+0x385E 0x4E94  # <CJK>
+0x385F 0x4E92  # <CJK>
+0x3860 0x4F0D  # <CJK>
+0x3861 0x5348  # <CJK>
+0x3862 0x5449  # <CJK>
+0x3863 0x543E  # <CJK>
+0x3864 0x5A2F  # <CJK>
+0x3865 0x5F8C  # <CJK>
+0x3866 0x5FA1  # <CJK>
+0x3867 0x609F  # <CJK>
+0x3868 0x68A7  # <CJK>
+0x3869 0x6A8E  # <CJK>
+0x386A 0x745A  # <CJK>
+0x386B 0x7881  # <CJK>
+0x386C 0x8A9E  # <CJK>
+0x386D 0x8AA4  # <CJK>
+0x386E 0x8B77  # <CJK>
+0x386F 0x9190  # <CJK>
+0x3870 0x4E5E  # <CJK>
+0x3871 0x9BC9  # <CJK>
+0x3872 0x4EA4  # <CJK>
+0x3873 0x4F7C  # <CJK>
+0x3874 0x4FAF  # <CJK>
+0x3875 0x5019  # <CJK>
+0x3876 0x5016  # <CJK>
+0x3877 0x5149  # <CJK>
+0x3878 0x516C  # <CJK>
+0x3879 0x529F  # <CJK>
+0x387A 0x52B9  # <CJK>
+0x387B 0x52FE  # <CJK>
+0x387C 0x539A  # <CJK>
+0x387D 0x53E3  # <CJK>
+0x387E 0x5411  # <CJK>
+0x3921 0x540E  # <CJK>
+0x3922 0x5589  # <CJK>
+0x3923 0x5751  # <CJK>
+0x3924 0x57A2  # <CJK>
+0x3925 0x597D  # <CJK>
+0x3926 0x5B54  # <CJK>
+0x3927 0x5B5D  # <CJK>
+0x3928 0x5B8F  # <CJK>
+0x3929 0x5DE5  # <CJK>
+0x392A 0x5DE7  # <CJK>
+0x392B 0x5DF7  # <CJK>
+0x392C 0x5E78  # <CJK>
+0x392D 0x5E83  # <CJK>
+0x392E 0x5E9A  # <CJK>
+0x392F 0x5EB7  # <CJK>
+0x3930 0x5F18  # <CJK>
+0x3931 0x6052  # <CJK>
+0x3932 0x614C  # <CJK>
+0x3933 0x6297  # <CJK>
+0x3934 0x62D8  # <CJK>
+0x3935 0x63A7  # <CJK>
+0x3936 0x653B  # <CJK>
+0x3937 0x6602  # <CJK>
+0x3938 0x6643  # <CJK>
+0x3939 0x66F4  # <CJK>
+0x393A 0x676D  # <CJK>
+0x393B 0x6821  # <CJK>
+0x393C 0x6897  # <CJK>
+0x393D 0x69CB  # <CJK>
+0x393E 0x6C5F  # <CJK>
+0x393F 0x6D2A  # <CJK>
+0x3940 0x6D69  # <CJK>
+0x3941 0x6E2F  # <CJK>
+0x3942 0x6E9D  # <CJK>
+0x3943 0x7532  # <CJK>
+0x3944 0x7687  # <CJK>
+0x3945 0x786C  # <CJK>
+0x3946 0x7A3F  # <CJK>
+0x3947 0x7CE0  # <CJK>
+0x3948 0x7D05  # <CJK>
+0x3949 0x7D18  # <CJK>
+0x394A 0x7D5E  # <CJK>
+0x394B 0x7DB1  # <CJK>
+0x394C 0x8015  # <CJK>
+0x394D 0x8003  # <CJK>
+0x394E 0x80AF  # <CJK>
+0x394F 0x80B1  # <CJK>
+0x3950 0x8154  # <CJK>
+0x3951 0x818F  # <CJK>
+0x3952 0x822A  # <CJK>
+0x3953 0x8352  # <CJK>
+0x3954 0x884C  # <CJK>
+0x3955 0x8861  # <CJK>
+0x3956 0x8B1B  # <CJK>
+0x3957 0x8CA2  # <CJK>
+0x3958 0x8CFC  # <CJK>
+0x3959 0x90CA  # <CJK>
+0x395A 0x9175  # <CJK>
+0x395B 0x9271  # <CJK>
+0x395C 0x783F  # <CJK>
+0x395D 0x92FC  # <CJK>
+0x395E 0x95A4  # <CJK>
+0x395F 0x964D  # <CJK>
+0x3960 0x9805  # <CJK>
+0x3961 0x9999  # <CJK>
+0x3962 0x9AD8  # <CJK>
+0x3963 0x9D3B  # <CJK>
+0x3964 0x525B  # <CJK>
+0x3965 0x52AB  # <CJK>
+0x3966 0x53F7  # <CJK>
+0x3967 0x5408  # <CJK>
+0x3968 0x58D5  # <CJK>
+0x3969 0x62F7  # <CJK>
+0x396A 0x6FE0  # <CJK>
+0x396B 0x8C6A  # <CJK>
+0x396C 0x8F5F  # <CJK>
+0x396D 0x9EB9  # <CJK>
+0x396E 0x514B  # <CJK>
+0x396F 0x523B  # <CJK>
+0x3970 0x544A  # <CJK>
+0x3971 0x56FD  # <CJK>
+0x3972 0x7A40  # <CJK>
+0x3973 0x9177  # <CJK>
+0x3974 0x9D60  # <CJK>
+0x3975 0x9ED2  # <CJK>
+0x3976 0x7344  # <CJK>
+0x3977 0x6F09  # <CJK>
+0x3978 0x8170  # <CJK>
+0x3979 0x7511  # <CJK>
+0x397A 0x5FFD  # <CJK>
+0x397B 0x60DA  # <CJK>
+0x397C 0x9AA8  # <CJK>
+0x397D 0x72DB  # <CJK>
+0x397E 0x8FBC  # <CJK>
+0x3A21 0x6B64  # <CJK>
+0x3A22 0x9803  # <CJK>
+0x3A23 0x4ECA  # <CJK>
+0x3A24 0x56F0  # <CJK>
+0x3A25 0x5764  # <CJK>
+0x3A26 0x58BE  # <CJK>
+0x3A27 0x5A5A  # <CJK>
+0x3A28 0x6068  # <CJK>
+0x3A29 0x61C7  # <CJK>
+0x3A2A 0x660F  # <CJK>
+0x3A2B 0x6606  # <CJK>
+0x3A2C 0x6839  # <CJK>
+0x3A2D 0x68B1  # <CJK>
+0x3A2E 0x6DF7  # <CJK>
+0x3A2F 0x75D5  # <CJK>
+0x3A30 0x7D3A  # <CJK>
+0x3A31 0x826E  # <CJK>
+0x3A32 0x9B42  # <CJK>
+0x3A33 0x4E9B  # <CJK>
+0x3A34 0x4F50  # <CJK>
+0x3A35 0x53C9  # <CJK>
+0x3A36 0x5506  # <CJK>
+0x3A37 0x5D6F  # <CJK>
+0x3A38 0x5DE6  # <CJK>
+0x3A39 0x5DEE  # <CJK>
+0x3A3A 0x67FB  # <CJK>
+0x3A3B 0x6C99  # <CJK>
+0x3A3C 0x7473  # <CJK>
+0x3A3D 0x7802  # <CJK>
+0x3A3E 0x8A50  # <CJK>
+0x3A3F 0x9396  # <CJK>
+0x3A40 0x88DF  # <CJK>
+0x3A41 0x5750  # <CJK>
+0x3A42 0x5EA7  # <CJK>
+0x3A43 0x632B  # <CJK>
+0x3A44 0x50B5  # <CJK>
+0x3A45 0x50AC  # <CJK>
+0x3A46 0x518D  # <CJK>
+0x3A47 0x6700  # <CJK>
+0x3A48 0x54C9  # <CJK>
+0x3A49 0x585E  # <CJK>
+0x3A4A 0x59BB  # <CJK>
+0x3A4B 0x5BB0  # <CJK>
+0x3A4C 0x5F69  # <CJK>
+0x3A4D 0x624D  # <CJK>
+0x3A4E 0x63A1  # <CJK>
+0x3A4F 0x683D  # <CJK>
+0x3A50 0x6B73  # <CJK>
+0x3A51 0x6E08  # <CJK>
+0x3A52 0x707D  # <CJK>
+0x3A53 0x91C7  # <CJK>
+0x3A54 0x7280  # <CJK>
+0x3A55 0x7815  # <CJK>
+0x3A56 0x7826  # <CJK>
+0x3A57 0x796D  # <CJK>
+0x3A58 0x658E  # <CJK>
+0x3A59 0x7D30  # <CJK>
+0x3A5A 0x83DC  # <CJK>
+0x3A5B 0x88C1  # <CJK>
+0x3A5C 0x8F09  # <CJK>
+0x3A5D 0x969B  # <CJK>
+0x3A5E 0x5264  # <CJK>
+0x3A5F 0x5728  # <CJK>
+0x3A60 0x6750  # <CJK>
+0x3A61 0x7F6A  # <CJK>
+0x3A62 0x8CA1  # <CJK>
+0x3A63 0x51B4  # <CJK>
+0x3A64 0x5742  # <CJK>
+0x3A65 0x962A  # <CJK>
+0x3A66 0x583A  # <CJK>
+0x3A67 0x698A  # <CJK>
+0x3A68 0x80B4  # <CJK>
+0x3A69 0x54B2  # <CJK>
+0x3A6A 0x5D0E  # <CJK>
+0x3A6B 0x57FC  # <CJK>
+0x3A6C 0x7895  # <CJK>
+0x3A6D 0x9DFA  # <CJK>
+0x3A6E 0x4F5C  # <CJK>
+0x3A6F 0x524A  # <CJK>
+0x3A70 0x548B  # <CJK>
+0x3A71 0x643E  # <CJK>
+0x3A72 0x6628  # <CJK>
+0x3A73 0x6714  # <CJK>
+0x3A74 0x67F5  # <CJK>
+0x3A75 0x7A84  # <CJK>
+0x3A76 0x7B56  # <CJK>
+0x3A77 0x7D22  # <CJK>
+0x3A78 0x932F  # <CJK>
+0x3A79 0x685C  # <CJK>
+0x3A7A 0x9BAD  # <CJK>
+0x3A7B 0x7B39  # <CJK>
+0x3A7C 0x5319  # <CJK>
+0x3A7D 0x518A  # <CJK>
+0x3A7E 0x5237  # <CJK>
+0x3B21 0x5BDF  # <CJK>
+0x3B22 0x62F6  # <CJK>
+0x3B23 0x64AE  # <CJK>
+0x3B24 0x64E6  # <CJK>
+0x3B25 0x672D  # <CJK>
+0x3B26 0x6BBA  # <CJK>
+0x3B27 0x85A9  # <CJK>
+0x3B28 0x96D1  # <CJK>
+0x3B29 0x7690  # <CJK>
+0x3B2A 0x9BD6  # <CJK>
+0x3B2B 0x634C  # <CJK>
+0x3B2C 0x9306  # <CJK>
+0x3B2D 0x9BAB  # <CJK>
+0x3B2E 0x76BF  # <CJK>
+0x3B2F 0x6652  # <CJK>
+0x3B30 0x4E09  # <CJK>
+0x3B31 0x5098  # <CJK>
+0x3B32 0x53C2  # <CJK>
+0x3B33 0x5C71  # <CJK>
+0x3B34 0x60E8  # <CJK>
+0x3B35 0x6492  # <CJK>
+0x3B36 0x6563  # <CJK>
+0x3B37 0x685F  # <CJK>
+0x3B38 0x71E6  # <CJK>
+0x3B39 0x73CA  # <CJK>
+0x3B3A 0x7523  # <CJK>
+0x3B3B 0x7B97  # <CJK>
+0x3B3C 0x7E82  # <CJK>
+0x3B3D 0x8695  # <CJK>
+0x3B3E 0x8B83  # <CJK>
+0x3B3F 0x8CDB  # <CJK>
+0x3B40 0x9178  # <CJK>
+0x3B41 0x9910  # <CJK>
+0x3B42 0x65AC  # <CJK>
+0x3B43 0x66AB  # <CJK>
+0x3B44 0x6B8B  # <CJK>
+0x3B45 0x4ED5  # <CJK>
+0x3B46 0x4ED4  # <CJK>
+0x3B47 0x4F3A  # <CJK>
+0x3B48 0x4F7F  # <CJK>
+0x3B49 0x523A  # <CJK>
+0x3B4A 0x53F8  # <CJK>
+0x3B4B 0x53F2  # <CJK>
+0x3B4C 0x55E3  # <CJK>
+0x3B4D 0x56DB  # <CJK>
+0x3B4E 0x58EB  # <CJK>
+0x3B4F 0x59CB  # <CJK>
+0x3B50 0x59C9  # <CJK>
+0x3B51 0x59FF  # <CJK>
+0x3B52 0x5B50  # <CJK>
+0x3B53 0x5C4D  # <CJK>
+0x3B54 0x5E02  # <CJK>
+0x3B55 0x5E2B  # <CJK>
+0x3B56 0x5FD7  # <CJK>
+0x3B57 0x601D  # <CJK>
+0x3B58 0x6307  # <CJK>
+0x3B59 0x652F  # <CJK>
+0x3B5A 0x5B5C  # <CJK>
+0x3B5B 0x65AF  # <CJK>
+0x3B5C 0x65BD  # <CJK>
+0x3B5D 0x65E8  # <CJK>
+0x3B5E 0x679D  # <CJK>
+0x3B5F 0x6B62  # <CJK>
+0x3B60 0x6B7B  # <CJK>
+0x3B61 0x6C0F  # <CJK>
+0x3B62 0x7345  # <CJK>
+0x3B63 0x7949  # <CJK>
+0x3B64 0x79C1  # <CJK>
+0x3B65 0x7CF8  # <CJK>
+0x3B66 0x7D19  # <CJK>
+0x3B67 0x7D2B  # <CJK>
+0x3B68 0x80A2  # <CJK>
+0x3B69 0x8102  # <CJK>
+0x3B6A 0x81F3  # <CJK>
+0x3B6B 0x8996  # <CJK>
+0x3B6C 0x8A5E  # <CJK>
+0x3B6D 0x8A69  # <CJK>
+0x3B6E 0x8A66  # <CJK>
+0x3B6F 0x8A8C  # <CJK>
+0x3B70 0x8AEE  # <CJK>
+0x3B71 0x8CC7  # <CJK>
+0x3B72 0x8CDC  # <CJK>
+0x3B73 0x96CC  # <CJK>
+0x3B74 0x98FC  # <CJK>
+0x3B75 0x6B6F  # <CJK>
+0x3B76 0x4E8B  # <CJK>
+0x3B77 0x4F3C  # <CJK>
+0x3B78 0x4F8D  # <CJK>
+0x3B79 0x5150  # <CJK>
+0x3B7A 0x5B57  # <CJK>
+0x3B7B 0x5BFA  # <CJK>
+0x3B7C 0x6148  # <CJK>
+0x3B7D 0x6301  # <CJK>
+0x3B7E 0x6642  # <CJK>
+0x3C21 0x6B21  # <CJK>
+0x3C22 0x6ECB  # <CJK>
+0x3C23 0x6CBB  # <CJK>
+0x3C24 0x723E  # <CJK>
+0x3C25 0x74BD  # <CJK>
+0x3C26 0x75D4  # <CJK>
+0x3C27 0x78C1  # <CJK>
+0x3C28 0x793A  # <CJK>
+0x3C29 0x800C  # <CJK>
+0x3C2A 0x8033  # <CJK>
+0x3C2B 0x81EA  # <CJK>
+0x3C2C 0x8494  # <CJK>
+0x3C2D 0x8F9E  # <CJK>
+0x3C2E 0x6C50  # <CJK>
+0x3C2F 0x9E7F  # <CJK>
+0x3C30 0x5F0F  # <CJK>
+0x3C31 0x8B58  # <CJK>
+0x3C32 0x9D2B  # <CJK>
+0x3C33 0x7AFA  # <CJK>
+0x3C34 0x8EF8  # <CJK>
+0x3C35 0x5B8D  # <CJK>
+0x3C36 0x96EB  # <CJK>
+0x3C37 0x4E03  # <CJK>
+0x3C38 0x53F1  # <CJK>
+0x3C39 0x57F7  # <CJK>
+0x3C3A 0x5931  # <CJK>
+0x3C3B 0x5AC9  # <CJK>
+0x3C3C 0x5BA4  # <CJK>
+0x3C3D 0x6089  # <CJK>
+0x3C3E 0x6E7F  # <CJK>
+0x3C3F 0x6F06  # <CJK>
+0x3C40 0x75BE  # <CJK>
+0x3C41 0x8CEA  # <CJK>
+0x3C42 0x5B9F  # <CJK>
+0x3C43 0x8500  # <CJK>
+0x3C44 0x7BE0  # <CJK>
+0x3C45 0x5072  # <CJK>
+0x3C46 0x67F4  # <CJK>
+0x3C47 0x829D  # <CJK>
+0x3C48 0x5C61  # <CJK>
+0x3C49 0x854A  # <CJK>
+0x3C4A 0x7E1E  # <CJK>
+0x3C4B 0x820E  # <CJK>
+0x3C4C 0x5199  # <CJK>
+0x3C4D 0x5C04  # <CJK>
+0x3C4E 0x6368  # <CJK>
+0x3C4F 0x8D66  # <CJK>
+0x3C50 0x659C  # <CJK>
+0x3C51 0x716E  # <CJK>
+0x3C52 0x793E  # <CJK>
+0x3C53 0x7D17  # <CJK>
+0x3C54 0x8005  # <CJK>
+0x3C55 0x8B1D  # <CJK>
+0x3C56 0x8ECA  # <CJK>
+0x3C57 0x906E  # <CJK>
+0x3C58 0x86C7  # <CJK>
+0x3C59 0x90AA  # <CJK>
+0x3C5A 0x501F  # <CJK>
+0x3C5B 0x52FA  # <CJK>
+0x3C5C 0x5C3A  # <CJK>
+0x3C5D 0x6753  # <CJK>
+0x3C5E 0x707C  # <CJK>
+0x3C5F 0x7235  # <CJK>
+0x3C60 0x914C  # <CJK>
+0x3C61 0x91C8  # <CJK>
+0x3C62 0x932B  # <CJK>
+0x3C63 0x82E5  # <CJK>
+0x3C64 0x5BC2  # <CJK>
+0x3C65 0x5F31  # <CJK>
+0x3C66 0x60F9  # <CJK>
+0x3C67 0x4E3B  # <CJK>
+0x3C68 0x53D6  # <CJK>
+0x3C69 0x5B88  # <CJK>
+0x3C6A 0x624B  # <CJK>
+0x3C6B 0x6731  # <CJK>
+0x3C6C 0x6B8A  # <CJK>
+0x3C6D 0x72E9  # <CJK>
+0x3C6E 0x73E0  # <CJK>
+0x3C6F 0x7A2E  # <CJK>
+0x3C70 0x816B  # <CJK>
+0x3C71 0x8DA3  # <CJK>
+0x3C72 0x9152  # <CJK>
+0x3C73 0x9996  # <CJK>
+0x3C74 0x5112  # <CJK>
+0x3C75 0x53D7  # <CJK>
+0x3C76 0x546A  # <CJK>
+0x3C77 0x5BFF  # <CJK>
+0x3C78 0x6388  # <CJK>
+0x3C79 0x6A39  # <CJK>
+0x3C7A 0x7DAC  # <CJK>
+0x3C7B 0x9700  # <CJK>
+0x3C7C 0x56DA  # <CJK>
+0x3C7D 0x53CE  # <CJK>
+0x3C7E 0x5468  # <CJK>
+0x3D21 0x5B97  # <CJK>
+0x3D22 0x5C31  # <CJK>
+0x3D23 0x5DDE  # <CJK>
+0x3D24 0x4FEE  # <CJK>
+0x3D25 0x6101  # <CJK>
+0x3D26 0x62FE  # <CJK>
+0x3D27 0x6D32  # <CJK>
+0x3D28 0x79C0  # <CJK>
+0x3D29 0x79CB  # <CJK>
+0x3D2A 0x7D42  # <CJK>
+0x3D2B 0x7E4D  # <CJK>
+0x3D2C 0x7FD2  # <CJK>
+0x3D2D 0x81ED  # <CJK>
+0x3D2E 0x821F  # <CJK>
+0x3D2F 0x8490  # <CJK>
+0x3D30 0x8846  # <CJK>
+0x3D31 0x8972  # <CJK>
+0x3D32 0x8B90  # <CJK>
+0x3D33 0x8E74  # <CJK>
+0x3D34 0x8F2F  # <CJK>
+0x3D35 0x9031  # <CJK>
+0x3D36 0x914B  # <CJK>
+0x3D37 0x916C  # <CJK>
+0x3D38 0x96C6  # <CJK>
+0x3D39 0x919C  # <CJK>
+0x3D3A 0x4EC0  # <CJK>
+0x3D3B 0x4F4F  # <CJK>
+0x3D3C 0x5145  # <CJK>
+0x3D3D 0x5341  # <CJK>
+0x3D3E 0x5F93  # <CJK>
+0x3D3F 0x620E  # <CJK>
+0x3D40 0x67D4  # <CJK>
+0x3D41 0x6C41  # <CJK>
+0x3D42 0x6E0B  # <CJK>
+0x3D43 0x7363  # <CJK>
+0x3D44 0x7E26  # <CJK>
+0x3D45 0x91CD  # <CJK>
+0x3D46 0x9283  # <CJK>
+0x3D47 0x53D4  # <CJK>
+0x3D48 0x5919  # <CJK>
+0x3D49 0x5BBF  # <CJK>
+0x3D4A 0x6DD1  # <CJK>
+0x3D4B 0x795D  # <CJK>
+0x3D4C 0x7E2E  # <CJK>
+0x3D4D 0x7C9B  # <CJK>
+0x3D4E 0x587E  # <CJK>
+0x3D4F 0x719F  # <CJK>
+0x3D50 0x51FA  # <CJK>
+0x3D51 0x8853  # <CJK>
+0x3D52 0x8FF0  # <CJK>
+0x3D53 0x4FCA  # <CJK>
+0x3D54 0x5CFB  # <CJK>
+0x3D55 0x6625  # <CJK>
+0x3D56 0x77AC  # <CJK>
+0x3D57 0x7AE3  # <CJK>
+0x3D58 0x821C  # <CJK>
+0x3D59 0x99FF  # <CJK>
+0x3D5A 0x51C6  # <CJK>
+0x3D5B 0x5FAA  # <CJK>
+0x3D5C 0x65EC  # <CJK>
+0x3D5D 0x696F  # <CJK>
+0x3D5E 0x6B89  # <CJK>
+0x3D5F 0x6DF3  # <CJK>
+0x3D60 0x6E96  # <CJK>
+0x3D61 0x6F64  # <CJK>
+0x3D62 0x76FE  # <CJK>
+0x3D63 0x7D14  # <CJK>
+0x3D64 0x5DE1  # <CJK>
+0x3D65 0x9075  # <CJK>
+0x3D66 0x9187  # <CJK>
+0x3D67 0x9806  # <CJK>
+0x3D68 0x51E6  # <CJK>
+0x3D69 0x521D  # <CJK>
+0x3D6A 0x6240  # <CJK>
+0x3D6B 0x6691  # <CJK>
+0x3D6C 0x66D9  # <CJK>
+0x3D6D 0x6E1A  # <CJK>
+0x3D6E 0x5EB6  # <CJK>
+0x3D6F 0x7DD2  # <CJK>
+0x3D70 0x7F72  # <CJK>
+0x3D71 0x66F8  # <CJK>
+0x3D72 0x85AF  # <CJK>
+0x3D73 0x85F7  # <CJK>
+0x3D74 0x8AF8  # <CJK>
+0x3D75 0x52A9  # <CJK>
+0x3D76 0x53D9  # <CJK>
+0x3D77 0x5973  # <CJK>
+0x3D78 0x5E8F  # <CJK>
+0x3D79 0x5F90  # <CJK>
+0x3D7A 0x6055  # <CJK>
+0x3D7B 0x92E4  # <CJK>
+0x3D7C 0x9664  # <CJK>
+0x3D7D 0x50B7  # <CJK>
+0x3D7E 0x511F  # <CJK>
+0x3E21 0x52DD  # <CJK>
+0x3E22 0x5320  # <CJK>
+0x3E23 0x5347  # <CJK>
+0x3E24 0x53EC  # <CJK>
+0x3E25 0x54E8  # <CJK>
+0x3E26 0x5546  # <CJK>
+0x3E27 0x5531  # <CJK>
+0x3E28 0x5617  # <CJK>
+0x3E29 0x5968  # <CJK>
+0x3E2A 0x59BE  # <CJK>
+0x3E2B 0x5A3C  # <CJK>
+0x3E2C 0x5BB5  # <CJK>
+0x3E2D 0x5C06  # <CJK>
+0x3E2E 0x5C0F  # <CJK>
+0x3E2F 0x5C11  # <CJK>
+0x3E30 0x5C1A  # <CJK>
+0x3E31 0x5E84  # <CJK>
+0x3E32 0x5E8A  # <CJK>
+0x3E33 0x5EE0  # <CJK>
+0x3E34 0x5F70  # <CJK>
+0x3E35 0x627F  # <CJK>
+0x3E36 0x6284  # <CJK>
+0x3E37 0x62DB  # <CJK>
+0x3E38 0x638C  # <CJK>
+0x3E39 0x6377  # <CJK>
+0x3E3A 0x6607  # <CJK>
+0x3E3B 0x660C  # <CJK>
+0x3E3C 0x662D  # <CJK>
+0x3E3D 0x6676  # <CJK>
+0x3E3E 0x677E  # <CJK>
+0x3E3F 0x68A2  # <CJK>
+0x3E40 0x6A1F  # <CJK>
+0x3E41 0x6A35  # <CJK>
+0x3E42 0x6CBC  # <CJK>
+0x3E43 0x6D88  # <CJK>
+0x3E44 0x6E09  # <CJK>
+0x3E45 0x6E58  # <CJK>
+0x3E46 0x713C  # <CJK>
+0x3E47 0x7126  # <CJK>
+0x3E48 0x7167  # <CJK>
+0x3E49 0x75C7  # <CJK>
+0x3E4A 0x7701  # <CJK>
+0x3E4B 0x785D  # <CJK>
+0x3E4C 0x7901  # <CJK>
+0x3E4D 0x7965  # <CJK>
+0x3E4E 0x79F0  # <CJK>
+0x3E4F 0x7AE0  # <CJK>
+0x3E50 0x7B11  # <CJK>
+0x3E51 0x7CA7  # <CJK>
+0x3E52 0x7D39  # <CJK>
+0x3E53 0x8096  # <CJK>
+0x3E54 0x83D6  # <CJK>
+0x3E55 0x848B  # <CJK>
+0x3E56 0x8549  # <CJK>
+0x3E57 0x885D  # <CJK>
+0x3E58 0x88F3  # <CJK>
+0x3E59 0x8A1F  # <CJK>
+0x3E5A 0x8A3C  # <CJK>
+0x3E5B 0x8A54  # <CJK>
+0x3E5C 0x8A73  # <CJK>
+0x3E5D 0x8C61  # <CJK>
+0x3E5E 0x8CDE  # <CJK>
+0x3E5F 0x91A4  # <CJK>
+0x3E60 0x9266  # <CJK>
+0x3E61 0x937E  # <CJK>
+0x3E62 0x9418  # <CJK>
+0x3E63 0x969C  # <CJK>
+0x3E64 0x9798  # <CJK>
+0x3E65 0x4E0A  # <CJK>
+0x3E66 0x4E08  # <CJK>
+0x3E67 0x4E1E  # <CJK>
+0x3E68 0x4E57  # <CJK>
+0x3E69 0x5197  # <CJK>
+0x3E6A 0x5270  # <CJK>
+0x3E6B 0x57CE  # <CJK>
+0x3E6C 0x5834  # <CJK>
+0x3E6D 0x58CC  # <CJK>
+0x3E6E 0x5B22  # <CJK>
+0x3E6F 0x5E38  # <CJK>
+0x3E70 0x60C5  # <CJK>
+0x3E71 0x64FE  # <CJK>
+0x3E72 0x6761  # <CJK>
+0x3E73 0x6756  # <CJK>
+0x3E74 0x6D44  # <CJK>
+0x3E75 0x72B6  # <CJK>
+0x3E76 0x7573  # <CJK>
+0x3E77 0x7A63  # <CJK>
+0x3E78 0x84B8  # <CJK>
+0x3E79 0x8B72  # <CJK>
+0x3E7A 0x91B8  # <CJK>
+0x3E7B 0x9320  # <CJK>
+0x3E7C 0x5631  # <CJK>
+0x3E7D 0x57F4  # <CJK>
+0x3E7E 0x98FE  # <CJK>
+0x3F21 0x62ED  # <CJK>
+0x3F22 0x690D  # <CJK>
+0x3F23 0x6B96  # <CJK>
+0x3F24 0x71ED  # <CJK>
+0x3F25 0x7E54  # <CJK>
+0x3F26 0x8077  # <CJK>
+0x3F27 0x8272  # <CJK>
+0x3F28 0x89E6  # <CJK>
+0x3F29 0x98DF  # <CJK>
+0x3F2A 0x8755  # <CJK>
+0x3F2B 0x8FB1  # <CJK>
+0x3F2C 0x5C3B  # <CJK>
+0x3F2D 0x4F38  # <CJK>
+0x3F2E 0x4FE1  # <CJK>
+0x3F2F 0x4FB5  # <CJK>
+0x3F30 0x5507  # <CJK>
+0x3F31 0x5A20  # <CJK>
+0x3F32 0x5BDD  # <CJK>
+0x3F33 0x5BE9  # <CJK>
+0x3F34 0x5FC3  # <CJK>
+0x3F35 0x614E  # <CJK>
+0x3F36 0x632F  # <CJK>
+0x3F37 0x65B0  # <CJK>
+0x3F38 0x664B  # <CJK>
+0x3F39 0x68EE  # <CJK>
+0x3F3A 0x699B  # <CJK>
+0x3F3B 0x6D78  # <CJK>
+0x3F3C 0x6DF1  # <CJK>
+0x3F3D 0x7533  # <CJK>
+0x3F3E 0x75B9  # <CJK>
+0x3F3F 0x771F  # <CJK>
+0x3F40 0x795E  # <CJK>
+0x3F41 0x79E6  # <CJK>
+0x3F42 0x7D33  # <CJK>
+0x3F43 0x81E3  # <CJK>
+0x3F44 0x82AF  # <CJK>
+0x3F45 0x85AA  # <CJK>
+0x3F46 0x89AA  # <CJK>
+0x3F47 0x8A3A  # <CJK>
+0x3F48 0x8EAB  # <CJK>
+0x3F49 0x8F9B  # <CJK>
+0x3F4A 0x9032  # <CJK>
+0x3F4B 0x91DD  # <CJK>
+0x3F4C 0x9707  # <CJK>
+0x3F4D 0x4EBA  # <CJK>
+0x3F4E 0x4EC1  # <CJK>
+0x3F4F 0x5203  # <CJK>
+0x3F50 0x5875  # <CJK>
+0x3F51 0x58EC  # <CJK>
+0x3F52 0x5C0B  # <CJK>
+0x3F53 0x751A  # <CJK>
+0x3F54 0x5C3D  # <CJK>
+0x3F55 0x814E  # <CJK>
+0x3F56 0x8A0A  # <CJK>
+0x3F57 0x8FC5  # <CJK>
+0x3F58 0x9663  # <CJK>
+0x3F59 0x976D  # <CJK>
+0x3F5A 0x7B25  # <CJK>
+0x3F5B 0x8ACF  # <CJK>
+0x3F5C 0x9808  # <CJK>
+0x3F5D 0x9162  # <CJK>
+0x3F5E 0x56F3  # <CJK>
+0x3F5F 0x53A8  # <CJK>
+0x3F60 0x9017  # <CJK>
+0x3F61 0x5439  # <CJK>
+0x3F62 0x5782  # <CJK>
+0x3F63 0x5E25  # <CJK>
+0x3F64 0x63A8  # <CJK>
+0x3F65 0x6C34  # <CJK>
+0x3F66 0x708A  # <CJK>
+0x3F67 0x7761  # <CJK>
+0x3F68 0x7C8B  # <CJK>
+0x3F69 0x7FE0  # <CJK>
+0x3F6A 0x8870  # <CJK>
+0x3F6B 0x9042  # <CJK>
+0x3F6C 0x9154  # <CJK>
+0x3F6D 0x9310  # <CJK>
+0x3F6E 0x9318  # <CJK>
+0x3F6F 0x968F  # <CJK>
+0x3F70 0x745E  # <CJK>
+0x3F71 0x9AC4  # <CJK>
+0x3F72 0x5D07  # <CJK>
+0x3F73 0x5D69  # <CJK>
+0x3F74 0x6570  # <CJK>
+0x3F75 0x67A2  # <CJK>
+0x3F76 0x8DA8  # <CJK>
+0x3F77 0x96DB  # <CJK>
+0x3F78 0x636E  # <CJK>
+0x3F79 0x6749  # <CJK>
+0x3F7A 0x6919  # <CJK>
+0x3F7B 0x83C5  # <CJK>
+0x3F7C 0x9817  # <CJK>
+0x3F7D 0x96C0  # <CJK>
+0x3F7E 0x88FE  # <CJK>
+0x4021 0x6F84  # <CJK>
+0x4022 0x647A  # <CJK>
+0x4023 0x5BF8  # <CJK>
+0x4024 0x4E16  # <CJK>
+0x4025 0x702C  # <CJK>
+0x4026 0x755D  # <CJK>
+0x4027 0x662F  # <CJK>
+0x4028 0x51C4  # <CJK>
+0x4029 0x5236  # <CJK>
+0x402A 0x52E2  # <CJK>
+0x402B 0x59D3  # <CJK>
+0x402C 0x5F81  # <CJK>
+0x402D 0x6027  # <CJK>
+0x402E 0x6210  # <CJK>
+0x402F 0x653F  # <CJK>
+0x4030 0x6574  # <CJK>
+0x4031 0x661F  # <CJK>
+0x4032 0x6674  # <CJK>
+0x4033 0x68F2  # <CJK>
+0x4034 0x6816  # <CJK>
+0x4035 0x6B63  # <CJK>
+0x4036 0x6E05  # <CJK>
+0x4037 0x7272  # <CJK>
+0x4038 0x751F  # <CJK>
+0x4039 0x76DB  # <CJK>
+0x403A 0x7CBE  # <CJK>
+0x403B 0x8056  # <CJK>
+0x403C 0x58F0  # <CJK>
+0x403D 0x88FD  # <CJK>
+0x403E 0x897F  # <CJK>
+0x403F 0x8AA0  # <CJK>
+0x4040 0x8A93  # <CJK>
+0x4041 0x8ACB  # <CJK>
+0x4042 0x901D  # <CJK>
+0x4043 0x9192  # <CJK>
+0x4044 0x9752  # <CJK>
+0x4045 0x9759  # <CJK>
+0x4046 0x6589  # <CJK>
+0x4047 0x7A0E  # <CJK>
+0x4048 0x8106  # <CJK>
+0x4049 0x96BB  # <CJK>
+0x404A 0x5E2D  # <CJK>
+0x404B 0x60DC  # <CJK>
+0x404C 0x621A  # <CJK>
+0x404D 0x65A5  # <CJK>
+0x404E 0x6614  # <CJK>
+0x404F 0x6790  # <CJK>
+0x4050 0x77F3  # <CJK>
+0x4051 0x7A4D  # <CJK>
+0x4052 0x7C4D  # <CJK>
+0x4053 0x7E3E  # <CJK>
+0x4054 0x810A  # <CJK>
+0x4055 0x8CAC  # <CJK>
+0x4056 0x8D64  # <CJK>
+0x4057 0x8DE1  # <CJK>
+0x4058 0x8E5F  # <CJK>
+0x4059 0x78A9  # <CJK>
+0x405A 0x5207  # <CJK>
+0x405B 0x62D9  # <CJK>
+0x405C 0x63A5  # <CJK>
+0x405D 0x6442  # <CJK>
+0x405E 0x6298  # <CJK>
+0x405F 0x8A2D  # <CJK>
+0x4060 0x7A83  # <CJK>
+0x4061 0x7BC0  # <CJK>
+0x4062 0x8AAC  # <CJK>
+0x4063 0x96EA  # <CJK>
+0x4064 0x7D76  # <CJK>
+0x4065 0x820C  # <CJK>
+0x4066 0x8749  # <CJK>
+0x4067 0x4ED9  # <CJK>
+0x4068 0x5148  # <CJK>
+0x4069 0x5343  # <CJK>
+0x406A 0x5360  # <CJK>
+0x406B 0x5BA3  # <CJK>
+0x406C 0x5C02  # <CJK>
+0x406D 0x5C16  # <CJK>
+0x406E 0x5DDD  # <CJK>
+0x406F 0x6226  # <CJK>
+0x4070 0x6247  # <CJK>
+0x4071 0x64B0  # <CJK>
+0x4072 0x6813  # <CJK>
+0x4073 0x6834  # <CJK>
+0x4074 0x6CC9  # <CJK>
+0x4075 0x6D45  # <CJK>
+0x4076 0x6D17  # <CJK>
+0x4077 0x67D3  # <CJK>
+0x4078 0x6F5C  # <CJK>
+0x4079 0x714E  # <CJK>
+0x407A 0x717D  # <CJK>
+0x407B 0x65CB  # <CJK>
+0x407C 0x7A7F  # <CJK>
+0x407D 0x7BAD  # <CJK>
+0x407E 0x7DDA  # <CJK>
+0x4121 0x7E4A  # <CJK>
+0x4122 0x7FA8  # <CJK>
+0x4123 0x817A  # <CJK>
+0x4124 0x821B  # <CJK>
+0x4125 0x8239  # <CJK>
+0x4126 0x85A6  # <CJK>
+0x4127 0x8A6E  # <CJK>
+0x4128 0x8CCE  # <CJK>
+0x4129 0x8DF5  # <CJK>
+0x412A 0x9078  # <CJK>
+0x412B 0x9077  # <CJK>
+0x412C 0x92AD  # <CJK>
+0x412D 0x9291  # <CJK>
+0x412E 0x9583  # <CJK>
+0x412F 0x9BAE  # <CJK>
+0x4130 0x524D  # <CJK>
+0x4131 0x5584  # <CJK>
+0x4132 0x6F38  # <CJK>
+0x4133 0x7136  # <CJK>
+0x4134 0x5168  # <CJK>
+0x4135 0x7985  # <CJK>
+0x4136 0x7E55  # <CJK>
+0x4137 0x81B3  # <CJK>
+0x4138 0x7CCE  # <CJK>
+0x4139 0x564C  # <CJK>
+0x413A 0x5851  # <CJK>
+0x413B 0x5CA8  # <CJK>
+0x413C 0x63AA  # <CJK>
+0x413D 0x66FE  # <CJK>
+0x413E 0x66FD  # <CJK>
+0x413F 0x695A  # <CJK>
+0x4140 0x72D9  # <CJK>
+0x4141 0x758F  # <CJK>
+0x4142 0x758E  # <CJK>
+0x4143 0x790E  # <CJK>
+0x4144 0x7956  # <CJK>
+0x4145 0x79DF  # <CJK>
+0x4146 0x7C97  # <CJK>
+0x4147 0x7D20  # <CJK>
+0x4148 0x7D44  # <CJK>
+0x4149 0x8607  # <CJK>
+0x414A 0x8A34  # <CJK>
+0x414B 0x963B  # <CJK>
+0x414C 0x9061  # <CJK>
+0x414D 0x9F20  # <CJK>
+0x414E 0x50E7  # <CJK>
+0x414F 0x5275  # <CJK>
+0x4150 0x53CC  # <CJK>
+0x4151 0x53E2  # <CJK>
+0x4152 0x5009  # <CJK>
+0x4153 0x55AA  # <CJK>
+0x4154 0x58EE  # <CJK>
+0x4155 0x594F  # <CJK>
+0x4156 0x723D  # <CJK>
+0x4157 0x5B8B  # <CJK>
+0x4158 0x5C64  # <CJK>
+0x4159 0x531D  # <CJK>
+0x415A 0x60E3  # <CJK>
+0x415B 0x60F3  # <CJK>
+0x415C 0x635C  # <CJK>
+0x415D 0x6383  # <CJK>
+0x415E 0x633F  # <CJK>
+0x415F 0x63BB  # <CJK>
+0x4160 0x64CD  # <CJK>
+0x4161 0x65E9  # <CJK>
+0x4162 0x66F9  # <CJK>
+0x4163 0x5DE3  # <CJK>
+0x4164 0x69CD  # <CJK>
+0x4165 0x69FD  # <CJK>
+0x4166 0x6F15  # <CJK>
+0x4167 0x71E5  # <CJK>
+0x4168 0x4E89  # <CJK>
+0x4169 0x75E9  # <CJK>
+0x416A 0x76F8  # <CJK>
+0x416B 0x7A93  # <CJK>
+0x416C 0x7CDF  # <CJK>
+0x416D 0x7DCF  # <CJK>
+0x416E 0x7D9C  # <CJK>
+0x416F 0x8061  # <CJK>
+0x4170 0x8349  # <CJK>
+0x4171 0x8358  # <CJK>
+0x4172 0x846C  # <CJK>
+0x4173 0x84BC  # <CJK>
+0x4174 0x85FB  # <CJK>
+0x4175 0x88C5  # <CJK>
+0x4176 0x8D70  # <CJK>
+0x4177 0x9001  # <CJK>
+0x4178 0x906D  # <CJK>
+0x4179 0x9397  # <CJK>
+0x417A 0x971C  # <CJK>
+0x417B 0x9A12  # <CJK>
+0x417C 0x50CF  # <CJK>
+0x417D 0x5897  # <CJK>
+0x417E 0x618E  # <CJK>
+0x4221 0x81D3  # <CJK>
+0x4222 0x8535  # <CJK>
+0x4223 0x8D08  # <CJK>
+0x4224 0x9020  # <CJK>
+0x4225 0x4FC3  # <CJK>
+0x4226 0x5074  # <CJK>
+0x4227 0x5247  # <CJK>
+0x4228 0x5373  # <CJK>
+0x4229 0x606F  # <CJK>
+0x422A 0x6349  # <CJK>
+0x422B 0x675F  # <CJK>
+0x422C 0x6E2C  # <CJK>
+0x422D 0x8DB3  # <CJK>
+0x422E 0x901F  # <CJK>
+0x422F 0x4FD7  # <CJK>
+0x4230 0x5C5E  # <CJK>
+0x4231 0x8CCA  # <CJK>
+0x4232 0x65CF  # <CJK>
+0x4233 0x7D9A  # <CJK>
+0x4234 0x5352  # <CJK>
+0x4235 0x8896  # <CJK>
+0x4236 0x5176  # <CJK>
+0x4237 0x63C3  # <CJK>
+0x4238 0x5B58  # <CJK>
+0x4239 0x5B6B  # <CJK>
+0x423A 0x5C0A  # <CJK>
+0x423B 0x640D  # <CJK>
+0x423C 0x6751  # <CJK>
+0x423D 0x905C  # <CJK>
+0x423E 0x4ED6  # <CJK>
+0x423F 0x591A  # <CJK>
+0x4240 0x592A  # <CJK>
+0x4241 0x6C70  # <CJK>
+0x4242 0x8A51  # <CJK>
+0x4243 0x553E  # <CJK>
+0x4244 0x5815  # <CJK>
+0x4245 0x59A5  # <CJK>
+0x4246 0x60F0  # <CJK>
+0x4247 0x6253  # <CJK>
+0x4248 0x67C1  # <CJK>
+0x4249 0x8235  # <CJK>
+0x424A 0x6955  # <CJK>
+0x424B 0x9640  # <CJK>
+0x424C 0x99C4  # <CJK>
+0x424D 0x9A28  # <CJK>
+0x424E 0x4F53  # <CJK>
+0x424F 0x5806  # <CJK>
+0x4250 0x5BFE  # <CJK>
+0x4251 0x8010  # <CJK>
+0x4252 0x5CB1  # <CJK>
+0x4253 0x5E2F  # <CJK>
+0x4254 0x5F85  # <CJK>
+0x4255 0x6020  # <CJK>
+0x4256 0x614B  # <CJK>
+0x4257 0x6234  # <CJK>
+0x4258 0x66FF  # <CJK>
+0x4259 0x6CF0  # <CJK>
+0x425A 0x6EDE  # <CJK>
+0x425B 0x80CE  # <CJK>
+0x425C 0x817F  # <CJK>
+0x425D 0x82D4  # <CJK>
+0x425E 0x888B  # <CJK>
+0x425F 0x8CB8  # <CJK>
+0x4260 0x9000  # <CJK>
+0x4261 0x902E  # <CJK>
+0x4262 0x968A  # <CJK>
+0x4263 0x9EDB  # <CJK>
+0x4264 0x9BDB  # <CJK>
+0x4265 0x4EE3  # <CJK>
+0x4266 0x53F0  # <CJK>
+0x4267 0x5927  # <CJK>
+0x4268 0x7B2C  # <CJK>
+0x4269 0x918D  # <CJK>
+0x426A 0x984C  # <CJK>
+0x426B 0x9DF9  # <CJK>
+0x426C 0x6EDD  # <CJK>
+0x426D 0x7027  # <CJK>
+0x426E 0x5353  # <CJK>
+0x426F 0x5544  # <CJK>
+0x4270 0x5B85  # <CJK>
+0x4271 0x6258  # <CJK>
+0x4272 0x629E  # <CJK>
+0x4273 0x62D3  # <CJK>
+0x4274 0x6CA2  # <CJK>
+0x4275 0x6FEF  # <CJK>
+0x4276 0x7422  # <CJK>
+0x4277 0x8A17  # <CJK>
+0x4278 0x9438  # <CJK>
+0x4279 0x6FC1  # <CJK>
+0x427A 0x8AFE  # <CJK>
+0x427B 0x8338  # <CJK>
+0x427C 0x51E7  # <CJK>
+0x427D 0x86F8  # <CJK>
+0x427E 0x53EA  # <CJK>
+0x4321 0x53E9  # <CJK>
+0x4322 0x4F46  # <CJK>
+0x4323 0x9054  # <CJK>
+0x4324 0x8FB0  # <CJK>
+0x4325 0x596A  # <CJK>
+0x4326 0x8131  # <CJK>
+0x4327 0x5DFD  # <CJK>
+0x4328 0x7AEA  # <CJK>
+0x4329 0x8FBF  # <CJK>
+0x432A 0x68DA  # <CJK>
+0x432B 0x8C37  # <CJK>
+0x432C 0x72F8  # <CJK>
+0x432D 0x9C48  # <CJK>
+0x432E 0x6A3D  # <CJK>
+0x432F 0x8AB0  # <CJK>
+0x4330 0x4E39  # <CJK>
+0x4331 0x5358  # <CJK>
+0x4332 0x5606  # <CJK>
+0x4333 0x5766  # <CJK>
+0x4334 0x62C5  # <CJK>
+0x4335 0x63A2  # <CJK>
+0x4336 0x65E6  # <CJK>
+0x4337 0x6B4E  # <CJK>
+0x4338 0x6DE1  # <CJK>
+0x4339 0x6E5B  # <CJK>
+0x433A 0x70AD  # <CJK>
+0x433B 0x77ED  # <CJK>
+0x433C 0x7AEF  # <CJK>
+0x433D 0x7BAA  # <CJK>
+0x433E 0x7DBB  # <CJK>
+0x433F 0x803D  # <CJK>
+0x4340 0x80C6  # <CJK>
+0x4341 0x86CB  # <CJK>
+0x4342 0x8A95  # <CJK>
+0x4343 0x935B  # <CJK>
+0x4344 0x56E3  # <CJK>
+0x4345 0x58C7  # <CJK>
+0x4346 0x5F3E  # <CJK>
+0x4347 0x65AD  # <CJK>
+0x4348 0x6696  # <CJK>
+0x4349 0x6A80  # <CJK>
+0x434A 0x6BB5  # <CJK>
+0x434B 0x7537  # <CJK>
+0x434C 0x8AC7  # <CJK>
+0x434D 0x5024  # <CJK>
+0x434E 0x77E5  # <CJK>
+0x434F 0x5730  # <CJK>
+0x4350 0x5F1B  # <CJK>
+0x4351 0x6065  # <CJK>
+0x4352 0x667A  # <CJK>
+0x4353 0x6C60  # <CJK>
+0x4354 0x75F4  # <CJK>
+0x4355 0x7A1A  # <CJK>
+0x4356 0x7F6E  # <CJK>
+0x4357 0x81F4  # <CJK>
+0x4358 0x8718  # <CJK>
+0x4359 0x9045  # <CJK>
+0x435A 0x99B3  # <CJK>
+0x435B 0x7BC9  # <CJK>
+0x435C 0x755C  # <CJK>
+0x435D 0x7AF9  # <CJK>
+0x435E 0x7B51  # <CJK>
+0x435F 0x84C4  # <CJK>
+0x4360 0x9010  # <CJK>
+0x4361 0x79E9  # <CJK>
+0x4362 0x7A92  # <CJK>
+0x4363 0x8336  # <CJK>
+0x4364 0x5AE1  # <CJK>
+0x4365 0x7740  # <CJK>
+0x4366 0x4E2D  # <CJK>
+0x4367 0x4EF2  # <CJK>
+0x4368 0x5B99  # <CJK>
+0x4369 0x5FE0  # <CJK>
+0x436A 0x62BD  # <CJK>
+0x436B 0x663C  # <CJK>
+0x436C 0x67F1  # <CJK>
+0x436D 0x6CE8  # <CJK>
+0x436E 0x866B  # <CJK>
+0x436F 0x8877  # <CJK>
+0x4370 0x8A3B  # <CJK>
+0x4371 0x914E  # <CJK>
+0x4372 0x92F3  # <CJK>
+0x4373 0x99D0  # <CJK>
+0x4374 0x6A17  # <CJK>
+0x4375 0x7026  # <CJK>
+0x4376 0x732A  # <CJK>
+0x4377 0x82E7  # <CJK>
+0x4378 0x8457  # <CJK>
+0x4379 0x8CAF  # <CJK>
+0x437A 0x4E01  # <CJK>
+0x437B 0x5146  # <CJK>
+0x437C 0x51CB  # <CJK>
+0x437D 0x558B  # <CJK>
+0x437E 0x5BF5  # <CJK>
+0x4421 0x5E16  # <CJK>
+0x4422 0x5E33  # <CJK>
+0x4423 0x5E81  # <CJK>
+0x4424 0x5F14  # <CJK>
+0x4425 0x5F35  # <CJK>
+0x4426 0x5F6B  # <CJK>
+0x4427 0x5FB4  # <CJK>
+0x4428 0x61F2  # <CJK>
+0x4429 0x6311  # <CJK>
+0x442A 0x66A2  # <CJK>
+0x442B 0x671D  # <CJK>
+0x442C 0x6F6E  # <CJK>
+0x442D 0x7252  # <CJK>
+0x442E 0x753A  # <CJK>
+0x442F 0x773A  # <CJK>
+0x4430 0x8074  # <CJK>
+0x4431 0x8139  # <CJK>
+0x4432 0x8178  # <CJK>
+0x4433 0x8776  # <CJK>
+0x4434 0x8ABF  # <CJK>
+0x4435 0x8ADC  # <CJK>
+0x4436 0x8D85  # <CJK>
+0x4437 0x8DF3  # <CJK>
+0x4438 0x929A  # <CJK>
+0x4439 0x9577  # <CJK>
+0x443A 0x9802  # <CJK>
+0x443B 0x9CE5  # <CJK>
+0x443C 0x52C5  # <CJK>
+0x443D 0x6357  # <CJK>
+0x443E 0x76F4  # <CJK>
+0x443F 0x6715  # <CJK>
+0x4440 0x6C88  # <CJK>
+0x4441 0x73CD  # <CJK>
+0x4442 0x8CC3  # <CJK>
+0x4443 0x93AE  # <CJK>
+0x4444 0x9673  # <CJK>
+0x4445 0x6D25  # <CJK>
+0x4446 0x589C  # <CJK>
+0x4447 0x690E  # <CJK>
+0x4448 0x69CC  # <CJK>
+0x4449 0x8FFD  # <CJK>
+0x444A 0x939A  # <CJK>
+0x444B 0x75DB  # <CJK>
+0x444C 0x901A  # <CJK>
+0x444D 0x585A  # <CJK>
+0x444E 0x6802  # <CJK>
+0x444F 0x63B4  # <CJK>
+0x4450 0x69FB  # <CJK>
+0x4451 0x4F43  # <CJK>
+0x4452 0x6F2C  # <CJK>
+0x4453 0x67D8  # <CJK>
+0x4454 0x8FBB  # <CJK>
+0x4455 0x8526  # <CJK>
+0x4456 0x7DB4  # <CJK>
+0x4457 0x9354  # <CJK>
+0x4458 0x693F  # <CJK>
+0x4459 0x6F70  # <CJK>
+0x445A 0x576A  # <CJK>
+0x445B 0x58F7  # <CJK>
+0x445C 0x5B2C  # <CJK>
+0x445D 0x7D2C  # <CJK>
+0x445E 0x722A  # <CJK>
+0x445F 0x540A  # <CJK>
+0x4460 0x91E3  # <CJK>
+0x4461 0x9DB4  # <CJK>
+0x4462 0x4EAD  # <CJK>
+0x4463 0x4F4E  # <CJK>
+0x4464 0x505C  # <CJK>
+0x4465 0x5075  # <CJK>
+0x4466 0x5243  # <CJK>
+0x4467 0x8C9E  # <CJK>
+0x4468 0x5448  # <CJK>
+0x4469 0x5824  # <CJK>
+0x446A 0x5B9A  # <CJK>
+0x446B 0x5E1D  # <CJK>
+0x446C 0x5E95  # <CJK>
+0x446D 0x5EAD  # <CJK>
+0x446E 0x5EF7  # <CJK>
+0x446F 0x5F1F  # <CJK>
+0x4470 0x608C  # <CJK>
+0x4471 0x62B5  # <CJK>
+0x4472 0x633A  # <CJK>
+0x4473 0x63D0  # <CJK>
+0x4474 0x68AF  # <CJK>
+0x4475 0x6C40  # <CJK>
+0x4476 0x7887  # <CJK>
+0x4477 0x798E  # <CJK>
+0x4478 0x7A0B  # <CJK>
+0x4479 0x7DE0  # <CJK>
+0x447A 0x8247  # <CJK>
+0x447B 0x8A02  # <CJK>
+0x447C 0x8AE6  # <CJK>
+0x447D 0x8E44  # <CJK>
+0x447E 0x9013  # <CJK>
+0x4521 0x90B8  # <CJK>
+0x4522 0x912D  # <CJK>
+0x4523 0x91D8  # <CJK>
+0x4524 0x9F0E  # <CJK>
+0x4525 0x6CE5  # <CJK>
+0x4526 0x6458  # <CJK>
+0x4527 0x64E2  # <CJK>
+0x4528 0x6575  # <CJK>
+0x4529 0x6EF4  # <CJK>
+0x452A 0x7684  # <CJK>
+0x452B 0x7B1B  # <CJK>
+0x452C 0x9069  # <CJK>
+0x452D 0x93D1  # <CJK>
+0x452E 0x6EBA  # <CJK>
+0x452F 0x54F2  # <CJK>
+0x4530 0x5FB9  # <CJK>
+0x4531 0x64A4  # <CJK>
+0x4532 0x8F4D  # <CJK>
+0x4533 0x8FED  # <CJK>
+0x4534 0x9244  # <CJK>
+0x4535 0x5178  # <CJK>
+0x4536 0x586B  # <CJK>
+0x4537 0x5929  # <CJK>
+0x4538 0x5C55  # <CJK>
+0x4539 0x5E97  # <CJK>
+0x453A 0x6DFB  # <CJK>
+0x453B 0x7E8F  # <CJK>
+0x453C 0x751C  # <CJK>
+0x453D 0x8CBC  # <CJK>
+0x453E 0x8EE2  # <CJK>
+0x453F 0x985B  # <CJK>
+0x4540 0x70B9  # <CJK>
+0x4541 0x4F1D  # <CJK>
+0x4542 0x6BBF  # <CJK>
+0x4543 0x6FB1  # <CJK>
+0x4544 0x7530  # <CJK>
+0x4545 0x96FB  # <CJK>
+0x4546 0x514E  # <CJK>
+0x4547 0x5410  # <CJK>
+0x4548 0x5835  # <CJK>
+0x4549 0x5857  # <CJK>
+0x454A 0x59AC  # <CJK>
+0x454B 0x5C60  # <CJK>
+0x454C 0x5F92  # <CJK>
+0x454D 0x6597  # <CJK>
+0x454E 0x675C  # <CJK>
+0x454F 0x6E21  # <CJK>
+0x4550 0x767B  # <CJK>
+0x4551 0x83DF  # <CJK>
+0x4552 0x8CED  # <CJK>
+0x4553 0x9014  # <CJK>
+0x4554 0x90FD  # <CJK>
+0x4555 0x934D  # <CJK>
+0x4556 0x7825  # <CJK>
+0x4557 0x783A  # <CJK>
+0x4558 0x52AA  # <CJK>
+0x4559 0x5EA6  # <CJK>
+0x455A 0x571F  # <CJK>
+0x455B 0x5974  # <CJK>
+0x455C 0x6012  # <CJK>
+0x455D 0x5012  # <CJK>
+0x455E 0x515A  # <CJK>
+0x455F 0x51AC  # <CJK>
+0x4560 0x51CD  # <CJK>
+0x4561 0x5200  # <CJK>
+0x4562 0x5510  # <CJK>
+0x4563 0x5854  # <CJK>
+0x4564 0x5858  # <CJK>
+0x4565 0x5957  # <CJK>
+0x4566 0x5B95  # <CJK>
+0x4567 0x5CF6  # <CJK>
+0x4568 0x5D8B  # <CJK>
+0x4569 0x60BC  # <CJK>
+0x456A 0x6295  # <CJK>
+0x456B 0x642D  # <CJK>
+0x456C 0x6771  # <CJK>
+0x456D 0x6843  # <CJK>
+0x456E 0x68BC  # <CJK>
+0x456F 0x68DF  # <CJK>
+0x4570 0x76D7  # <CJK>
+0x4571 0x6DD8  # <CJK>
+0x4572 0x6E6F  # <CJK>
+0x4573 0x6D9B  # <CJK>
+0x4574 0x706F  # <CJK>
+0x4575 0x71C8  # <CJK>
+0x4576 0x5F53  # <CJK>
+0x4577 0x75D8  # <CJK>
+0x4578 0x7977  # <CJK>
+0x4579 0x7B49  # <CJK>
+0x457A 0x7B54  # <CJK>
+0x457B 0x7B52  # <CJK>
+0x457C 0x7CD6  # <CJK>
+0x457D 0x7D71  # <CJK>
+0x457E 0x5230  # <CJK>
+0x4621 0x8463  # <CJK>
+0x4622 0x8569  # <CJK>
+0x4623 0x85E4  # <CJK>
+0x4624 0x8A0E  # <CJK>
+0x4625 0x8B04  # <CJK>
+0x4626 0x8C46  # <CJK>
+0x4627 0x8E0F  # <CJK>
+0x4628 0x9003  # <CJK>
+0x4629 0x900F  # <CJK>
+0x462A 0x9419  # <CJK>
+0x462B 0x9676  # <CJK>
+0x462C 0x982D  # <CJK>
+0x462D 0x9A30  # <CJK>
+0x462E 0x95D8  # <CJK>
+0x462F 0x50CD  # <CJK>
+0x4630 0x52D5  # <CJK>
+0x4631 0x540C  # <CJK>
+0x4632 0x5802  # <CJK>
+0x4633 0x5C0E  # <CJK>
+0x4634 0x61A7  # <CJK>
+0x4635 0x649E  # <CJK>
+0x4636 0x6D1E  # <CJK>
+0x4637 0x77B3  # <CJK>
+0x4638 0x7AE5  # <CJK>
+0x4639 0x80F4  # <CJK>
+0x463A 0x8404  # <CJK>
+0x463B 0x9053  # <CJK>
+0x463C 0x9285  # <CJK>
+0x463D 0x5CE0  # <CJK>
+0x463E 0x9D07  # <CJK>
+0x463F 0x533F  # <CJK>
+0x4640 0x5F97  # <CJK>
+0x4641 0x5FB3  # <CJK>
+0x4642 0x6D9C  # <CJK>
+0x4643 0x7279  # <CJK>
+0x4644 0x7763  # <CJK>
+0x4645 0x79BF  # <CJK>
+0x4646 0x7BE4  # <CJK>
+0x4647 0x6BD2  # <CJK>
+0x4648 0x72EC  # <CJK>
+0x4649 0x8AAD  # <CJK>
+0x464A 0x6803  # <CJK>
+0x464B 0x6A61  # <CJK>
+0x464C 0x51F8  # <CJK>
+0x464D 0x7A81  # <CJK>
+0x464E 0x6934  # <CJK>
+0x464F 0x5C4A  # <CJK>
+0x4650 0x9CF6  # <CJK>
+0x4651 0x82EB  # <CJK>
+0x4652 0x5BC5  # <CJK>
+0x4653 0x9149  # <CJK>
+0x4654 0x701E  # <CJK>
+0x4655 0x5678  # <CJK>
+0x4656 0x5C6F  # <CJK>
+0x4657 0x60C7  # <CJK>
+0x4658 0x6566  # <CJK>
+0x4659 0x6C8C  # <CJK>
+0x465A 0x8C5A  # <CJK>
+0x465B 0x9041  # <CJK>
+0x465C 0x9813  # <CJK>
+0x465D 0x5451  # <CJK>
+0x465E 0x66C7  # <CJK>
+0x465F 0x920D  # <CJK>
+0x4660 0x5948  # <CJK>
+0x4661 0x90A3  # <CJK>
+0x4662 0x5185  # <CJK>
+0x4663 0x4E4D  # <CJK>
+0x4664 0x51EA  # <CJK>
+0x4665 0x8599  # <CJK>
+0x4666 0x8B0E  # <CJK>
+0x4667 0x7058  # <CJK>
+0x4668 0x637A  # <CJK>
+0x4669 0x934B  # <CJK>
+0x466A 0x6962  # <CJK>
+0x466B 0x99B4  # <CJK>
+0x466C 0x7E04  # <CJK>
+0x466D 0x7577  # <CJK>
+0x466E 0x5357  # <CJK>
+0x466F 0x6960  # <CJK>
+0x4670 0x8EDF  # <CJK>
+0x4671 0x96E3  # <CJK>
+0x4672 0x6C5D  # <CJK>
+0x4673 0x4E8C  # <CJK>
+0x4674 0x5C3C  # <CJK>
+0x4675 0x5F10  # <CJK>
+0x4676 0x8FE9  # <CJK>
+0x4677 0x5302  # <CJK>
+0x4678 0x8CD1  # <CJK>
+0x4679 0x8089  # <CJK>
+0x467A 0x8679  # <CJK>
+0x467B 0x5EFF  # <CJK>
+0x467C 0x65E5  # <CJK>
+0x467D 0x4E73  # <CJK>
+0x467E 0x5165  # <CJK>
+0x4721 0x5982  # <CJK>
+0x4722 0x5C3F  # <CJK>
+0x4723 0x97EE  # <CJK>
+0x4724 0x4EFB  # <CJK>
+0x4725 0x598A  # <CJK>
+0x4726 0x5FCD  # <CJK>
+0x4727 0x8A8D  # <CJK>
+0x4728 0x6FE1  # <CJK>
+0x4729 0x79B0  # <CJK>
+0x472A 0x7962  # <CJK>
+0x472B 0x5BE7  # <CJK>
+0x472C 0x8471  # <CJK>
+0x472D 0x732B  # <CJK>
+0x472E 0x71B1  # <CJK>
+0x472F 0x5E74  # <CJK>
+0x4730 0x5FF5  # <CJK>
+0x4731 0x637B  # <CJK>
+0x4732 0x649A  # <CJK>
+0x4733 0x71C3  # <CJK>
+0x4734 0x7C98  # <CJK>
+0x4735 0x4E43  # <CJK>
+0x4736 0x5EFC  # <CJK>
+0x4737 0x4E4B  # <CJK>
+0x4738 0x57DC  # <CJK>
+0x4739 0x56A2  # <CJK>
+0x473A 0x60A9  # <CJK>
+0x473B 0x6FC3  # <CJK>
+0x473C 0x7D0D  # <CJK>
+0x473D 0x80FD  # <CJK>
+0x473E 0x8133  # <CJK>
+0x473F 0x81BF  # <CJK>
+0x4740 0x8FB2  # <CJK>
+0x4741 0x8997  # <CJK>
+0x4742 0x86A4  # <CJK>
+0x4743 0x5DF4  # <CJK>
+0x4744 0x628A  # <CJK>
+0x4745 0x64AD  # <CJK>
+0x4746 0x8987  # <CJK>
+0x4747 0x6777  # <CJK>
+0x4748 0x6CE2  # <CJK>
+0x4749 0x6D3E  # <CJK>
+0x474A 0x7436  # <CJK>
+0x474B 0x7834  # <CJK>
+0x474C 0x5A46  # <CJK>
+0x474D 0x7F75  # <CJK>
+0x474E 0x82AD  # <CJK>
+0x474F 0x99AC  # <CJK>
+0x4750 0x4FF3  # <CJK>
+0x4751 0x5EC3  # <CJK>
+0x4752 0x62DD  # <CJK>
+0x4753 0x6392  # <CJK>
+0x4754 0x6557  # <CJK>
+0x4755 0x676F  # <CJK>
+0x4756 0x76C3  # <CJK>
+0x4757 0x724C  # <CJK>
+0x4758 0x80CC  # <CJK>
+0x4759 0x80BA  # <CJK>
+0x475A 0x8F29  # <CJK>
+0x475B 0x914D  # <CJK>
+0x475C 0x500D  # <CJK>
+0x475D 0x57F9  # <CJK>
+0x475E 0x5A92  # <CJK>
+0x475F 0x6885  # <CJK>
+0x4760 0x6973  # <CJK>
+0x4761 0x7164  # <CJK>
+0x4762 0x72FD  # <CJK>
+0x4763 0x8CB7  # <CJK>
+0x4764 0x58F2  # <CJK>
+0x4765 0x8CE0  # <CJK>
+0x4766 0x966A  # <CJK>
+0x4767 0x9019  # <CJK>
+0x4768 0x877F  # <CJK>
+0x4769 0x79E4  # <CJK>
+0x476A 0x77E7  # <CJK>
+0x476B 0x8429  # <CJK>
+0x476C 0x4F2F  # <CJK>
+0x476D 0x5265  # <CJK>
+0x476E 0x535A  # <CJK>
+0x476F 0x62CD  # <CJK>
+0x4770 0x67CF  # <CJK>
+0x4771 0x6CCA  # <CJK>
+0x4772 0x767D  # <CJK>
+0x4773 0x7B94  # <CJK>
+0x4774 0x7C95  # <CJK>
+0x4775 0x8236  # <CJK>
+0x4776 0x8584  # <CJK>
+0x4777 0x8FEB  # <CJK>
+0x4778 0x66DD  # <CJK>
+0x4779 0x6F20  # <CJK>
+0x477A 0x7206  # <CJK>
+0x477B 0x7E1B  # <CJK>
+0x477C 0x83AB  # <CJK>
+0x477D 0x99C1  # <CJK>
+0x477E 0x9EA6  # <CJK>
+0x4821 0x51FD  # <CJK>
+0x4822 0x7BB1  # <CJK>
+0x4823 0x7872  # <CJK>
+0x4824 0x7BB8  # <CJK>
+0x4825 0x8087  # <CJK>
+0x4826 0x7B48  # <CJK>
+0x4827 0x6AE8  # <CJK>
+0x4828 0x5E61  # <CJK>
+0x4829 0x808C  # <CJK>
+0x482A 0x7551  # <CJK>
+0x482B 0x7560  # <CJK>
+0x482C 0x516B  # <CJK>
+0x482D 0x9262  # <CJK>
+0x482E 0x6E8C  # <CJK>
+0x482F 0x767A  # <CJK>
+0x4830 0x9197  # <CJK>
+0x4831 0x9AEA  # <CJK>
+0x4832 0x4F10  # <CJK>
+0x4833 0x7F70  # <CJK>
+0x4834 0x629C  # <CJK>
+0x4835 0x7B4F  # <CJK>
+0x4836 0x95A5  # <CJK>
+0x4837 0x9CE9  # <CJK>
+0x4838 0x567A  # <CJK>
+0x4839 0x5859  # <CJK>
+0x483A 0x86E4  # <CJK>
+0x483B 0x96BC  # <CJK>
+0x483C 0x4F34  # <CJK>
+0x483D 0x5224  # <CJK>
+0x483E 0x534A  # <CJK>
+0x483F 0x53CD  # <CJK>
+0x4840 0x53DB  # <CJK>
+0x4841 0x5E06  # <CJK>
+0x4842 0x642C  # <CJK>
+0x4843 0x6591  # <CJK>
+0x4844 0x677F  # <CJK>
+0x4845 0x6C3E  # <CJK>
+0x4846 0x6C4E  # <CJK>
+0x4847 0x7248  # <CJK>
+0x4848 0x72AF  # <CJK>
+0x4849 0x73ED  # <CJK>
+0x484A 0x7554  # <CJK>
+0x484B 0x7E41  # <CJK>
+0x484C 0x822C  # <CJK>
+0x484D 0x85E9  # <CJK>
+0x484E 0x8CA9  # <CJK>
+0x484F 0x7BC4  # <CJK>
+0x4850 0x91C6  # <CJK>
+0x4851 0x7169  # <CJK>
+0x4852 0x9812  # <CJK>
+0x4853 0x98EF  # <CJK>
+0x4854 0x633D  # <CJK>
+0x4855 0x6669  # <CJK>
+0x4856 0x756A  # <CJK>
+0x4857 0x76E4  # <CJK>
+0x4858 0x78D0  # <CJK>
+0x4859 0x8543  # <CJK>
+0x485A 0x86EE  # <CJK>
+0x485B 0x532A  # <CJK>
+0x485C 0x5351  # <CJK>
+0x485D 0x5426  # <CJK>
+0x485E 0x5983  # <CJK>
+0x485F 0x5E87  # <CJK>
+0x4860 0x5F7C  # <CJK>
+0x4861 0x60B2  # <CJK>
+0x4862 0x6249  # <CJK>
+0x4863 0x6279  # <CJK>
+0x4864 0x62AB  # <CJK>
+0x4865 0x6590  # <CJK>
+0x4866 0x6BD4  # <CJK>
+0x4867 0x6CCC  # <CJK>
+0x4868 0x75B2  # <CJK>
+0x4869 0x76AE  # <CJK>
+0x486A 0x7891  # <CJK>
+0x486B 0x79D8  # <CJK>
+0x486C 0x7DCB  # <CJK>
+0x486D 0x7F77  # <CJK>
+0x486E 0x80A5  # <CJK>
+0x486F 0x88AB  # <CJK>
+0x4870 0x8AB9  # <CJK>
+0x4871 0x8CBB  # <CJK>
+0x4872 0x907F  # <CJK>
+0x4873 0x975E  # <CJK>
+0x4874 0x98DB  # <CJK>
+0x4875 0x6A0B  # <CJK>
+0x4876 0x7C38  # <CJK>
+0x4877 0x5099  # <CJK>
+0x4878 0x5C3E  # <CJK>
+0x4879 0x5FAE  # <CJK>
+0x487A 0x6787  # <CJK>
+0x487B 0x6BD8  # <CJK>
+0x487C 0x7435  # <CJK>
+0x487D 0x7709  # <CJK>
+0x487E 0x7F8E  # <CJK>
+0x4921 0x9F3B  # <CJK>
+0x4922 0x67CA  # <CJK>
+0x4923 0x7A17  # <CJK>
+0x4924 0x5339  # <CJK>
+0x4925 0x758B  # <CJK>
+0x4926 0x9AED  # <CJK>
+0x4927 0x5F66  # <CJK>
+0x4928 0x819D  # <CJK>
+0x4929 0x83F1  # <CJK>
+0x492A 0x8098  # <CJK>
+0x492B 0x5F3C  # <CJK>
+0x492C 0x5FC5  # <CJK>
+0x492D 0x7562  # <CJK>
+0x492E 0x7B46  # <CJK>
+0x492F 0x903C  # <CJK>
+0x4930 0x6867  # <CJK>
+0x4931 0x59EB  # <CJK>
+0x4932 0x5A9B  # <CJK>
+0x4933 0x7D10  # <CJK>
+0x4934 0x767E  # <CJK>
+0x4935 0x8B2C  # <CJK>
+0x4936 0x4FF5  # <CJK>
+0x4937 0x5F6A  # <CJK>
+0x4938 0x6A19  # <CJK>
+0x4939 0x6C37  # <CJK>
+0x493A 0x6F02  # <CJK>
+0x493B 0x74E2  # <CJK>
+0x493C 0x7968  # <CJK>
+0x493D 0x8868  # <CJK>
+0x493E 0x8A55  # <CJK>
+0x493F 0x8C79  # <CJK>
+0x4940 0x5EDF  # <CJK>
+0x4941 0x63CF  # <CJK>
+0x4942 0x75C5  # <CJK>
+0x4943 0x79D2  # <CJK>
+0x4944 0x82D7  # <CJK>
+0x4945 0x9328  # <CJK>
+0x4946 0x92F2  # <CJK>
+0x4947 0x849C  # <CJK>
+0x4948 0x86ED  # <CJK>
+0x4949 0x9C2D  # <CJK>
+0x494A 0x54C1  # <CJK>
+0x494B 0x5F6C  # <CJK>
+0x494C 0x658C  # <CJK>
+0x494D 0x6D5C  # <CJK>
+0x494E 0x7015  # <CJK>
+0x494F 0x8CA7  # <CJK>
+0x4950 0x8CD3  # <CJK>
+0x4951 0x983B  # <CJK>
+0x4952 0x654F  # <CJK>
+0x4953 0x74F6  # <CJK>
+0x4954 0x4E0D  # <CJK>
+0x4955 0x4ED8  # <CJK>
+0x4956 0x57E0  # <CJK>
+0x4957 0x592B  # <CJK>
+0x4958 0x5A66  # <CJK>
+0x4959 0x5BCC  # <CJK>
+0x495A 0x51A8  # <CJK>
+0x495B 0x5E03  # <CJK>
+0x495C 0x5E9C  # <CJK>
+0x495D 0x6016  # <CJK>
+0x495E 0x6276  # <CJK>
+0x495F 0x6577  # <CJK>
+0x4960 0x65A7  # <CJK>
+0x4961 0x666E  # <CJK>
+0x4962 0x6D6E  # <CJK>
+0x4963 0x7236  # <CJK>
+0x4964 0x7B26  # <CJK>
+0x4965 0x8150  # <CJK>
+0x4966 0x819A  # <CJK>
+0x4967 0x8299  # <CJK>
+0x4968 0x8B5C  # <CJK>
+0x4969 0x8CA0  # <CJK>
+0x496A 0x8CE6  # <CJK>
+0x496B 0x8D74  # <CJK>
+0x496C 0x961C  # <CJK>
+0x496D 0x9644  # <CJK>
+0x496E 0x4FAE  # <CJK>
+0x496F 0x64AB  # <CJK>
+0x4970 0x6B66  # <CJK>
+0x4971 0x821E  # <CJK>
+0x4972 0x8461  # <CJK>
+0x4973 0x856A  # <CJK>
+0x4974 0x90E8  # <CJK>
+0x4975 0x5C01  # <CJK>
+0x4976 0x6953  # <CJK>
+0x4977 0x98A8  # <CJK>
+0x4978 0x847A  # <CJK>
+0x4979 0x8557  # <CJK>
+0x497A 0x4F0F  # <CJK>
+0x497B 0x526F  # <CJK>
+0x497C 0x5FA9  # <CJK>
+0x497D 0x5E45  # <CJK>
+0x497E 0x670D  # <CJK>
+0x4A21 0x798F  # <CJK>
+0x4A22 0x8179  # <CJK>
+0x4A23 0x8907  # <CJK>
+0x4A24 0x8986  # <CJK>
+0x4A25 0x6DF5  # <CJK>
+0x4A26 0x5F17  # <CJK>
+0x4A27 0x6255  # <CJK>
+0x4A28 0x6CB8  # <CJK>
+0x4A29 0x4ECF  # <CJK>
+0x4A2A 0x7269  # <CJK>
+0x4A2B 0x9B92  # <CJK>
+0x4A2C 0x5206  # <CJK>
+0x4A2D 0x543B  # <CJK>
+0x4A2E 0x5674  # <CJK>
+0x4A2F 0x58B3  # <CJK>
+0x4A30 0x61A4  # <CJK>
+0x4A31 0x626E  # <CJK>
+0x4A32 0x711A  # <CJK>
+0x4A33 0x596E  # <CJK>
+0x4A34 0x7C89  # <CJK>
+0x4A35 0x7CDE  # <CJK>
+0x4A36 0x7D1B  # <CJK>
+0x4A37 0x96F0  # <CJK>
+0x4A38 0x6587  # <CJK>
+0x4A39 0x805E  # <CJK>
+0x4A3A 0x4E19  # <CJK>
+0x4A3B 0x4F75  # <CJK>
+0x4A3C 0x5175  # <CJK>
+0x4A3D 0x5840  # <CJK>
+0x4A3E 0x5E63  # <CJK>
+0x4A3F 0x5E73  # <CJK>
+0x4A40 0x5F0A  # <CJK>
+0x4A41 0x67C4  # <CJK>
+0x4A42 0x4E26  # <CJK>
+0x4A43 0x853D  # <CJK>
+0x4A44 0x9589  # <CJK>
+0x4A45 0x965B  # <CJK>
+0x4A46 0x7C73  # <CJK>
+0x4A47 0x9801  # <CJK>
+0x4A48 0x50FB  # <CJK>
+0x4A49 0x58C1  # <CJK>
+0x4A4A 0x7656  # <CJK>
+0x4A4B 0x78A7  # <CJK>
+0x4A4C 0x5225  # <CJK>
+0x4A4D 0x77A5  # <CJK>
+0x4A4E 0x8511  # <CJK>
+0x4A4F 0x7B86  # <CJK>
+0x4A50 0x504F  # <CJK>
+0x4A51 0x5909  # <CJK>
+0x4A52 0x7247  # <CJK>
+0x4A53 0x7BC7  # <CJK>
+0x4A54 0x7DE8  # <CJK>
+0x4A55 0x8FBA  # <CJK>
+0x4A56 0x8FD4  # <CJK>
+0x4A57 0x904D  # <CJK>
+0x4A58 0x4FBF  # <CJK>
+0x4A59 0x52C9  # <CJK>
+0x4A5A 0x5A29  # <CJK>
+0x4A5B 0x5F01  # <CJK>
+0x4A5C 0x97AD  # <CJK>
+0x4A5D 0x4FDD  # <CJK>
+0x4A5E 0x8217  # <CJK>
+0x4A5F 0x92EA  # <CJK>
+0x4A60 0x5703  # <CJK>
+0x4A61 0x6355  # <CJK>
+0x4A62 0x6B69  # <CJK>
+0x4A63 0x752B  # <CJK>
+0x4A64 0x88DC  # <CJK>
+0x4A65 0x8F14  # <CJK>
+0x4A66 0x7A42  # <CJK>
+0x4A67 0x52DF  # <CJK>
+0x4A68 0x5893  # <CJK>
+0x4A69 0x6155  # <CJK>
+0x4A6A 0x620A  # <CJK>
+0x4A6B 0x66AE  # <CJK>
+0x4A6C 0x6BCD  # <CJK>
+0x4A6D 0x7C3F  # <CJK>
+0x4A6E 0x83E9  # <CJK>
+0x4A6F 0x5023  # <CJK>
+0x4A70 0x4FF8  # <CJK>
+0x4A71 0x5305  # <CJK>
+0x4A72 0x5446  # <CJK>
+0x4A73 0x5831  # <CJK>
+0x4A74 0x5949  # <CJK>
+0x4A75 0x5B9D  # <CJK>
+0x4A76 0x5CF0  # <CJK>
+0x4A77 0x5CEF  # <CJK>
+0x4A78 0x5D29  # <CJK>
+0x4A79 0x5E96  # <CJK>
+0x4A7A 0x62B1  # <CJK>
+0x4A7B 0x6367  # <CJK>
+0x4A7C 0x653E  # <CJK>
+0x4A7D 0x65B9  # <CJK>
+0x4A7E 0x670B  # <CJK>
+0x4B21 0x6CD5  # <CJK>
+0x4B22 0x6CE1  # <CJK>
+0x4B23 0x70F9  # <CJK>
+0x4B24 0x7832  # <CJK>
+0x4B25 0x7E2B  # <CJK>
+0x4B26 0x80DE  # <CJK>
+0x4B27 0x82B3  # <CJK>
+0x4B28 0x840C  # <CJK>
+0x4B29 0x84EC  # <CJK>
+0x4B2A 0x8702  # <CJK>
+0x4B2B 0x8912  # <CJK>
+0x4B2C 0x8A2A  # <CJK>
+0x4B2D 0x8C4A  # <CJK>
+0x4B2E 0x90A6  # <CJK>
+0x4B2F 0x92D2  # <CJK>
+0x4B30 0x98FD  # <CJK>
+0x4B31 0x9CF3  # <CJK>
+0x4B32 0x9D6C  # <CJK>
+0x4B33 0x4E4F  # <CJK>
+0x4B34 0x4EA1  # <CJK>
+0x4B35 0x508D  # <CJK>
+0x4B36 0x5256  # <CJK>
+0x4B37 0x574A  # <CJK>
+0x4B38 0x59A8  # <CJK>
+0x4B39 0x5E3D  # <CJK>
+0x4B3A 0x5FD8  # <CJK>
+0x4B3B 0x5FD9  # <CJK>
+0x4B3C 0x623F  # <CJK>
+0x4B3D 0x66B4  # <CJK>
+0x4B3E 0x671B  # <CJK>
+0x4B3F 0x67D0  # <CJK>
+0x4B40 0x68D2  # <CJK>
+0x4B41 0x5192  # <CJK>
+0x4B42 0x7D21  # <CJK>
+0x4B43 0x80AA  # <CJK>
+0x4B44 0x81A8  # <CJK>
+0x4B45 0x8B00  # <CJK>
+0x4B46 0x8C8C  # <CJK>
+0x4B47 0x8CBF  # <CJK>
+0x4B48 0x927E  # <CJK>
+0x4B49 0x9632  # <CJK>
+0x4B4A 0x5420  # <CJK>
+0x4B4B 0x982C  # <CJK>
+0x4B4C 0x5317  # <CJK>
+0x4B4D 0x50D5  # <CJK>
+0x4B4E 0x535C  # <CJK>
+0x4B4F 0x58A8  # <CJK>
+0x4B50 0x64B2  # <CJK>
+0x4B51 0x6734  # <CJK>
+0x4B52 0x7267  # <CJK>
+0x4B53 0x7766  # <CJK>
+0x4B54 0x7A46  # <CJK>
+0x4B55 0x91E6  # <CJK>
+0x4B56 0x52C3  # <CJK>
+0x4B57 0x6CA1  # <CJK>
+0x4B58 0x6B86  # <CJK>
+0x4B59 0x5800  # <CJK>
+0x4B5A 0x5E4C  # <CJK>
+0x4B5B 0x5954  # <CJK>
+0x4B5C 0x672C  # <CJK>
+0x4B5D 0x7FFB  # <CJK>
+0x4B5E 0x51E1  # <CJK>
+0x4B5F 0x76C6  # <CJK>
+0x4B60 0x6469  # <CJK>
+0x4B61 0x78E8  # <CJK>
+0x4B62 0x9B54  # <CJK>
+0x4B63 0x9EBB  # <CJK>
+0x4B64 0x57CB  # <CJK>
+0x4B65 0x59B9  # <CJK>
+0x4B66 0x6627  # <CJK>
+0x4B67 0x679A  # <CJK>
+0x4B68 0x6BCE  # <CJK>
+0x4B69 0x54E9  # <CJK>
+0x4B6A 0x69D9  # <CJK>
+0x4B6B 0x5E55  # <CJK>
+0x4B6C 0x819C  # <CJK>
+0x4B6D 0x6795  # <CJK>
+0x4B6E 0x9BAA  # <CJK>
+0x4B6F 0x67FE  # <CJK>
+0x4B70 0x9C52  # <CJK>
+0x4B71 0x685D  # <CJK>
+0x4B72 0x4EA6  # <CJK>
+0x4B73 0x4FE3  # <CJK>
+0x4B74 0x53C8  # <CJK>
+0x4B75 0x62B9  # <CJK>
+0x4B76 0x672B  # <CJK>
+0x4B77 0x6CAB  # <CJK>
+0x4B78 0x8FC4  # <CJK>
+0x4B79 0x4FAD  # <CJK>
+0x4B7A 0x7E6D  # <CJK>
+0x4B7B 0x9EBF  # <CJK>
+0x4B7C 0x4E07  # <CJK>
+0x4B7D 0x6162  # <CJK>
+0x4B7E 0x6E80  # <CJK>
+0x4C21 0x6F2B  # <CJK>
+0x4C22 0x8513  # <CJK>
+0x4C23 0x5473  # <CJK>
+0x4C24 0x672A  # <CJK>
+0x4C25 0x9B45  # <CJK>
+0x4C26 0x5DF3  # <CJK>
+0x4C27 0x7B95  # <CJK>
+0x4C28 0x5CAC  # <CJK>
+0x4C29 0x5BC6  # <CJK>
+0x4C2A 0x871C  # <CJK>
+0x4C2B 0x6E4A  # <CJK>
+0x4C2C 0x84D1  # <CJK>
+0x4C2D 0x7A14  # <CJK>
+0x4C2E 0x8108  # <CJK>
+0x4C2F 0x5999  # <CJK>
+0x4C30 0x7C8D  # <CJK>
+0x4C31 0x6C11  # <CJK>
+0x4C32 0x7720  # <CJK>
+0x4C33 0x52D9  # <CJK>
+0x4C34 0x5922  # <CJK>
+0x4C35 0x7121  # <CJK>
+0x4C36 0x725F  # <CJK>
+0x4C37 0x77DB  # <CJK>
+0x4C38 0x9727  # <CJK>
+0x4C39 0x9D61  # <CJK>
+0x4C3A 0x690B  # <CJK>
+0x4C3B 0x5A7F  # <CJK>
+0x4C3C 0x5A18  # <CJK>
+0x4C3D 0x51A5  # <CJK>
+0x4C3E 0x540D  # <CJK>
+0x4C3F 0x547D  # <CJK>
+0x4C40 0x660E  # <CJK>
+0x4C41 0x76DF  # <CJK>
+0x4C42 0x8FF7  # <CJK>
+0x4C43 0x9298  # <CJK>
+0x4C44 0x9CF4  # <CJK>
+0x4C45 0x59EA  # <CJK>
+0x4C46 0x725D  # <CJK>
+0x4C47 0x6EC5  # <CJK>
+0x4C48 0x514D  # <CJK>
+0x4C49 0x68C9  # <CJK>
+0x4C4A 0x7DBF  # <CJK>
+0x4C4B 0x7DEC  # <CJK>
+0x4C4C 0x9762  # <CJK>
+0x4C4D 0x9EBA  # <CJK>
+0x4C4E 0x6478  # <CJK>
+0x4C4F 0x6A21  # <CJK>
+0x4C50 0x8302  # <CJK>
+0x4C51 0x5984  # <CJK>
+0x4C52 0x5B5F  # <CJK>
+0x4C53 0x6BDB  # <CJK>
+0x4C54 0x731B  # <CJK>
+0x4C55 0x76F2  # <CJK>
+0x4C56 0x7DB2  # <CJK>
+0x4C57 0x8017  # <CJK>
+0x4C58 0x8499  # <CJK>
+0x4C59 0x5132  # <CJK>
+0x4C5A 0x6728  # <CJK>
+0x4C5B 0x9ED9  # <CJK>
+0x4C5C 0x76EE  # <CJK>
+0x4C5D 0x6762  # <CJK>
+0x4C5E 0x52FF  # <CJK>
+0x4C5F 0x9905  # <CJK>
+0x4C60 0x5C24  # <CJK>
+0x4C61 0x623B  # <CJK>
+0x4C62 0x7C7E  # <CJK>
+0x4C63 0x8CB0  # <CJK>
+0x4C64 0x554F  # <CJK>
+0x4C65 0x60B6  # <CJK>
+0x4C66 0x7D0B  # <CJK>
+0x4C67 0x9580  # <CJK>
+0x4C68 0x5301  # <CJK>
+0x4C69 0x4E5F  # <CJK>
+0x4C6A 0x51B6  # <CJK>
+0x4C6B 0x591C  # <CJK>
+0x4C6C 0x723A  # <CJK>
+0x4C6D 0x8036  # <CJK>
+0x4C6E 0x91CE  # <CJK>
+0x4C6F 0x5F25  # <CJK>
+0x4C70 0x77E2  # <CJK>
+0x4C71 0x5384  # <CJK>
+0x4C72 0x5F79  # <CJK>
+0x4C73 0x7D04  # <CJK>
+0x4C74 0x85AC  # <CJK>
+0x4C75 0x8A33  # <CJK>
+0x4C76 0x8E8D  # <CJK>
+0x4C77 0x9756  # <CJK>
+0x4C78 0x67F3  # <CJK>
+0x4C79 0x85AE  # <CJK>
+0x4C7A 0x9453  # <CJK>
+0x4C7B 0x6109  # <CJK>
+0x4C7C 0x6108  # <CJK>
+0x4C7D 0x6CB9  # <CJK>
+0x4C7E 0x7652  # <CJK>
+0x4D21 0x8AED  # <CJK>
+0x4D22 0x8F38  # <CJK>
+0x4D23 0x552F  # <CJK>
+0x4D24 0x4F51  # <CJK>
+0x4D25 0x512A  # <CJK>
+0x4D26 0x52C7  # <CJK>
+0x4D27 0x53CB  # <CJK>
+0x4D28 0x5BA5  # <CJK>
+0x4D29 0x5E7D  # <CJK>
+0x4D2A 0x60A0  # <CJK>
+0x4D2B 0x6182  # <CJK>
+0x4D2C 0x63D6  # <CJK>
+0x4D2D 0x6709  # <CJK>
+0x4D2E 0x67DA  # <CJK>
+0x4D2F 0x6E67  # <CJK>
+0x4D30 0x6D8C  # <CJK>
+0x4D31 0x7336  # <CJK>
+0x4D32 0x7337  # <CJK>
+0x4D33 0x7531  # <CJK>
+0x4D34 0x7950  # <CJK>
+0x4D35 0x88D5  # <CJK>
+0x4D36 0x8A98  # <CJK>
+0x4D37 0x904A  # <CJK>
+0x4D38 0x9091  # <CJK>
+0x4D39 0x90F5  # <CJK>
+0x4D3A 0x96C4  # <CJK>
+0x4D3B 0x878D  # <CJK>
+0x4D3C 0x5915  # <CJK>
+0x4D3D 0x4E88  # <CJK>
+0x4D3E 0x4F59  # <CJK>
+0x4D3F 0x4E0E  # <CJK>
+0x4D40 0x8A89  # <CJK>
+0x4D41 0x8F3F  # <CJK>
+0x4D42 0x9810  # <CJK>
+0x4D43 0x50AD  # <CJK>
+0x4D44 0x5E7C  # <CJK>
+0x4D45 0x5996  # <CJK>
+0x4D46 0x5BB9  # <CJK>
+0x4D47 0x5EB8  # <CJK>
+0x4D48 0x63DA  # <CJK>
+0x4D49 0x63FA  # <CJK>
+0x4D4A 0x64C1  # <CJK>
+0x4D4B 0x66DC  # <CJK>
+0x4D4C 0x694A  # <CJK>
+0x4D4D 0x69D8  # <CJK>
+0x4D4E 0x6D0B  # <CJK>
+0x4D4F 0x6EB6  # <CJK>
+0x4D50 0x7194  # <CJK>
+0x4D51 0x7528  # <CJK>
+0x4D52 0x7AAF  # <CJK>
+0x4D53 0x7F8A  # <CJK>
+0x4D54 0x8000  # <CJK>
+0x4D55 0x8449  # <CJK>
+0x4D56 0x84C9  # <CJK>
+0x4D57 0x8981  # <CJK>
+0x4D58 0x8B21  # <CJK>
+0x4D59 0x8E0A  # <CJK>
+0x4D5A 0x9065  # <CJK>
+0x4D5B 0x967D  # <CJK>
+0x4D5C 0x990A  # <CJK>
+0x4D5D 0x617E  # <CJK>
+0x4D5E 0x6291  # <CJK>
+0x4D5F 0x6B32  # <CJK>
+0x4D60 0x6C83  # <CJK>
+0x4D61 0x6D74  # <CJK>
+0x4D62 0x7FCC  # <CJK>
+0x4D63 0x7FFC  # <CJK>
+0x4D64 0x6DC0  # <CJK>
+0x4D65 0x7F85  # <CJK>
+0x4D66 0x87BA  # <CJK>
+0x4D67 0x88F8  # <CJK>
+0x4D68 0x6765  # <CJK>
+0x4D69 0x83B1  # <CJK>
+0x4D6A 0x983C  # <CJK>
+0x4D6B 0x96F7  # <CJK>
+0x4D6C 0x6D1B  # <CJK>
+0x4D6D 0x7D61  # <CJK>
+0x4D6E 0x843D  # <CJK>
+0x4D6F 0x916A  # <CJK>
+0x4D70 0x4E71  # <CJK>
+0x4D71 0x5375  # <CJK>
+0x4D72 0x5D50  # <CJK>
+0x4D73 0x6B04  # <CJK>
+0x4D74 0x6FEB  # <CJK>
+0x4D75 0x85CD  # <CJK>
+0x4D76 0x862D  # <CJK>
+0x4D77 0x89A7  # <CJK>
+0x4D78 0x5229  # <CJK>
+0x4D79 0x540F  # <CJK>
+0x4D7A 0x5C65  # <CJK>
+0x4D7B 0x674E  # <CJK>
+0x4D7C 0x68A8  # <CJK>
+0x4D7D 0x7406  # <CJK>
+0x4D7E 0x7483  # <CJK>
+0x4E21 0x75E2  # <CJK>
+0x4E22 0x88CF  # <CJK>
+0x4E23 0x88E1  # <CJK>
+0x4E24 0x91CC  # <CJK>
+0x4E25 0x96E2  # <CJK>
+0x4E26 0x9678  # <CJK>
+0x4E27 0x5F8B  # <CJK>
+0x4E28 0x7387  # <CJK>
+0x4E29 0x7ACB  # <CJK>
+0x4E2A 0x844E  # <CJK>
+0x4E2B 0x63A0  # <CJK>
+0x4E2C 0x7565  # <CJK>
+0x4E2D 0x5289  # <CJK>
+0x4E2E 0x6D41  # <CJK>
+0x4E2F 0x6E9C  # <CJK>
+0x4E30 0x7409  # <CJK>
+0x4E31 0x7559  # <CJK>
+0x4E32 0x786B  # <CJK>
+0x4E33 0x7C92  # <CJK>
+0x4E34 0x9686  # <CJK>
+0x4E35 0x7ADC  # <CJK>
+0x4E36 0x9F8D  # <CJK>
+0x4E37 0x4FB6  # <CJK>
+0x4E38 0x616E  # <CJK>
+0x4E39 0x65C5  # <CJK>
+0x4E3A 0x865C  # <CJK>
+0x4E3B 0x4E86  # <CJK>
+0x4E3C 0x4EAE  # <CJK>
+0x4E3D 0x50DA  # <CJK>
+0x4E3E 0x4E21  # <CJK>
+0x4E3F 0x51CC  # <CJK>
+0x4E40 0x5BEE  # <CJK>
+0x4E41 0x6599  # <CJK>
+0x4E42 0x6881  # <CJK>
+0x4E43 0x6DBC  # <CJK>
+0x4E44 0x731F  # <CJK>
+0x4E45 0x7642  # <CJK>
+0x4E46 0x77AD  # <CJK>
+0x4E47 0x7A1C  # <CJK>
+0x4E48 0x7CE7  # <CJK>
+0x4E49 0x826F  # <CJK>
+0x4E4A 0x8AD2  # <CJK>
+0x4E4B 0x907C  # <CJK>
+0x4E4C 0x91CF  # <CJK>
+0x4E4D 0x9675  # <CJK>
+0x4E4E 0x9818  # <CJK>
+0x4E4F 0x529B  # <CJK>
+0x4E50 0x7DD1  # <CJK>
+0x4E51 0x502B  # <CJK>
+0x4E52 0x5398  # <CJK>
+0x4E53 0x6797  # <CJK>
+0x4E54 0x6DCB  # <CJK>
+0x4E55 0x71D0  # <CJK>
+0x4E56 0x7433  # <CJK>
+0x4E57 0x81E8  # <CJK>
+0x4E58 0x8F2A  # <CJK>
+0x4E59 0x96A3  # <CJK>
+0x4E5A 0x9C57  # <CJK>
+0x4E5B 0x9E9F  # <CJK>
+0x4E5C 0x7460  # <CJK>
+0x4E5D 0x5841  # <CJK>
+0x4E5E 0x6D99  # <CJK>
+0x4E5F 0x7D2F  # <CJK>
+0x4E60 0x985E  # <CJK>
+0x4E61 0x4EE4  # <CJK>
+0x4E62 0x4F36  # <CJK>
+0x4E63 0x4F8B  # <CJK>
+0x4E64 0x51B7  # <CJK>
+0x4E65 0x52B1  # <CJK>
+0x4E66 0x5DBA  # <CJK>
+0x4E67 0x601C  # <CJK>
+0x4E68 0x73B2  # <CJK>
+0x4E69 0x793C  # <CJK>
+0x4E6A 0x82D3  # <CJK>
+0x4E6B 0x9234  # <CJK>
+0x4E6C 0x96B7  # <CJK>
+0x4E6D 0x96F6  # <CJK>
+0x4E6E 0x970A  # <CJK>
+0x4E6F 0x9E97  # <CJK>
+0x4E70 0x9F62  # <CJK>
+0x4E71 0x66A6  # <CJK>
+0x4E72 0x6B74  # <CJK>
+0x4E73 0x5217  # <CJK>
+0x4E74 0x52A3  # <CJK>
+0x4E75 0x70C8  # <CJK>
+0x4E76 0x88C2  # <CJK>
+0x4E77 0x5EC9  # <CJK>
+0x4E78 0x604B  # <CJK>
+0x4E79 0x6190  # <CJK>
+0x4E7A 0x6F23  # <CJK>
+0x4E7B 0x7149  # <CJK>
+0x4E7C 0x7C3E  # <CJK>
+0x4E7D 0x7DF4  # <CJK>
+0x4E7E 0x806F  # <CJK>
+0x4F21 0x84EE  # <CJK>
+0x4F22 0x9023  # <CJK>
+0x4F23 0x932C  # <CJK>
+0x4F24 0x5442  # <CJK>
+0x4F25 0x9B6F  # <CJK>
+0x4F26 0x6AD3  # <CJK>
+0x4F27 0x7089  # <CJK>
+0x4F28 0x8CC2  # <CJK>
+0x4F29 0x8DEF  # <CJK>
+0x4F2A 0x9732  # <CJK>
+0x4F2B 0x52B4  # <CJK>
+0x4F2C 0x5A41  # <CJK>
+0x4F2D 0x5ECA  # <CJK>
+0x4F2E 0x5F04  # <CJK>
+0x4F2F 0x6717  # <CJK>
+0x4F30 0x697C  # <CJK>
+0x4F31 0x6994  # <CJK>
+0x4F32 0x6D6A  # <CJK>
+0x4F33 0x6F0F  # <CJK>
+0x4F34 0x7262  # <CJK>
+0x4F35 0x72FC  # <CJK>
+0x4F36 0x7BED  # <CJK>
+0x4F37 0x8001  # <CJK>
+0x4F38 0x807E  # <CJK>
+0x4F39 0x874B  # <CJK>
+0x4F3A 0x90CE  # <CJK>
+0x4F3B 0x516D  # <CJK>
+0x4F3C 0x9E93  # <CJK>
+0x4F3D 0x7984  # <CJK>
+0x4F3E 0x808B  # <CJK>
+0x4F3F 0x9332  # <CJK>
+0x4F40 0x8AD6  # <CJK>
+0x4F41 0x502D  # <CJK>
+0x4F42 0x548C  # <CJK>
+0x4F43 0x8A71  # <CJK>
+0x4F44 0x6B6A  # <CJK>
+0x4F45 0x8CC4  # <CJK>
+0x4F46 0x8107  # <CJK>
+0x4F47 0x60D1  # <CJK>
+0x4F48 0x67A0  # <CJK>
+0x4F49 0x9DF2  # <CJK>
+0x4F4A 0x4E99  # <CJK>
+0x4F4B 0x4E98  # <CJK>
+0x4F4C 0x9C10  # <CJK>
+0x4F4D 0x8A6B  # <CJK>
+0x4F4E 0x85C1  # <CJK>
+0x4F4F 0x8568  # <CJK>
+0x4F50 0x6900  # <CJK>
+0x4F51 0x6E7E  # <CJK>
+0x4F52 0x7897  # <CJK>
+0x4F53 0x8155  # <CJK>
+0x5021 0x5F0C  # <CJK>
+0x5022 0x4E10  # <CJK>
+0x5023 0x4E15  # <CJK>
+0x5024 0x4E2A  # <CJK>
+0x5025 0x4E31  # <CJK>
+0x5026 0x4E36  # <CJK>
+0x5027 0x4E3C  # <CJK>
+0x5028 0x4E3F  # <CJK>
+0x5029 0x4E42  # <CJK>
+0x502A 0x4E56  # <CJK>
+0x502B 0x4E58  # <CJK>
+0x502C 0x4E82  # <CJK>
+0x502D 0x4E85  # <CJK>
+0x502E 0x8C6B  # <CJK>
+0x502F 0x4E8A  # <CJK>
+0x5030 0x8212  # <CJK>
+0x5031 0x5F0D  # <CJK>
+0x5032 0x4E8E  # <CJK>
+0x5033 0x4E9E  # <CJK>
+0x5034 0x4E9F  # <CJK>
+0x5035 0x4EA0  # <CJK>
+0x5036 0x4EA2  # <CJK>
+0x5037 0x4EB0  # <CJK>
+0x5038 0x4EB3  # <CJK>
+0x5039 0x4EB6  # <CJK>
+0x503A 0x4ECE  # <CJK>
+0x503B 0x4ECD  # <CJK>
+0x503C 0x4EC4  # <CJK>
+0x503D 0x4EC6  # <CJK>
+0x503E 0x4EC2  # <CJK>
+0x503F 0x4ED7  # <CJK>
+0x5040 0x4EDE  # <CJK>
+0x5041 0x4EED  # <CJK>
+0x5042 0x4EDF  # <CJK>
+0x5043 0x4EF7  # <CJK>
+0x5044 0x4F09  # <CJK>
+0x5045 0x4F5A  # <CJK>
+0x5046 0x4F30  # <CJK>
+0x5047 0x4F5B  # <CJK>
+0x5048 0x4F5D  # <CJK>
+0x5049 0x4F57  # <CJK>
+0x504A 0x4F47  # <CJK>
+0x504B 0x4F76  # <CJK>
+0x504C 0x4F88  # <CJK>
+0x504D 0x4F8F  # <CJK>
+0x504E 0x4F98  # <CJK>
+0x504F 0x4F7B  # <CJK>
+0x5050 0x4F69  # <CJK>
+0x5051 0x4F70  # <CJK>
+0x5052 0x4F91  # <CJK>
+0x5053 0x4F6F  # <CJK>
+0x5054 0x4F86  # <CJK>
+0x5055 0x4F96  # <CJK>
+0x5056 0x5118  # <CJK>
+0x5057 0x4FD4  # <CJK>
+0x5058 0x4FDF  # <CJK>
+0x5059 0x4FCE  # <CJK>
+0x505A 0x4FD8  # <CJK>
+0x505B 0x4FDB  # <CJK>
+0x505C 0x4FD1  # <CJK>
+0x505D 0x4FDA  # <CJK>
+0x505E 0x4FD0  # <CJK>
+0x505F 0x4FE4  # <CJK>
+0x5060 0x4FE5  # <CJK>
+0x5061 0x501A  # <CJK>
+0x5062 0x5028  # <CJK>
+0x5063 0x5014  # <CJK>
+0x5064 0x502A  # <CJK>
+0x5065 0x5025  # <CJK>
+0x5066 0x5005  # <CJK>
+0x5067 0x4F1C  # <CJK>
+0x5068 0x4FF6  # <CJK>
+0x5069 0x5021  # <CJK>
+0x506A 0x5029  # <CJK>
+0x506B 0x502C  # <CJK>
+0x506C 0x4FFE  # <CJK>
+0x506D 0x4FEF  # <CJK>
+0x506E 0x5011  # <CJK>
+0x506F 0x5006  # <CJK>
+0x5070 0x5043  # <CJK>
+0x5071 0x5047  # <CJK>
+0x5072 0x6703  # <CJK>
+0x5073 0x5055  # <CJK>
+0x5074 0x5050  # <CJK>
+0x5075 0x5048  # <CJK>
+0x5076 0x505A  # <CJK>
+0x5077 0x5056  # <CJK>
+0x5078 0x506C  # <CJK>
+0x5079 0x5078  # <CJK>
+0x507A 0x5080  # <CJK>
+0x507B 0x509A  # <CJK>
+0x507C 0x5085  # <CJK>
+0x507D 0x50B4  # <CJK>
+0x507E 0x50B2  # <CJK>
+0x5121 0x50C9  # <CJK>
+0x5122 0x50CA  # <CJK>
+0x5123 0x50B3  # <CJK>
+0x5124 0x50C2  # <CJK>
+0x5125 0x50D6  # <CJK>
+0x5126 0x50DE  # <CJK>
+0x5127 0x50E5  # <CJK>
+0x5128 0x50ED  # <CJK>
+0x5129 0x50E3  # <CJK>
+0x512A 0x50EE  # <CJK>
+0x512B 0x50F9  # <CJK>
+0x512C 0x50F5  # <CJK>
+0x512D 0x5109  # <CJK>
+0x512E 0x5101  # <CJK>
+0x512F 0x5102  # <CJK>
+0x5130 0x5116  # <CJK>
+0x5131 0x5115  # <CJK>
+0x5132 0x5114  # <CJK>
+0x5133 0x511A  # <CJK>
+0x5134 0x5121  # <CJK>
+0x5135 0x513A  # <CJK>
+0x5136 0x5137  # <CJK>
+0x5137 0x513C  # <CJK>
+0x5138 0x513B  # <CJK>
+0x5139 0x513F  # <CJK>
+0x513A 0x5140  # <CJK>
+0x513B 0x5152  # <CJK>
+0x513C 0x514C  # <CJK>
+0x513D 0x5154  # <CJK>
+0x513E 0x5162  # <CJK>
+0x513F 0x7AF8  # <CJK>
+0x5140 0x5169  # <CJK>
+0x5141 0x516A  # <CJK>
+0x5142 0x516E  # <CJK>
+0x5143 0x5180  # <CJK>
+0x5144 0x5182  # <CJK>
+0x5145 0x56D8  # <CJK>
+0x5146 0x518C  # <CJK>
+0x5147 0x5189  # <CJK>
+0x5148 0x518F  # <CJK>
+0x5149 0x5191  # <CJK>
+0x514A 0x5193  # <CJK>
+0x514B 0x5195  # <CJK>
+0x514C 0x5196  # <CJK>
+0x514D 0x51A4  # <CJK>
+0x514E 0x51A6  # <CJK>
+0x514F 0x51A2  # <CJK>
+0x5150 0x51A9  # <CJK>
+0x5151 0x51AA  # <CJK>
+0x5152 0x51AB  # <CJK>
+0x5153 0x51B3  # <CJK>
+0x5154 0x51B1  # <CJK>
+0x5155 0x51B2  # <CJK>
+0x5156 0x51B0  # <CJK>
+0x5157 0x51B5  # <CJK>
+0x5158 0x51BD  # <CJK>
+0x5159 0x51C5  # <CJK>
+0x515A 0x51C9  # <CJK>
+0x515B 0x51DB  # <CJK>
+0x515C 0x51E0  # <CJK>
+0x515D 0x8655  # <CJK>
+0x515E 0x51E9  # <CJK>
+0x515F 0x51ED  # <CJK>
+0x5160 0x51F0  # <CJK>
+0x5161 0x51F5  # <CJK>
+0x5162 0x51FE  # <CJK>
+0x5163 0x5204  # <CJK>
+0x5164 0x520B  # <CJK>
+0x5165 0x5214  # <CJK>
+0x5166 0x520E  # <CJK>
+0x5167 0x5227  # <CJK>
+0x5168 0x522A  # <CJK>
+0x5169 0x522E  # <CJK>
+0x516A 0x5233  # <CJK>
+0x516B 0x5239  # <CJK>
+0x516C 0x524F  # <CJK>
+0x516D 0x5244  # <CJK>
+0x516E 0x524B  # <CJK>
+0x516F 0x524C  # <CJK>
+0x5170 0x525E  # <CJK>
+0x5171 0x5254  # <CJK>
+0x5172 0x526A  # <CJK>
+0x5173 0x5274  # <CJK>
+0x5174 0x5269  # <CJK>
+0x5175 0x5273  # <CJK>
+0x5176 0x527F  # <CJK>
+0x5177 0x527D  # <CJK>
+0x5178 0x528D  # <CJK>
+0x5179 0x5294  # <CJK>
+0x517A 0x5292  # <CJK>
+0x517B 0x5271  # <CJK>
+0x517C 0x5288  # <CJK>
+0x517D 0x5291  # <CJK>
+0x517E 0x8FA8  # <CJK>
+0x5221 0x8FA7  # <CJK>
+0x5222 0x52AC  # <CJK>
+0x5223 0x52AD  # <CJK>
+0x5224 0x52BC  # <CJK>
+0x5225 0x52B5  # <CJK>
+0x5226 0x52C1  # <CJK>
+0x5227 0x52CD  # <CJK>
+0x5228 0x52D7  # <CJK>
+0x5229 0x52DE  # <CJK>
+0x522A 0x52E3  # <CJK>
+0x522B 0x52E6  # <CJK>
+0x522C 0x98ED  # <CJK>
+0x522D 0x52E0  # <CJK>
+0x522E 0x52F3  # <CJK>
+0x522F 0x52F5  # <CJK>
+0x5230 0x52F8  # <CJK>
+0x5231 0x52F9  # <CJK>
+0x5232 0x5306  # <CJK>
+0x5233 0x5308  # <CJK>
+0x5234 0x7538  # <CJK>
+0x5235 0x530D  # <CJK>
+0x5236 0x5310  # <CJK>
+0x5237 0x530F  # <CJK>
+0x5238 0x5315  # <CJK>
+0x5239 0x531A  # <CJK>
+0x523A 0x5323  # <CJK>
+0x523B 0x532F  # <CJK>
+0x523C 0x5331  # <CJK>
+0x523D 0x5333  # <CJK>
+0x523E 0x5338  # <CJK>
+0x523F 0x5340  # <CJK>
+0x5240 0x5346  # <CJK>
+0x5241 0x5345  # <CJK>
+0x5242 0x4E17  # <CJK>
+0x5243 0x5349  # <CJK>
+0x5244 0x534D  # <CJK>
+0x5245 0x51D6  # <CJK>
+0x5246 0x535E  # <CJK>
+0x5247 0x5369  # <CJK>
+0x5248 0x536E  # <CJK>
+0x5249 0x5918  # <CJK>
+0x524A 0x537B  # <CJK>
+0x524B 0x5377  # <CJK>
+0x524C 0x5382  # <CJK>
+0x524D 0x5396  # <CJK>
+0x524E 0x53A0  # <CJK>
+0x524F 0x53A6  # <CJK>
+0x5250 0x53A5  # <CJK>
+0x5251 0x53AE  # <CJK>
+0x5252 0x53B0  # <CJK>
+0x5253 0x53B6  # <CJK>
+0x5254 0x53C3  # <CJK>
+0x5255 0x7C12  # <CJK>
+0x5256 0x96D9  # <CJK>
+0x5257 0x53DF  # <CJK>
+0x5258 0x66FC  # <CJK>
+0x5259 0x71EE  # <CJK>
+0x525A 0x53EE  # <CJK>
+0x525B 0x53E8  # <CJK>
+0x525C 0x53ED  # <CJK>
+0x525D 0x53FA  # <CJK>
+0x525E 0x5401  # <CJK>
+0x525F 0x543D  # <CJK>
+0x5260 0x5440  # <CJK>
+0x5261 0x542C  # <CJK>
+0x5262 0x542D  # <CJK>
+0x5263 0x543C  # <CJK>
+0x5264 0x542E  # <CJK>
+0x5265 0x5436  # <CJK>
+0x5266 0x5429  # <CJK>
+0x5267 0x541D  # <CJK>
+0x5268 0x544E  # <CJK>
+0x5269 0x548F  # <CJK>
+0x526A 0x5475  # <CJK>
+0x526B 0x548E  # <CJK>
+0x526C 0x545F  # <CJK>
+0x526D 0x5471  # <CJK>
+0x526E 0x5477  # <CJK>
+0x526F 0x5470  # <CJK>
+0x5270 0x5492  # <CJK>
+0x5271 0x547B  # <CJK>
+0x5272 0x5480  # <CJK>
+0x5273 0x5476  # <CJK>
+0x5274 0x5484  # <CJK>
+0x5275 0x5490  # <CJK>
+0x5276 0x5486  # <CJK>
+0x5277 0x54C7  # <CJK>
+0x5278 0x54A2  # <CJK>
+0x5279 0x54B8  # <CJK>
+0x527A 0x54A5  # <CJK>
+0x527B 0x54AC  # <CJK>
+0x527C 0x54C4  # <CJK>
+0x527D 0x54C8  # <CJK>
+0x527E 0x54A8  # <CJK>
+0x5321 0x54AB  # <CJK>
+0x5322 0x54C2  # <CJK>
+0x5323 0x54A4  # <CJK>
+0x5324 0x54BE  # <CJK>
+0x5325 0x54BC  # <CJK>
+0x5326 0x54D8  # <CJK>
+0x5327 0x54E5  # <CJK>
+0x5328 0x54E6  # <CJK>
+0x5329 0x550F  # <CJK>
+0x532A 0x5514  # <CJK>
+0x532B 0x54FD  # <CJK>
+0x532C 0x54EE  # <CJK>
+0x532D 0x54ED  # <CJK>
+0x532E 0x54FA  # <CJK>
+0x532F 0x54E2  # <CJK>
+0x5330 0x5539  # <CJK>
+0x5331 0x5540  # <CJK>
+0x5332 0x5563  # <CJK>
+0x5333 0x554C  # <CJK>
+0x5334 0x552E  # <CJK>
+0x5335 0x555C  # <CJK>
+0x5336 0x5545  # <CJK>
+0x5337 0x5556  # <CJK>
+0x5338 0x5557  # <CJK>
+0x5339 0x5538  # <CJK>
+0x533A 0x5533  # <CJK>
+0x533B 0x555D  # <CJK>
+0x533C 0x5599  # <CJK>
+0x533D 0x5580  # <CJK>
+0x533E 0x54AF  # <CJK>
+0x533F 0x558A  # <CJK>
+0x5340 0x559F  # <CJK>
+0x5341 0x557B  # <CJK>
+0x5342 0x557E  # <CJK>
+0x5343 0x5598  # <CJK>
+0x5344 0x559E  # <CJK>
+0x5345 0x55AE  # <CJK>
+0x5346 0x557C  # <CJK>
+0x5347 0x5583  # <CJK>
+0x5348 0x55A9  # <CJK>
+0x5349 0x5587  # <CJK>
+0x534A 0x55A8  # <CJK>
+0x534B 0x55DA  # <CJK>
+0x534C 0x55C5  # <CJK>
+0x534D 0x55DF  # <CJK>
+0x534E 0x55C4  # <CJK>
+0x534F 0x55DC  # <CJK>
+0x5350 0x55E4  # <CJK>
+0x5351 0x55D4  # <CJK>
+0x5352 0x5614  # <CJK>
+0x5353 0x55F7  # <CJK>
+0x5354 0x5616  # <CJK>
+0x5355 0x55FE  # <CJK>
+0x5356 0x55FD  # <CJK>
+0x5357 0x561B  # <CJK>
+0x5358 0x55F9  # <CJK>
+0x5359 0x564E  # <CJK>
+0x535A 0x5650  # <CJK>
+0x535B 0x71DF  # <CJK>
+0x535C 0x5634  # <CJK>
+0x535D 0x5636  # <CJK>
+0x535E 0x5632  # <CJK>
+0x535F 0x5638  # <CJK>
+0x5360 0x566B  # <CJK>
+0x5361 0x5664  # <CJK>
+0x5362 0x562F  # <CJK>
+0x5363 0x566C  # <CJK>
+0x5364 0x566A  # <CJK>
+0x5365 0x5686  # <CJK>
+0x5366 0x5680  # <CJK>
+0x5367 0x568A  # <CJK>
+0x5368 0x56A0  # <CJK>
+0x5369 0x5694  # <CJK>
+0x536A 0x568F  # <CJK>
+0x536B 0x56A5  # <CJK>
+0x536C 0x56AE  # <CJK>
+0x536D 0x56B6  # <CJK>
+0x536E 0x56B4  # <CJK>
+0x536F 0x56C2  # <CJK>
+0x5370 0x56BC  # <CJK>
+0x5371 0x56C1  # <CJK>
+0x5372 0x56C3  # <CJK>
+0x5373 0x56C0  # <CJK>
+0x5374 0x56C8  # <CJK>
+0x5375 0x56CE  # <CJK>
+0x5376 0x56D1  # <CJK>
+0x5377 0x56D3  # <CJK>
+0x5378 0x56D7  # <CJK>
+0x5379 0x56EE  # <CJK>
+0x537A 0x56F9  # <CJK>
+0x537B 0x5700  # <CJK>
+0x537C 0x56FF  # <CJK>
+0x537D 0x5704  # <CJK>
+0x537E 0x5709  # <CJK>
+0x5421 0x5708  # <CJK>
+0x5422 0x570B  # <CJK>
+0x5423 0x570D  # <CJK>
+0x5424 0x5713  # <CJK>
+0x5425 0x5718  # <CJK>
+0x5426 0x5716  # <CJK>
+0x5427 0x55C7  # <CJK>
+0x5428 0x571C  # <CJK>
+0x5429 0x5726  # <CJK>
+0x542A 0x5737  # <CJK>
+0x542B 0x5738  # <CJK>
+0x542C 0x574E  # <CJK>
+0x542D 0x573B  # <CJK>
+0x542E 0x5740  # <CJK>
+0x542F 0x574F  # <CJK>
+0x5430 0x5769  # <CJK>
+0x5431 0x57C0  # <CJK>
+0x5432 0x5788  # <CJK>
+0x5433 0x5761  # <CJK>
+0x5434 0x577F  # <CJK>
+0x5435 0x5789  # <CJK>
+0x5436 0x5793  # <CJK>
+0x5437 0x57A0  # <CJK>
+0x5438 0x57B3  # <CJK>
+0x5439 0x57A4  # <CJK>
+0x543A 0x57AA  # <CJK>
+0x543B 0x57B0  # <CJK>
+0x543C 0x57C3  # <CJK>
+0x543D 0x57C6  # <CJK>
+0x543E 0x57D4  # <CJK>
+0x543F 0x57D2  # <CJK>
+0x5440 0x57D3  # <CJK>
+0x5441 0x580A  # <CJK>
+0x5442 0x57D6  # <CJK>
+0x5443 0x57E3  # <CJK>
+0x5444 0x580B  # <CJK>
+0x5445 0x5819  # <CJK>
+0x5446 0x581D  # <CJK>
+0x5447 0x5872  # <CJK>
+0x5448 0x5821  # <CJK>
+0x5449 0x5862  # <CJK>
+0x544A 0x584B  # <CJK>
+0x544B 0x5870  # <CJK>
+0x544C 0x6BC0  # <CJK>
+0x544D 0x5852  # <CJK>
+0x544E 0x583D  # <CJK>
+0x544F 0x5879  # <CJK>
+0x5450 0x5885  # <CJK>
+0x5451 0x58B9  # <CJK>
+0x5452 0x589F  # <CJK>
+0x5453 0x58AB  # <CJK>
+0x5454 0x58BA  # <CJK>
+0x5455 0x58DE  # <CJK>
+0x5456 0x58BB  # <CJK>
+0x5457 0x58B8  # <CJK>
+0x5458 0x58AE  # <CJK>
+0x5459 0x58C5  # <CJK>
+0x545A 0x58D3  # <CJK>
+0x545B 0x58D1  # <CJK>
+0x545C 0x58D7  # <CJK>
+0x545D 0x58D9  # <CJK>
+0x545E 0x58D8  # <CJK>
+0x545F 0x58E5  # <CJK>
+0x5460 0x58DC  # <CJK>
+0x5461 0x58E4  # <CJK>
+0x5462 0x58DF  # <CJK>
+0x5463 0x58EF  # <CJK>
+0x5464 0x58FA  # <CJK>
+0x5465 0x58F9  # <CJK>
+0x5466 0x58FB  # <CJK>
+0x5467 0x58FC  # <CJK>
+0x5468 0x58FD  # <CJK>
+0x5469 0x5902  # <CJK>
+0x546A 0x590A  # <CJK>
+0x546B 0x5910  # <CJK>
+0x546C 0x591B  # <CJK>
+0x546D 0x68A6  # <CJK>
+0x546E 0x5925  # <CJK>
+0x546F 0x592C  # <CJK>
+0x5470 0x592D  # <CJK>
+0x5471 0x5932  # <CJK>
+0x5472 0x5938  # <CJK>
+0x5473 0x593E  # <CJK>
+0x5474 0x7AD2  # <CJK>
+0x5475 0x5955  # <CJK>
+0x5476 0x5950  # <CJK>
+0x5477 0x594E  # <CJK>
+0x5478 0x595A  # <CJK>
+0x5479 0x5958  # <CJK>
+0x547A 0x5962  # <CJK>
+0x547B 0x5960  # <CJK>
+0x547C 0x5967  # <CJK>
+0x547D 0x596C  # <CJK>
+0x547E 0x5969  # <CJK>
+0x5521 0x5978  # <CJK>
+0x5522 0x5981  # <CJK>
+0x5523 0x599D  # <CJK>
+0x5524 0x4F5E  # <CJK>
+0x5525 0x4FAB  # <CJK>
+0x5526 0x59A3  # <CJK>
+0x5527 0x59B2  # <CJK>
+0x5528 0x59C6  # <CJK>
+0x5529 0x59E8  # <CJK>
+0x552A 0x59DC  # <CJK>
+0x552B 0x598D  # <CJK>
+0x552C 0x59D9  # <CJK>
+0x552D 0x59DA  # <CJK>
+0x552E 0x5A25  # <CJK>
+0x552F 0x5A1F  # <CJK>
+0x5530 0x5A11  # <CJK>
+0x5531 0x5A1C  # <CJK>
+0x5532 0x5A09  # <CJK>
+0x5533 0x5A1A  # <CJK>
+0x5534 0x5A40  # <CJK>
+0x5535 0x5A6C  # <CJK>
+0x5536 0x5A49  # <CJK>
+0x5537 0x5A35  # <CJK>
+0x5538 0x5A36  # <CJK>
+0x5539 0x5A62  # <CJK>
+0x553A 0x5A6A  # <CJK>
+0x553B 0x5A9A  # <CJK>
+0x553C 0x5ABC  # <CJK>
+0x553D 0x5ABE  # <CJK>
+0x553E 0x5ACB  # <CJK>
+0x553F 0x5AC2  # <CJK>
+0x5540 0x5ABD  # <CJK>
+0x5541 0x5AE3  # <CJK>
+0x5542 0x5AD7  # <CJK>
+0x5543 0x5AE6  # <CJK>
+0x5544 0x5AE9  # <CJK>
+0x5545 0x5AD6  # <CJK>
+0x5546 0x5AFA  # <CJK>
+0x5547 0x5AFB  # <CJK>
+0x5548 0x5B0C  # <CJK>
+0x5549 0x5B0B  # <CJK>
+0x554A 0x5B16  # <CJK>
+0x554B 0x5B32  # <CJK>
+0x554C 0x5AD0  # <CJK>
+0x554D 0x5B2A  # <CJK>
+0x554E 0x5B36  # <CJK>
+0x554F 0x5B3E  # <CJK>
+0x5550 0x5B43  # <CJK>
+0x5551 0x5B45  # <CJK>
+0x5552 0x5B40  # <CJK>
+0x5553 0x5B51  # <CJK>
+0x5554 0x5B55  # <CJK>
+0x5555 0x5B5A  # <CJK>
+0x5556 0x5B5B  # <CJK>
+0x5557 0x5B65  # <CJK>
+0x5558 0x5B69  # <CJK>
+0x5559 0x5B70  # <CJK>
+0x555A 0x5B73  # <CJK>
+0x555B 0x5B75  # <CJK>
+0x555C 0x5B78  # <CJK>
+0x555D 0x6588  # <CJK>
+0x555E 0x5B7A  # <CJK>
+0x555F 0x5B80  # <CJK>
+0x5560 0x5B83  # <CJK>
+0x5561 0x5BA6  # <CJK>
+0x5562 0x5BB8  # <CJK>
+0x5563 0x5BC3  # <CJK>
+0x5564 0x5BC7  # <CJK>
+0x5565 0x5BC9  # <CJK>
+0x5566 0x5BD4  # <CJK>
+0x5567 0x5BD0  # <CJK>
+0x5568 0x5BE4  # <CJK>
+0x5569 0x5BE6  # <CJK>
+0x556A 0x5BE2  # <CJK>
+0x556B 0x5BDE  # <CJK>
+0x556C 0x5BE5  # <CJK>
+0x556D 0x5BEB  # <CJK>
+0x556E 0x5BF0  # <CJK>
+0x556F 0x5BF6  # <CJK>
+0x5570 0x5BF3  # <CJK>
+0x5571 0x5C05  # <CJK>
+0x5572 0x5C07  # <CJK>
+0x5573 0x5C08  # <CJK>
+0x5574 0x5C0D  # <CJK>
+0x5575 0x5C13  # <CJK>
+0x5576 0x5C20  # <CJK>
+0x5577 0x5C22  # <CJK>
+0x5578 0x5C28  # <CJK>
+0x5579 0x5C38  # <CJK>
+0x557A 0x5C39  # <CJK>
+0x557B 0x5C41  # <CJK>
+0x557C 0x5C46  # <CJK>
+0x557D 0x5C4E  # <CJK>
+0x557E 0x5C53  # <CJK>
+0x5621 0x5C50  # <CJK>
+0x5622 0x5C4F  # <CJK>
+0x5623 0x5B71  # <CJK>
+0x5624 0x5C6C  # <CJK>
+0x5625 0x5C6E  # <CJK>
+0x5626 0x4E62  # <CJK>
+0x5627 0x5C76  # <CJK>
+0x5628 0x5C79  # <CJK>
+0x5629 0x5C8C  # <CJK>
+0x562A 0x5C91  # <CJK>
+0x562B 0x5C94  # <CJK>
+0x562C 0x599B  # <CJK>
+0x562D 0x5CAB  # <CJK>
+0x562E 0x5CBB  # <CJK>
+0x562F 0x5CB6  # <CJK>
+0x5630 0x5CBC  # <CJK>
+0x5631 0x5CB7  # <CJK>
+0x5632 0x5CC5  # <CJK>
+0x5633 0x5CBE  # <CJK>
+0x5634 0x5CC7  # <CJK>
+0x5635 0x5CD9  # <CJK>
+0x5636 0x5CE9  # <CJK>
+0x5637 0x5CFD  # <CJK>
+0x5638 0x5CFA  # <CJK>
+0x5639 0x5CED  # <CJK>
+0x563A 0x5D8C  # <CJK>
+0x563B 0x5CEA  # <CJK>
+0x563C 0x5D0B  # <CJK>
+0x563D 0x5D15  # <CJK>
+0x563E 0x5D17  # <CJK>
+0x563F 0x5D5C  # <CJK>
+0x5640 0x5D1F  # <CJK>
+0x5641 0x5D1B  # <CJK>
+0x5642 0x5D11  # <CJK>
+0x5643 0x5D14  # <CJK>
+0x5644 0x5D22  # <CJK>
+0x5645 0x5D1A  # <CJK>
+0x5646 0x5D19  # <CJK>
+0x5647 0x5D18  # <CJK>
+0x5648 0x5D4C  # <CJK>
+0x5649 0x5D52  # <CJK>
+0x564A 0x5D4E  # <CJK>
+0x564B 0x5D4B  # <CJK>
+0x564C 0x5D6C  # <CJK>
+0x564D 0x5D73  # <CJK>
+0x564E 0x5D76  # <CJK>
+0x564F 0x5D87  # <CJK>
+0x5650 0x5D84  # <CJK>
+0x5651 0x5D82  # <CJK>
+0x5652 0x5DA2  # <CJK>
+0x5653 0x5D9D  # <CJK>
+0x5654 0x5DAC  # <CJK>
+0x5655 0x5DAE  # <CJK>
+0x5656 0x5DBD  # <CJK>
+0x5657 0x5D90  # <CJK>
+0x5658 0x5DB7  # <CJK>
+0x5659 0x5DBC  # <CJK>
+0x565A 0x5DC9  # <CJK>
+0x565B 0x5DCD  # <CJK>
+0x565C 0x5DD3  # <CJK>
+0x565D 0x5DD2  # <CJK>
+0x565E 0x5DD6  # <CJK>
+0x565F 0x5DDB  # <CJK>
+0x5660 0x5DEB  # <CJK>
+0x5661 0x5DF2  # <CJK>
+0x5662 0x5DF5  # <CJK>
+0x5663 0x5E0B  # <CJK>
+0x5664 0x5E1A  # <CJK>
+0x5665 0x5E19  # <CJK>
+0x5666 0x5E11  # <CJK>
+0x5667 0x5E1B  # <CJK>
+0x5668 0x5E36  # <CJK>
+0x5669 0x5E37  # <CJK>
+0x566A 0x5E44  # <CJK>
+0x566B 0x5E43  # <CJK>
+0x566C 0x5E40  # <CJK>
+0x566D 0x5E4E  # <CJK>
+0x566E 0x5E57  # <CJK>
+0x566F 0x5E54  # <CJK>
+0x5670 0x5E5F  # <CJK>
+0x5671 0x5E62  # <CJK>
+0x5672 0x5E64  # <CJK>
+0x5673 0x5E47  # <CJK>
+0x5674 0x5E75  # <CJK>
+0x5675 0x5E76  # <CJK>
+0x5676 0x5E7A  # <CJK>
+0x5677 0x9EBC  # <CJK>
+0x5678 0x5E7F  # <CJK>
+0x5679 0x5EA0  # <CJK>
+0x567A 0x5EC1  # <CJK>
+0x567B 0x5EC2  # <CJK>
+0x567C 0x5EC8  # <CJK>
+0x567D 0x5ED0  # <CJK>
+0x567E 0x5ECF  # <CJK>
+0x5721 0x5ED6  # <CJK>
+0x5722 0x5EE3  # <CJK>
+0x5723 0x5EDD  # <CJK>
+0x5724 0x5EDA  # <CJK>
+0x5725 0x5EDB  # <CJK>
+0x5726 0x5EE2  # <CJK>
+0x5727 0x5EE1  # <CJK>
+0x5728 0x5EE8  # <CJK>
+0x5729 0x5EE9  # <CJK>
+0x572A 0x5EEC  # <CJK>
+0x572B 0x5EF1  # <CJK>
+0x572C 0x5EF3  # <CJK>
+0x572D 0x5EF0  # <CJK>
+0x572E 0x5EF4  # <CJK>
+0x572F 0x5EF8  # <CJK>
+0x5730 0x5EFE  # <CJK>
+0x5731 0x5F03  # <CJK>
+0x5732 0x5F09  # <CJK>
+0x5733 0x5F5D  # <CJK>
+0x5734 0x5F5C  # <CJK>
+0x5735 0x5F0B  # <CJK>
+0x5736 0x5F11  # <CJK>
+0x5737 0x5F16  # <CJK>
+0x5738 0x5F29  # <CJK>
+0x5739 0x5F2D  # <CJK>
+0x573A 0x5F38  # <CJK>
+0x573B 0x5F41  # <CJK>
+0x573C 0x5F48  # <CJK>
+0x573D 0x5F4C  # <CJK>
+0x573E 0x5F4E  # <CJK>
+0x573F 0x5F2F  # <CJK>
+0x5740 0x5F51  # <CJK>
+0x5741 0x5F56  # <CJK>
+0x5742 0x5F57  # <CJK>
+0x5743 0x5F59  # <CJK>
+0x5744 0x5F61  # <CJK>
+0x5745 0x5F6D  # <CJK>
+0x5746 0x5F73  # <CJK>
+0x5747 0x5F77  # <CJK>
+0x5748 0x5F83  # <CJK>
+0x5749 0x5F82  # <CJK>
+0x574A 0x5F7F  # <CJK>
+0x574B 0x5F8A  # <CJK>
+0x574C 0x5F88  # <CJK>
+0x574D 0x5F91  # <CJK>
+0x574E 0x5F87  # <CJK>
+0x574F 0x5F9E  # <CJK>
+0x5750 0x5F99  # <CJK>
+0x5751 0x5F98  # <CJK>
+0x5752 0x5FA0  # <CJK>
+0x5753 0x5FA8  # <CJK>
+0x5754 0x5FAD  # <CJK>
+0x5755 0x5FBC  # <CJK>
+0x5756 0x5FD6  # <CJK>
+0x5757 0x5FFB  # <CJK>
+0x5758 0x5FE4  # <CJK>
+0x5759 0x5FF8  # <CJK>
+0x575A 0x5FF1  # <CJK>
+0x575B 0x5FDD  # <CJK>
+0x575C 0x60B3  # <CJK>
+0x575D 0x5FFF  # <CJK>
+0x575E 0x6021  # <CJK>
+0x575F 0x6060  # <CJK>
+0x5760 0x6019  # <CJK>
+0x5761 0x6010  # <CJK>
+0x5762 0x6029  # <CJK>
+0x5763 0x600E  # <CJK>
+0x5764 0x6031  # <CJK>
+0x5765 0x601B  # <CJK>
+0x5766 0x6015  # <CJK>
+0x5767 0x602B  # <CJK>
+0x5768 0x6026  # <CJK>
+0x5769 0x600F  # <CJK>
+0x576A 0x603A  # <CJK>
+0x576B 0x605A  # <CJK>
+0x576C 0x6041  # <CJK>
+0x576D 0x606A  # <CJK>
+0x576E 0x6077  # <CJK>
+0x576F 0x605F  # <CJK>
+0x5770 0x604A  # <CJK>
+0x5771 0x6046  # <CJK>
+0x5772 0x604D  # <CJK>
+0x5773 0x6063  # <CJK>
+0x5774 0x6043  # <CJK>
+0x5775 0x6064  # <CJK>
+0x5776 0x6042  # <CJK>
+0x5777 0x606C  # <CJK>
+0x5778 0x606B  # <CJK>
+0x5779 0x6059  # <CJK>
+0x577A 0x6081  # <CJK>
+0x577B 0x608D  # <CJK>
+0x577C 0x60E7  # <CJK>
+0x577D 0x6083  # <CJK>
+0x577E 0x609A  # <CJK>
+0x5821 0x6084  # <CJK>
+0x5822 0x609B  # <CJK>
+0x5823 0x6096  # <CJK>
+0x5824 0x6097  # <CJK>
+0x5825 0x6092  # <CJK>
+0x5826 0x60A7  # <CJK>
+0x5827 0x608B  # <CJK>
+0x5828 0x60E1  # <CJK>
+0x5829 0x60B8  # <CJK>
+0x582A 0x60E0  # <CJK>
+0x582B 0x60D3  # <CJK>
+0x582C 0x60B4  # <CJK>
+0x582D 0x5FF0  # <CJK>
+0x582E 0x60BD  # <CJK>
+0x582F 0x60C6  # <CJK>
+0x5830 0x60B5  # <CJK>
+0x5831 0x60D8  # <CJK>
+0x5832 0x614D  # <CJK>
+0x5833 0x6115  # <CJK>
+0x5834 0x6106  # <CJK>
+0x5835 0x60F6  # <CJK>
+0x5836 0x60F7  # <CJK>
+0x5837 0x6100  # <CJK>
+0x5838 0x60F4  # <CJK>
+0x5839 0x60FA  # <CJK>
+0x583A 0x6103  # <CJK>
+0x583B 0x6121  # <CJK>
+0x583C 0x60FB  # <CJK>
+0x583D 0x60F1  # <CJK>
+0x583E 0x610D  # <CJK>
+0x583F 0x610E  # <CJK>
+0x5840 0x6147  # <CJK>
+0x5841 0x613E  # <CJK>
+0x5842 0x6128  # <CJK>
+0x5843 0x6127  # <CJK>
+0x5844 0x614A  # <CJK>
+0x5845 0x613F  # <CJK>
+0x5846 0x613C  # <CJK>
+0x5847 0x612C  # <CJK>
+0x5848 0x6134  # <CJK>
+0x5849 0x613D  # <CJK>
+0x584A 0x6142  # <CJK>
+0x584B 0x6144  # <CJK>
+0x584C 0x6173  # <CJK>
+0x584D 0x6177  # <CJK>
+0x584E 0x6158  # <CJK>
+0x584F 0x6159  # <CJK>
+0x5850 0x615A  # <CJK>
+0x5851 0x616B  # <CJK>
+0x5852 0x6174  # <CJK>
+0x5853 0x616F  # <CJK>
+0x5854 0x6165  # <CJK>
+0x5855 0x6171  # <CJK>
+0x5856 0x615F  # <CJK>
+0x5857 0x615D  # <CJK>
+0x5858 0x6153  # <CJK>
+0x5859 0x6175  # <CJK>
+0x585A 0x6199  # <CJK>
+0x585B 0x6196  # <CJK>
+0x585C 0x6187  # <CJK>
+0x585D 0x61AC  # <CJK>
+0x585E 0x6194  # <CJK>
+0x585F 0x619A  # <CJK>
+0x5860 0x618A  # <CJK>
+0x5861 0x6191  # <CJK>
+0x5862 0x61AB  # <CJK>
+0x5863 0x61AE  # <CJK>
+0x5864 0x61CC  # <CJK>
+0x5865 0x61CA  # <CJK>
+0x5866 0x61C9  # <CJK>
+0x5867 0x61F7  # <CJK>
+0x5868 0x61C8  # <CJK>
+0x5869 0x61C3  # <CJK>
+0x586A 0x61C6  # <CJK>
+0x586B 0x61BA  # <CJK>
+0x586C 0x61CB  # <CJK>
+0x586D 0x7F79  # <CJK>
+0x586E 0x61CD  # <CJK>
+0x586F 0x61E6  # <CJK>
+0x5870 0x61E3  # <CJK>
+0x5871 0x61F6  # <CJK>
+0x5872 0x61FA  # <CJK>
+0x5873 0x61F4  # <CJK>
+0x5874 0x61FF  # <CJK>
+0x5875 0x61FD  # <CJK>
+0x5876 0x61FC  # <CJK>
+0x5877 0x61FE  # <CJK>
+0x5878 0x6200  # <CJK>
+0x5879 0x6208  # <CJK>
+0x587A 0x6209  # <CJK>
+0x587B 0x620D  # <CJK>
+0x587C 0x620C  # <CJK>
+0x587D 0x6214  # <CJK>
+0x587E 0x621B  # <CJK>
+0x5921 0x621E  # <CJK>
+0x5922 0x6221  # <CJK>
+0x5923 0x622A  # <CJK>
+0x5924 0x622E  # <CJK>
+0x5925 0x6230  # <CJK>
+0x5926 0x6232  # <CJK>
+0x5927 0x6233  # <CJK>
+0x5928 0x6241  # <CJK>
+0x5929 0x624E  # <CJK>
+0x592A 0x625E  # <CJK>
+0x592B 0x6263  # <CJK>
+0x592C 0x625B  # <CJK>
+0x592D 0x6260  # <CJK>
+0x592E 0x6268  # <CJK>
+0x592F 0x627C  # <CJK>
+0x5930 0x6282  # <CJK>
+0x5931 0x6289  # <CJK>
+0x5932 0x627E  # <CJK>
+0x5933 0x6292  # <CJK>
+0x5934 0x6293  # <CJK>
+0x5935 0x6296  # <CJK>
+0x5936 0x62D4  # <CJK>
+0x5937 0x6283  # <CJK>
+0x5938 0x6294  # <CJK>
+0x5939 0x62D7  # <CJK>
+0x593A 0x62D1  # <CJK>
+0x593B 0x62BB  # <CJK>
+0x593C 0x62CF  # <CJK>
+0x593D 0x62FF  # <CJK>
+0x593E 0x62C6  # <CJK>
+0x593F 0x64D4  # <CJK>
+0x5940 0x62C8  # <CJK>
+0x5941 0x62DC  # <CJK>
+0x5942 0x62CC  # <CJK>
+0x5943 0x62CA  # <CJK>
+0x5944 0x62C2  # <CJK>
+0x5945 0x62C7  # <CJK>
+0x5946 0x629B  # <CJK>
+0x5947 0x62C9  # <CJK>
+0x5948 0x630C  # <CJK>
+0x5949 0x62EE  # <CJK>
+0x594A 0x62F1  # <CJK>
+0x594B 0x6327  # <CJK>
+0x594C 0x6302  # <CJK>
+0x594D 0x6308  # <CJK>
+0x594E 0x62EF  # <CJK>
+0x594F 0x62F5  # <CJK>
+0x5950 0x6350  # <CJK>
+0x5951 0x633E  # <CJK>
+0x5952 0x634D  # <CJK>
+0x5953 0x641C  # <CJK>
+0x5954 0x634F  # <CJK>
+0x5955 0x6396  # <CJK>
+0x5956 0x638E  # <CJK>
+0x5957 0x6380  # <CJK>
+0x5958 0x63AB  # <CJK>
+0x5959 0x6376  # <CJK>
+0x595A 0x63A3  # <CJK>
+0x595B 0x638F  # <CJK>
+0x595C 0x6389  # <CJK>
+0x595D 0x639F  # <CJK>
+0x595E 0x63B5  # <CJK>
+0x595F 0x636B  # <CJK>
+0x5960 0x6369  # <CJK>
+0x5961 0x63BE  # <CJK>
+0x5962 0x63E9  # <CJK>
+0x5963 0x63C0  # <CJK>
+0x5964 0x63C6  # <CJK>
+0x5965 0x63E3  # <CJK>
+0x5966 0x63C9  # <CJK>
+0x5967 0x63D2  # <CJK>
+0x5968 0x63F6  # <CJK>
+0x5969 0x63C4  # <CJK>
+0x596A 0x6416  # <CJK>
+0x596B 0x6434  # <CJK>
+0x596C 0x6406  # <CJK>
+0x596D 0x6413  # <CJK>
+0x596E 0x6426  # <CJK>
+0x596F 0x6436  # <CJK>
+0x5970 0x651D  # <CJK>
+0x5971 0x6417  # <CJK>
+0x5972 0x6428  # <CJK>
+0x5973 0x640F  # <CJK>
+0x5974 0x6467  # <CJK>
+0x5975 0x646F  # <CJK>
+0x5976 0x6476  # <CJK>
+0x5977 0x644E  # <CJK>
+0x5978 0x652A  # <CJK>
+0x5979 0x6495  # <CJK>
+0x597A 0x6493  # <CJK>
+0x597B 0x64A5  # <CJK>
+0x597C 0x64A9  # <CJK>
+0x597D 0x6488  # <CJK>
+0x597E 0x64BC  # <CJK>
+0x5A21 0x64DA  # <CJK>
+0x5A22 0x64D2  # <CJK>
+0x5A23 0x64C5  # <CJK>
+0x5A24 0x64C7  # <CJK>
+0x5A25 0x64BB  # <CJK>
+0x5A26 0x64D8  # <CJK>
+0x5A27 0x64C2  # <CJK>
+0x5A28 0x64F1  # <CJK>
+0x5A29 0x64E7  # <CJK>
+0x5A2A 0x8209  # <CJK>
+0x5A2B 0x64E0  # <CJK>
+0x5A2C 0x64E1  # <CJK>
+0x5A2D 0x62AC  # <CJK>
+0x5A2E 0x64E3  # <CJK>
+0x5A2F 0x64EF  # <CJK>
+0x5A30 0x652C  # <CJK>
+0x5A31 0x64F6  # <CJK>
+0x5A32 0x64F4  # <CJK>
+0x5A33 0x64F2  # <CJK>
+0x5A34 0x64FA  # <CJK>
+0x5A35 0x6500  # <CJK>
+0x5A36 0x64FD  # <CJK>
+0x5A37 0x6518  # <CJK>
+0x5A38 0x651C  # <CJK>
+0x5A39 0x6505  # <CJK>
+0x5A3A 0x6524  # <CJK>
+0x5A3B 0x6523  # <CJK>
+0x5A3C 0x652B  # <CJK>
+0x5A3D 0x6534  # <CJK>
+0x5A3E 0x6535  # <CJK>
+0x5A3F 0x6537  # <CJK>
+0x5A40 0x6536  # <CJK>
+0x5A41 0x6538  # <CJK>
+0x5A42 0x754B  # <CJK>
+0x5A43 0x6548  # <CJK>
+0x5A44 0x6556  # <CJK>
+0x5A45 0x6555  # <CJK>
+0x5A46 0x654D  # <CJK>
+0x5A47 0x6558  # <CJK>
+0x5A48 0x655E  # <CJK>
+0x5A49 0x655D  # <CJK>
+0x5A4A 0x6572  # <CJK>
+0x5A4B 0x6578  # <CJK>
+0x5A4C 0x6582  # <CJK>
+0x5A4D 0x6583  # <CJK>
+0x5A4E 0x8B8A  # <CJK>
+0x5A4F 0x659B  # <CJK>
+0x5A50 0x659F  # <CJK>
+0x5A51 0x65AB  # <CJK>
+0x5A52 0x65B7  # <CJK>
+0x5A53 0x65C3  # <CJK>
+0x5A54 0x65C6  # <CJK>
+0x5A55 0x65C1  # <CJK>
+0x5A56 0x65C4  # <CJK>
+0x5A57 0x65CC  # <CJK>
+0x5A58 0x65D2  # <CJK>
+0x5A59 0x65DB  # <CJK>
+0x5A5A 0x65D9  # <CJK>
+0x5A5B 0x65E0  # <CJK>
+0x5A5C 0x65E1  # <CJK>
+0x5A5D 0x65F1  # <CJK>
+0x5A5E 0x6772  # <CJK>
+0x5A5F 0x660A  # <CJK>
+0x5A60 0x6603  # <CJK>
+0x5A61 0x65FB  # <CJK>
+0x5A62 0x6773  # <CJK>
+0x5A63 0x6635  # <CJK>
+0x5A64 0x6636  # <CJK>
+0x5A65 0x6634  # <CJK>
+0x5A66 0x661C  # <CJK>
+0x5A67 0x664F  # <CJK>
+0x5A68 0x6644  # <CJK>
+0x5A69 0x6649  # <CJK>
+0x5A6A 0x6641  # <CJK>
+0x5A6B 0x665E  # <CJK>
+0x5A6C 0x665D  # <CJK>
+0x5A6D 0x6664  # <CJK>
+0x5A6E 0x6667  # <CJK>
+0x5A6F 0x6668  # <CJK>
+0x5A70 0x665F  # <CJK>
+0x5A71 0x6662  # <CJK>
+0x5A72 0x6670  # <CJK>
+0x5A73 0x6683  # <CJK>
+0x5A74 0x6688  # <CJK>
+0x5A75 0x668E  # <CJK>
+0x5A76 0x6689  # <CJK>
+0x5A77 0x6684  # <CJK>
+0x5A78 0x6698  # <CJK>
+0x5A79 0x669D  # <CJK>
+0x5A7A 0x66C1  # <CJK>
+0x5A7B 0x66B9  # <CJK>
+0x5A7C 0x66C9  # <CJK>
+0x5A7D 0x66BE  # <CJK>
+0x5A7E 0x66BC  # <CJK>
+0x5B21 0x66C4  # <CJK>
+0x5B22 0x66B8  # <CJK>
+0x5B23 0x66D6  # <CJK>
+0x5B24 0x66DA  # <CJK>
+0x5B25 0x66E0  # <CJK>
+0x5B26 0x663F  # <CJK>
+0x5B27 0x66E6  # <CJK>
+0x5B28 0x66E9  # <CJK>
+0x5B29 0x66F0  # <CJK>
+0x5B2A 0x66F5  # <CJK>
+0x5B2B 0x66F7  # <CJK>
+0x5B2C 0x670F  # <CJK>
+0x5B2D 0x6716  # <CJK>
+0x5B2E 0x671E  # <CJK>
+0x5B2F 0x6726  # <CJK>
+0x5B30 0x6727  # <CJK>
+0x5B31 0x9738  # <CJK>
+0x5B32 0x672E  # <CJK>
+0x5B33 0x673F  # <CJK>
+0x5B34 0x6736  # <CJK>
+0x5B35 0x6741  # <CJK>
+0x5B36 0x6738  # <CJK>
+0x5B37 0x6737  # <CJK>
+0x5B38 0x6746  # <CJK>
+0x5B39 0x675E  # <CJK>
+0x5B3A 0x6760  # <CJK>
+0x5B3B 0x6759  # <CJK>
+0x5B3C 0x6763  # <CJK>
+0x5B3D 0x6764  # <CJK>
+0x5B3E 0x6789  # <CJK>
+0x5B3F 0x6770  # <CJK>
+0x5B40 0x67A9  # <CJK>
+0x5B41 0x677C  # <CJK>
+0x5B42 0x676A  # <CJK>
+0x5B43 0x678C  # <CJK>
+0x5B44 0x678B  # <CJK>
+0x5B45 0x67A6  # <CJK>
+0x5B46 0x67A1  # <CJK>
+0x5B47 0x6785  # <CJK>
+0x5B48 0x67B7  # <CJK>
+0x5B49 0x67EF  # <CJK>
+0x5B4A 0x67B4  # <CJK>
+0x5B4B 0x67EC  # <CJK>
+0x5B4C 0x67B3  # <CJK>
+0x5B4D 0x67E9  # <CJK>
+0x5B4E 0x67B8  # <CJK>
+0x5B4F 0x67E4  # <CJK>
+0x5B50 0x67DE  # <CJK>
+0x5B51 0x67DD  # <CJK>
+0x5B52 0x67E2  # <CJK>
+0x5B53 0x67EE  # <CJK>
+0x5B54 0x67B9  # <CJK>
+0x5B55 0x67CE  # <CJK>
+0x5B56 0x67C6  # <CJK>
+0x5B57 0x67E7  # <CJK>
+0x5B58 0x6A9C  # <CJK>
+0x5B59 0x681E  # <CJK>
+0x5B5A 0x6846  # <CJK>
+0x5B5B 0x6829  # <CJK>
+0x5B5C 0x6840  # <CJK>
+0x5B5D 0x684D  # <CJK>
+0x5B5E 0x6832  # <CJK>
+0x5B5F 0x684E  # <CJK>
+0x5B60 0x68B3  # <CJK>
+0x5B61 0x682B  # <CJK>
+0x5B62 0x6859  # <CJK>
+0x5B63 0x6863  # <CJK>
+0x5B64 0x6877  # <CJK>
+0x5B65 0x687F  # <CJK>
+0x5B66 0x689F  # <CJK>
+0x5B67 0x688F  # <CJK>
+0x5B68 0x68AD  # <CJK>
+0x5B69 0x6894  # <CJK>
+0x5B6A 0x689D  # <CJK>
+0x5B6B 0x689B  # <CJK>
+0x5B6C 0x6883  # <CJK>
+0x5B6D 0x6AAE  # <CJK>
+0x5B6E 0x68B9  # <CJK>
+0x5B6F 0x6874  # <CJK>
+0x5B70 0x68B5  # <CJK>
+0x5B71 0x68A0  # <CJK>
+0x5B72 0x68BA  # <CJK>
+0x5B73 0x690F  # <CJK>
+0x5B74 0x688D  # <CJK>
+0x5B75 0x687E  # <CJK>
+0x5B76 0x6901  # <CJK>
+0x5B77 0x68CA  # <CJK>
+0x5B78 0x6908  # <CJK>
+0x5B79 0x68D8  # <CJK>
+0x5B7A 0x6922  # <CJK>
+0x5B7B 0x6926  # <CJK>
+0x5B7C 0x68E1  # <CJK>
+0x5B7D 0x690C  # <CJK>
+0x5B7E 0x68CD  # <CJK>
+0x5C21 0x68D4  # <CJK>
+0x5C22 0x68E7  # <CJK>
+0x5C23 0x68D5  # <CJK>
+0x5C24 0x6936  # <CJK>
+0x5C25 0x6912  # <CJK>
+0x5C26 0x6904  # <CJK>
+0x5C27 0x68D7  # <CJK>
+0x5C28 0x68E3  # <CJK>
+0x5C29 0x6925  # <CJK>
+0x5C2A 0x68F9  # <CJK>
+0x5C2B 0x68E0  # <CJK>
+0x5C2C 0x68EF  # <CJK>
+0x5C2D 0x6928  # <CJK>
+0x5C2E 0x692A  # <CJK>
+0x5C2F 0x691A  # <CJK>
+0x5C30 0x6923  # <CJK>
+0x5C31 0x6921  # <CJK>
+0x5C32 0x68C6  # <CJK>
+0x5C33 0x6979  # <CJK>
+0x5C34 0x6977  # <CJK>
+0x5C35 0x695C  # <CJK>
+0x5C36 0x6978  # <CJK>
+0x5C37 0x696B  # <CJK>
+0x5C38 0x6954  # <CJK>
+0x5C39 0x697E  # <CJK>
+0x5C3A 0x696E  # <CJK>
+0x5C3B 0x6939  # <CJK>
+0x5C3C 0x6974  # <CJK>
+0x5C3D 0x693D  # <CJK>
+0x5C3E 0x6959  # <CJK>
+0x5C3F 0x6930  # <CJK>
+0x5C40 0x6961  # <CJK>
+0x5C41 0x695E  # <CJK>
+0x5C42 0x695D  # <CJK>
+0x5C43 0x6981  # <CJK>
+0x5C44 0x696A  # <CJK>
+0x5C45 0x69B2  # <CJK>
+0x5C46 0x69AE  # <CJK>
+0x5C47 0x69D0  # <CJK>
+0x5C48 0x69BF  # <CJK>
+0x5C49 0x69C1  # <CJK>
+0x5C4A 0x69D3  # <CJK>
+0x5C4B 0x69BE  # <CJK>
+0x5C4C 0x69CE  # <CJK>
+0x5C4D 0x5BE8  # <CJK>
+0x5C4E 0x69CA  # <CJK>
+0x5C4F 0x69DD  # <CJK>
+0x5C50 0x69BB  # <CJK>
+0x5C51 0x69C3  # <CJK>
+0x5C52 0x69A7  # <CJK>
+0x5C53 0x6A2E  # <CJK>
+0x5C54 0x6991  # <CJK>
+0x5C55 0x69A0  # <CJK>
+0x5C56 0x699C  # <CJK>
+0x5C57 0x6995  # <CJK>
+0x5C58 0x69B4  # <CJK>
+0x5C59 0x69DE  # <CJK>
+0x5C5A 0x69E8  # <CJK>
+0x5C5B 0x6A02  # <CJK>
+0x5C5C 0x6A1B  # <CJK>
+0x5C5D 0x69FF  # <CJK>
+0x5C5E 0x6B0A  # <CJK>
+0x5C5F 0x69F9  # <CJK>
+0x5C60 0x69F2  # <CJK>
+0x5C61 0x69E7  # <CJK>
+0x5C62 0x6A05  # <CJK>
+0x5C63 0x69B1  # <CJK>
+0x5C64 0x6A1E  # <CJK>
+0x5C65 0x69ED  # <CJK>
+0x5C66 0x6A14  # <CJK>
+0x5C67 0x69EB  # <CJK>
+0x5C68 0x6A0A  # <CJK>
+0x5C69 0x6A12  # <CJK>
+0x5C6A 0x6AC1  # <CJK>
+0x5C6B 0x6A23  # <CJK>
+0x5C6C 0x6A13  # <CJK>
+0x5C6D 0x6A44  # <CJK>
+0x5C6E 0x6A0C  # <CJK>
+0x5C6F 0x6A72  # <CJK>
+0x5C70 0x6A36  # <CJK>
+0x5C71 0x6A78  # <CJK>
+0x5C72 0x6A47  # <CJK>
+0x5C73 0x6A62  # <CJK>
+0x5C74 0x6A59  # <CJK>
+0x5C75 0x6A66  # <CJK>
+0x5C76 0x6A48  # <CJK>
+0x5C77 0x6A38  # <CJK>
+0x5C78 0x6A22  # <CJK>
+0x5C79 0x6A90  # <CJK>
+0x5C7A 0x6A8D  # <CJK>
+0x5C7B 0x6AA0  # <CJK>
+0x5C7C 0x6A84  # <CJK>
+0x5C7D 0x6AA2  # <CJK>
+0x5C7E 0x6AA3  # <CJK>
+0x5D21 0x6A97  # <CJK>
+0x5D22 0x8617  # <CJK>
+0x5D23 0x6ABB  # <CJK>
+0x5D24 0x6AC3  # <CJK>
+0x5D25 0x6AC2  # <CJK>
+0x5D26 0x6AB8  # <CJK>
+0x5D27 0x6AB3  # <CJK>
+0x5D28 0x6AAC  # <CJK>
+0x5D29 0x6ADE  # <CJK>
+0x5D2A 0x6AD1  # <CJK>
+0x5D2B 0x6ADF  # <CJK>
+0x5D2C 0x6AAA  # <CJK>
+0x5D2D 0x6ADA  # <CJK>
+0x5D2E 0x6AEA  # <CJK>
+0x5D2F 0x6AFB  # <CJK>
+0x5D30 0x6B05  # <CJK>
+0x5D31 0x8616  # <CJK>
+0x5D32 0x6AFA  # <CJK>
+0x5D33 0x6B12  # <CJK>
+0x5D34 0x6B16  # <CJK>
+0x5D35 0x9B31  # <CJK>
+0x5D36 0x6B1F  # <CJK>
+0x5D37 0x6B38  # <CJK>
+0x5D38 0x6B37  # <CJK>
+0x5D39 0x76DC  # <CJK>
+0x5D3A 0x6B39  # <CJK>
+0x5D3B 0x98EE  # <CJK>
+0x5D3C 0x6B47  # <CJK>
+0x5D3D 0x6B43  # <CJK>
+0x5D3E 0x6B49  # <CJK>
+0x5D3F 0x6B50  # <CJK>
+0x5D40 0x6B59  # <CJK>
+0x5D41 0x6B54  # <CJK>
+0x5D42 0x6B5B  # <CJK>
+0x5D43 0x6B5F  # <CJK>
+0x5D44 0x6B61  # <CJK>
+0x5D45 0x6B78  # <CJK>
+0x5D46 0x6B79  # <CJK>
+0x5D47 0x6B7F  # <CJK>
+0x5D48 0x6B80  # <CJK>
+0x5D49 0x6B84  # <CJK>
+0x5D4A 0x6B83  # <CJK>
+0x5D4B 0x6B8D  # <CJK>
+0x5D4C 0x6B98  # <CJK>
+0x5D4D 0x6B95  # <CJK>
+0x5D4E 0x6B9E  # <CJK>
+0x5D4F 0x6BA4  # <CJK>
+0x5D50 0x6BAA  # <CJK>
+0x5D51 0x6BAB  # <CJK>
+0x5D52 0x6BAF  # <CJK>
+0x5D53 0x6BB2  # <CJK>
+0x5D54 0x6BB1  # <CJK>
+0x5D55 0x6BB3  # <CJK>
+0x5D56 0x6BB7  # <CJK>
+0x5D57 0x6BBC  # <CJK>
+0x5D58 0x6BC6  # <CJK>
+0x5D59 0x6BCB  # <CJK>
+0x5D5A 0x6BD3  # <CJK>
+0x5D5B 0x6BDF  # <CJK>
+0x5D5C 0x6BEC  # <CJK>
+0x5D5D 0x6BEB  # <CJK>
+0x5D5E 0x6BF3  # <CJK>
+0x5D5F 0x6BEF  # <CJK>
+0x5D60 0x9EBE  # <CJK>
+0x5D61 0x6C08  # <CJK>
+0x5D62 0x6C13  # <CJK>
+0x5D63 0x6C14  # <CJK>
+0x5D64 0x6C1B  # <CJK>
+0x5D65 0x6C24  # <CJK>
+0x5D66 0x6C23  # <CJK>
+0x5D67 0x6C5E  # <CJK>
+0x5D68 0x6C55  # <CJK>
+0x5D69 0x6C62  # <CJK>
+0x5D6A 0x6C6A  # <CJK>
+0x5D6B 0x6C82  # <CJK>
+0x5D6C 0x6C8D  # <CJK>
+0x5D6D 0x6C9A  # <CJK>
+0x5D6E 0x6C81  # <CJK>
+0x5D6F 0x6C9B  # <CJK>
+0x5D70 0x6C7E  # <CJK>
+0x5D71 0x6C68  # <CJK>
+0x5D72 0x6C73  # <CJK>
+0x5D73 0x6C92  # <CJK>
+0x5D74 0x6C90  # <CJK>
+0x5D75 0x6CC4  # <CJK>
+0x5D76 0x6CF1  # <CJK>
+0x5D77 0x6CD3  # <CJK>
+0x5D78 0x6CBD  # <CJK>
+0x5D79 0x6CD7  # <CJK>
+0x5D7A 0x6CC5  # <CJK>
+0x5D7B 0x6CDD  # <CJK>
+0x5D7C 0x6CAE  # <CJK>
+0x5D7D 0x6CB1  # <CJK>
+0x5D7E 0x6CBE  # <CJK>
+0x5E21 0x6CBA  # <CJK>
+0x5E22 0x6CDB  # <CJK>
+0x5E23 0x6CEF  # <CJK>
+0x5E24 0x6CD9  # <CJK>
+0x5E25 0x6CEA  # <CJK>
+0x5E26 0x6D1F  # <CJK>
+0x5E27 0x884D  # <CJK>
+0x5E28 0x6D36  # <CJK>
+0x5E29 0x6D2B  # <CJK>
+0x5E2A 0x6D3D  # <CJK>
+0x5E2B 0x6D38  # <CJK>
+0x5E2C 0x6D19  # <CJK>
+0x5E2D 0x6D35  # <CJK>
+0x5E2E 0x6D33  # <CJK>
+0x5E2F 0x6D12  # <CJK>
+0x5E30 0x6D0C  # <CJK>
+0x5E31 0x6D63  # <CJK>
+0x5E32 0x6D93  # <CJK>
+0x5E33 0x6D64  # <CJK>
+0x5E34 0x6D5A  # <CJK>
+0x5E35 0x6D79  # <CJK>
+0x5E36 0x6D59  # <CJK>
+0x5E37 0x6D8E  # <CJK>
+0x5E38 0x6D95  # <CJK>
+0x5E39 0x6FE4  # <CJK>
+0x5E3A 0x6D85  # <CJK>
+0x5E3B 0x6DF9  # <CJK>
+0x5E3C 0x6E15  # <CJK>
+0x5E3D 0x6E0A  # <CJK>
+0x5E3E 0x6DB5  # <CJK>
+0x5E3F 0x6DC7  # <CJK>
+0x5E40 0x6DE6  # <CJK>
+0x5E41 0x6DB8  # <CJK>
+0x5E42 0x6DC6  # <CJK>
+0x5E43 0x6DEC  # <CJK>
+0x5E44 0x6DDE  # <CJK>
+0x5E45 0x6DCC  # <CJK>
+0x5E46 0x6DE8  # <CJK>
+0x5E47 0x6DD2  # <CJK>
+0x5E48 0x6DC5  # <CJK>
+0x5E49 0x6DFA  # <CJK>
+0x5E4A 0x6DD9  # <CJK>
+0x5E4B 0x6DE4  # <CJK>
+0x5E4C 0x6DD5  # <CJK>
+0x5E4D 0x6DEA  # <CJK>
+0x5E4E 0x6DEE  # <CJK>
+0x5E4F 0x6E2D  # <CJK>
+0x5E50 0x6E6E  # <CJK>
+0x5E51 0x6E2E  # <CJK>
+0x5E52 0x6E19  # <CJK>
+0x5E53 0x6E72  # <CJK>
+0x5E54 0x6E5F  # <CJK>
+0x5E55 0x6E3E  # <CJK>
+0x5E56 0x6E23  # <CJK>
+0x5E57 0x6E6B  # <CJK>
+0x5E58 0x6E2B  # <CJK>
+0x5E59 0x6E76  # <CJK>
+0x5E5A 0x6E4D  # <CJK>
+0x5E5B 0x6E1F  # <CJK>
+0x5E5C 0x6E43  # <CJK>
+0x5E5D 0x6E3A  # <CJK>
+0x5E5E 0x6E4E  # <CJK>
+0x5E5F 0x6E24  # <CJK>
+0x5E60 0x6EFF  # <CJK>
+0x5E61 0x6E1D  # <CJK>
+0x5E62 0x6E38  # <CJK>
+0x5E63 0x6E82  # <CJK>
+0x5E64 0x6EAA  # <CJK>
+0x5E65 0x6E98  # <CJK>
+0x5E66 0x6EC9  # <CJK>
+0x5E67 0x6EB7  # <CJK>
+0x5E68 0x6ED3  # <CJK>
+0x5E69 0x6EBD  # <CJK>
+0x5E6A 0x6EAF  # <CJK>
+0x5E6B 0x6EC4  # <CJK>
+0x5E6C 0x6EB2  # <CJK>
+0x5E6D 0x6ED4  # <CJK>
+0x5E6E 0x6ED5  # <CJK>
+0x5E6F 0x6E8F  # <CJK>
+0x5E70 0x6EA5  # <CJK>
+0x5E71 0x6EC2  # <CJK>
+0x5E72 0x6E9F  # <CJK>
+0x5E73 0x6F41  # <CJK>
+0x5E74 0x6F11  # <CJK>
+0x5E75 0x704C  # <CJK>
+0x5E76 0x6EEC  # <CJK>
+0x5E77 0x6EF8  # <CJK>
+0x5E78 0x6EFE  # <CJK>
+0x5E79 0x6F3F  # <CJK>
+0x5E7A 0x6EF2  # <CJK>
+0x5E7B 0x6F31  # <CJK>
+0x5E7C 0x6EEF  # <CJK>
+0x5E7D 0x6F32  # <CJK>
+0x5E7E 0x6ECC  # <CJK>
+0x5F21 0x6F3E  # <CJK>
+0x5F22 0x6F13  # <CJK>
+0x5F23 0x6EF7  # <CJK>
+0x5F24 0x6F86  # <CJK>
+0x5F25 0x6F7A  # <CJK>
+0x5F26 0x6F78  # <CJK>
+0x5F27 0x6F81  # <CJK>
+0x5F28 0x6F80  # <CJK>
+0x5F29 0x6F6F  # <CJK>
+0x5F2A 0x6F5B  # <CJK>
+0x5F2B 0x6FF3  # <CJK>
+0x5F2C 0x6F6D  # <CJK>
+0x5F2D 0x6F82  # <CJK>
+0x5F2E 0x6F7C  # <CJK>
+0x5F2F 0x6F58  # <CJK>
+0x5F30 0x6F8E  # <CJK>
+0x5F31 0x6F91  # <CJK>
+0x5F32 0x6FC2  # <CJK>
+0x5F33 0x6F66  # <CJK>
+0x5F34 0x6FB3  # <CJK>
+0x5F35 0x6FA3  # <CJK>
+0x5F36 0x6FA1  # <CJK>
+0x5F37 0x6FA4  # <CJK>
+0x5F38 0x6FB9  # <CJK>
+0x5F39 0x6FC6  # <CJK>
+0x5F3A 0x6FAA  # <CJK>
+0x5F3B 0x6FDF  # <CJK>
+0x5F3C 0x6FD5  # <CJK>
+0x5F3D 0x6FEC  # <CJK>
+0x5F3E 0x6FD4  # <CJK>
+0x5F3F 0x6FD8  # <CJK>
+0x5F40 0x6FF1  # <CJK>
+0x5F41 0x6FEE  # <CJK>
+0x5F42 0x6FDB  # <CJK>
+0x5F43 0x7009  # <CJK>
+0x5F44 0x700B  # <CJK>
+0x5F45 0x6FFA  # <CJK>
+0x5F46 0x7011  # <CJK>
+0x5F47 0x7001  # <CJK>
+0x5F48 0x700F  # <CJK>
+0x5F49 0x6FFE  # <CJK>
+0x5F4A 0x701B  # <CJK>
+0x5F4B 0x701A  # <CJK>
+0x5F4C 0x6F74  # <CJK>
+0x5F4D 0x701D  # <CJK>
+0x5F4E 0x7018  # <CJK>
+0x5F4F 0x701F  # <CJK>
+0x5F50 0x7030  # <CJK>
+0x5F51 0x703E  # <CJK>
+0x5F52 0x7032  # <CJK>
+0x5F53 0x7051  # <CJK>
+0x5F54 0x7063  # <CJK>
+0x5F55 0x7099  # <CJK>
+0x5F56 0x7092  # <CJK>
+0x5F57 0x70AF  # <CJK>
+0x5F58 0x70F1  # <CJK>
+0x5F59 0x70AC  # <CJK>
+0x5F5A 0x70B8  # <CJK>
+0x5F5B 0x70B3  # <CJK>
+0x5F5C 0x70AE  # <CJK>
+0x5F5D 0x70DF  # <CJK>
+0x5F5E 0x70CB  # <CJK>
+0x5F5F 0x70DD  # <CJK>
+0x5F60 0x70D9  # <CJK>
+0x5F61 0x7109  # <CJK>
+0x5F62 0x70FD  # <CJK>
+0x5F63 0x711C  # <CJK>
+0x5F64 0x7119  # <CJK>
+0x5F65 0x7165  # <CJK>
+0x5F66 0x7155  # <CJK>
+0x5F67 0x7188  # <CJK>
+0x5F68 0x7166  # <CJK>
+0x5F69 0x7162  # <CJK>
+0x5F6A 0x714C  # <CJK>
+0x5F6B 0x7156  # <CJK>
+0x5F6C 0x716C  # <CJK>
+0x5F6D 0x718F  # <CJK>
+0x5F6E 0x71FB  # <CJK>
+0x5F6F 0x7184  # <CJK>
+0x5F70 0x7195  # <CJK>
+0x5F71 0x71A8  # <CJK>
+0x5F72 0x71AC  # <CJK>
+0x5F73 0x71D7  # <CJK>
+0x5F74 0x71B9  # <CJK>
+0x5F75 0x71BE  # <CJK>
+0x5F76 0x71D2  # <CJK>
+0x5F77 0x71C9  # <CJK>
+0x5F78 0x71D4  # <CJK>
+0x5F79 0x71CE  # <CJK>
+0x5F7A 0x71E0  # <CJK>
+0x5F7B 0x71EC  # <CJK>
+0x5F7C 0x71E7  # <CJK>
+0x5F7D 0x71F5  # <CJK>
+0x5F7E 0x71FC  # <CJK>
+0x6021 0x71F9  # <CJK>
+0x6022 0x71FF  # <CJK>
+0x6023 0x720D  # <CJK>
+0x6024 0x7210  # <CJK>
+0x6025 0x721B  # <CJK>
+0x6026 0x7228  # <CJK>
+0x6027 0x722D  # <CJK>
+0x6028 0x722C  # <CJK>
+0x6029 0x7230  # <CJK>
+0x602A 0x7232  # <CJK>
+0x602B 0x723B  # <CJK>
+0x602C 0x723C  # <CJK>
+0x602D 0x723F  # <CJK>
+0x602E 0x7240  # <CJK>
+0x602F 0x7246  # <CJK>
+0x6030 0x724B  # <CJK>
+0x6031 0x7258  # <CJK>
+0x6032 0x7274  # <CJK>
+0x6033 0x727E  # <CJK>
+0x6034 0x7282  # <CJK>
+0x6035 0x7281  # <CJK>
+0x6036 0x7287  # <CJK>
+0x6037 0x7292  # <CJK>
+0x6038 0x7296  # <CJK>
+0x6039 0x72A2  # <CJK>
+0x603A 0x72A7  # <CJK>
+0x603B 0x72B9  # <CJK>
+0x603C 0x72B2  # <CJK>
+0x603D 0x72C3  # <CJK>
+0x603E 0x72C6  # <CJK>
+0x603F 0x72C4  # <CJK>
+0x6040 0x72CE  # <CJK>
+0x6041 0x72D2  # <CJK>
+0x6042 0x72E2  # <CJK>
+0x6043 0x72E0  # <CJK>
+0x6044 0x72E1  # <CJK>
+0x6045 0x72F9  # <CJK>
+0x6046 0x72F7  # <CJK>
+0x6047 0x500F  # <CJK>
+0x6048 0x7317  # <CJK>
+0x6049 0x730A  # <CJK>
+0x604A 0x731C  # <CJK>
+0x604B 0x7316  # <CJK>
+0x604C 0x731D  # <CJK>
+0x604D 0x7334  # <CJK>
+0x604E 0x732F  # <CJK>
+0x604F 0x7329  # <CJK>
+0x6050 0x7325  # <CJK>
+0x6051 0x733E  # <CJK>
+0x6052 0x734E  # <CJK>
+0x6053 0x734F  # <CJK>
+0x6054 0x9ED8  # <CJK>
+0x6055 0x7357  # <CJK>
+0x6056 0x736A  # <CJK>
+0x6057 0x7368  # <CJK>
+0x6058 0x7370  # <CJK>
+0x6059 0x7378  # <CJK>
+0x605A 0x7375  # <CJK>
+0x605B 0x737B  # <CJK>
+0x605C 0x737A  # <CJK>
+0x605D 0x73C8  # <CJK>
+0x605E 0x73B3  # <CJK>
+0x605F 0x73CE  # <CJK>
+0x6060 0x73BB  # <CJK>
+0x6061 0x73C0  # <CJK>
+0x6062 0x73E5  # <CJK>
+0x6063 0x73EE  # <CJK>
+0x6064 0x73DE  # <CJK>
+0x6065 0x74A2  # <CJK>
+0x6066 0x7405  # <CJK>
+0x6067 0x746F  # <CJK>
+0x6068 0x7425  # <CJK>
+0x6069 0x73F8  # <CJK>
+0x606A 0x7432  # <CJK>
+0x606B 0x743A  # <CJK>
+0x606C 0x7455  # <CJK>
+0x606D 0x743F  # <CJK>
+0x606E 0x745F  # <CJK>
+0x606F 0x7459  # <CJK>
+0x6070 0x7441  # <CJK>
+0x6071 0x745C  # <CJK>
+0x6072 0x7469  # <CJK>
+0x6073 0x7470  # <CJK>
+0x6074 0x7463  # <CJK>
+0x6075 0x746A  # <CJK>
+0x6076 0x7476  # <CJK>
+0x6077 0x747E  # <CJK>
+0x6078 0x748B  # <CJK>
+0x6079 0x749E  # <CJK>
+0x607A 0x74A7  # <CJK>
+0x607B 0x74CA  # <CJK>
+0x607C 0x74CF  # <CJK>
+0x607D 0x74D4  # <CJK>
+0x607E 0x73F1  # <CJK>
+0x6121 0x74E0  # <CJK>
+0x6122 0x74E3  # <CJK>
+0x6123 0x74E7  # <CJK>
+0x6124 0x74E9  # <CJK>
+0x6125 0x74EE  # <CJK>
+0x6126 0x74F2  # <CJK>
+0x6127 0x74F0  # <CJK>
+0x6128 0x74F1  # <CJK>
+0x6129 0x74F8  # <CJK>
+0x612A 0x74F7  # <CJK>
+0x612B 0x7504  # <CJK>
+0x612C 0x7503  # <CJK>
+0x612D 0x7505  # <CJK>
+0x612E 0x750C  # <CJK>
+0x612F 0x750E  # <CJK>
+0x6130 0x750D  # <CJK>
+0x6131 0x7515  # <CJK>
+0x6132 0x7513  # <CJK>
+0x6133 0x751E  # <CJK>
+0x6134 0x7526  # <CJK>
+0x6135 0x752C  # <CJK>
+0x6136 0x753C  # <CJK>
+0x6137 0x7544  # <CJK>
+0x6138 0x754D  # <CJK>
+0x6139 0x754A  # <CJK>
+0x613A 0x7549  # <CJK>
+0x613B 0x755B  # <CJK>
+0x613C 0x7546  # <CJK>
+0x613D 0x755A  # <CJK>
+0x613E 0x7569  # <CJK>
+0x613F 0x7564  # <CJK>
+0x6140 0x7567  # <CJK>
+0x6141 0x756B  # <CJK>
+0x6142 0x756D  # <CJK>
+0x6143 0x7578  # <CJK>
+0x6144 0x7576  # <CJK>
+0x6145 0x7586  # <CJK>
+0x6146 0x7587  # <CJK>
+0x6147 0x7574  # <CJK>
+0x6148 0x758A  # <CJK>
+0x6149 0x7589  # <CJK>
+0x614A 0x7582  # <CJK>
+0x614B 0x7594  # <CJK>
+0x614C 0x759A  # <CJK>
+0x614D 0x759D  # <CJK>
+0x614E 0x75A5  # <CJK>
+0x614F 0x75A3  # <CJK>
+0x6150 0x75C2  # <CJK>
+0x6151 0x75B3  # <CJK>
+0x6152 0x75C3  # <CJK>
+0x6153 0x75B5  # <CJK>
+0x6154 0x75BD  # <CJK>
+0x6155 0x75B8  # <CJK>
+0x6156 0x75BC  # <CJK>
+0x6157 0x75B1  # <CJK>
+0x6158 0x75CD  # <CJK>
+0x6159 0x75CA  # <CJK>
+0x615A 0x75D2  # <CJK>
+0x615B 0x75D9  # <CJK>
+0x615C 0x75E3  # <CJK>
+0x615D 0x75DE  # <CJK>
+0x615E 0x75FE  # <CJK>
+0x615F 0x75FF  # <CJK>
+0x6160 0x75FC  # <CJK>
+0x6161 0x7601  # <CJK>
+0x6162 0x75F0  # <CJK>
+0x6163 0x75FA  # <CJK>
+0x6164 0x75F2  # <CJK>
+0x6165 0x75F3  # <CJK>
+0x6166 0x760B  # <CJK>
+0x6167 0x760D  # <CJK>
+0x6168 0x7609  # <CJK>
+0x6169 0x761F  # <CJK>
+0x616A 0x7627  # <CJK>
+0x616B 0x7620  # <CJK>
+0x616C 0x7621  # <CJK>
+0x616D 0x7622  # <CJK>
+0x616E 0x7624  # <CJK>
+0x616F 0x7634  # <CJK>
+0x6170 0x7630  # <CJK>
+0x6171 0x763B  # <CJK>
+0x6172 0x7647  # <CJK>
+0x6173 0x7648  # <CJK>
+0x6174 0x7646  # <CJK>
+0x6175 0x765C  # <CJK>
+0x6176 0x7658  # <CJK>
+0x6177 0x7661  # <CJK>
+0x6178 0x7662  # <CJK>
+0x6179 0x7668  # <CJK>
+0x617A 0x7669  # <CJK>
+0x617B 0x766A  # <CJK>
+0x617C 0x7667  # <CJK>
+0x617D 0x766C  # <CJK>
+0x617E 0x7670  # <CJK>
+0x6221 0x7672  # <CJK>
+0x6222 0x7676  # <CJK>
+0x6223 0x7678  # <CJK>
+0x6224 0x767C  # <CJK>
+0x6225 0x7680  # <CJK>
+0x6226 0x7683  # <CJK>
+0x6227 0x7688  # <CJK>
+0x6228 0x768B  # <CJK>
+0x6229 0x768E  # <CJK>
+0x622A 0x7696  # <CJK>
+0x622B 0x7693  # <CJK>
+0x622C 0x7699  # <CJK>
+0x622D 0x769A  # <CJK>
+0x622E 0x76B0  # <CJK>
+0x622F 0x76B4  # <CJK>
+0x6230 0x76B8  # <CJK>
+0x6231 0x76B9  # <CJK>
+0x6232 0x76BA  # <CJK>
+0x6233 0x76C2  # <CJK>
+0x6234 0x76CD  # <CJK>
+0x6235 0x76D6  # <CJK>
+0x6236 0x76D2  # <CJK>
+0x6237 0x76DE  # <CJK>
+0x6238 0x76E1  # <CJK>
+0x6239 0x76E5  # <CJK>
+0x623A 0x76E7  # <CJK>
+0x623B 0x76EA  # <CJK>
+0x623C 0x862F  # <CJK>
+0x623D 0x76FB  # <CJK>
+0x623E 0x7708  # <CJK>
+0x623F 0x7707  # <CJK>
+0x6240 0x7704  # <CJK>
+0x6241 0x7729  # <CJK>
+0x6242 0x7724  # <CJK>
+0x6243 0x771E  # <CJK>
+0x6244 0x7725  # <CJK>
+0x6245 0x7726  # <CJK>
+0x6246 0x771B  # <CJK>
+0x6247 0x7737  # <CJK>
+0x6248 0x7738  # <CJK>
+0x6249 0x7747  # <CJK>
+0x624A 0x775A  # <CJK>
+0x624B 0x7768  # <CJK>
+0x624C 0x776B  # <CJK>
+0x624D 0x775B  # <CJK>
+0x624E 0x7765  # <CJK>
+0x624F 0x777F  # <CJK>
+0x6250 0x777E  # <CJK>
+0x6251 0x7779  # <CJK>
+0x6252 0x778E  # <CJK>
+0x6253 0x778B  # <CJK>
+0x6254 0x7791  # <CJK>
+0x6255 0x77A0  # <CJK>
+0x6256 0x779E  # <CJK>
+0x6257 0x77B0  # <CJK>
+0x6258 0x77B6  # <CJK>
+0x6259 0x77B9  # <CJK>
+0x625A 0x77BF  # <CJK>
+0x625B 0x77BC  # <CJK>
+0x625C 0x77BD  # <CJK>
+0x625D 0x77BB  # <CJK>
+0x625E 0x77C7  # <CJK>
+0x625F 0x77CD  # <CJK>
+0x6260 0x77D7  # <CJK>
+0x6261 0x77DA  # <CJK>
+0x6262 0x77DC  # <CJK>
+0x6263 0x77E3  # <CJK>
+0x6264 0x77EE  # <CJK>
+0x6265 0x77FC  # <CJK>
+0x6266 0x780C  # <CJK>
+0x6267 0x7812  # <CJK>
+0x6268 0x7926  # <CJK>
+0x6269 0x7820  # <CJK>
+0x626A 0x792A  # <CJK>
+0x626B 0x7845  # <CJK>
+0x626C 0x788E  # <CJK>
+0x626D 0x7874  # <CJK>
+0x626E 0x7886  # <CJK>
+0x626F 0x787C  # <CJK>
+0x6270 0x789A  # <CJK>
+0x6271 0x788C  # <CJK>
+0x6272 0x78A3  # <CJK>
+0x6273 0x78B5  # <CJK>
+0x6274 0x78AA  # <CJK>
+0x6275 0x78AF  # <CJK>
+0x6276 0x78D1  # <CJK>
+0x6277 0x78C6  # <CJK>
+0x6278 0x78CB  # <CJK>
+0x6279 0x78D4  # <CJK>
+0x627A 0x78BE  # <CJK>
+0x627B 0x78BC  # <CJK>
+0x627C 0x78C5  # <CJK>
+0x627D 0x78CA  # <CJK>
+0x627E 0x78EC  # <CJK>
+0x6321 0x78E7  # <CJK>
+0x6322 0x78DA  # <CJK>
+0x6323 0x78FD  # <CJK>
+0x6324 0x78F4  # <CJK>
+0x6325 0x7907  # <CJK>
+0x6326 0x7912  # <CJK>
+0x6327 0x7911  # <CJK>
+0x6328 0x7919  # <CJK>
+0x6329 0x792C  # <CJK>
+0x632A 0x792B  # <CJK>
+0x632B 0x7940  # <CJK>
+0x632C 0x7960  # <CJK>
+0x632D 0x7957  # <CJK>
+0x632E 0x795F  # <CJK>
+0x632F 0x795A  # <CJK>
+0x6330 0x7955  # <CJK>
+0x6331 0x7953  # <CJK>
+0x6332 0x797A  # <CJK>
+0x6333 0x797F  # <CJK>
+0x6334 0x798A  # <CJK>
+0x6335 0x799D  # <CJK>
+0x6336 0x79A7  # <CJK>
+0x6337 0x9F4B  # <CJK>
+0x6338 0x79AA  # <CJK>
+0x6339 0x79AE  # <CJK>
+0x633A 0x79B3  # <CJK>
+0x633B 0x79B9  # <CJK>
+0x633C 0x79BA  # <CJK>
+0x633D 0x79C9  # <CJK>
+0x633E 0x79D5  # <CJK>
+0x633F 0x79E7  # <CJK>
+0x6340 0x79EC  # <CJK>
+0x6341 0x79E1  # <CJK>
+0x6342 0x79E3  # <CJK>
+0x6343 0x7A08  # <CJK>
+0x6344 0x7A0D  # <CJK>
+0x6345 0x7A18  # <CJK>
+0x6346 0x7A19  # <CJK>
+0x6347 0x7A20  # <CJK>
+0x6348 0x7A1F  # <CJK>
+0x6349 0x7980  # <CJK>
+0x634A 0x7A31  # <CJK>
+0x634B 0x7A3B  # <CJK>
+0x634C 0x7A3E  # <CJK>
+0x634D 0x7A37  # <CJK>
+0x634E 0x7A43  # <CJK>
+0x634F 0x7A57  # <CJK>
+0x6350 0x7A49  # <CJK>
+0x6351 0x7A61  # <CJK>
+0x6352 0x7A62  # <CJK>
+0x6353 0x7A69  # <CJK>
+0x6354 0x9F9D  # <CJK>
+0x6355 0x7A70  # <CJK>
+0x6356 0x7A79  # <CJK>
+0x6357 0x7A7D  # <CJK>
+0x6358 0x7A88  # <CJK>
+0x6359 0x7A97  # <CJK>
+0x635A 0x7A95  # <CJK>
+0x635B 0x7A98  # <CJK>
+0x635C 0x7A96  # <CJK>
+0x635D 0x7AA9  # <CJK>
+0x635E 0x7AC8  # <CJK>
+0x635F 0x7AB0  # <CJK>
+0x6360 0x7AB6  # <CJK>
+0x6361 0x7AC5  # <CJK>
+0x6362 0x7AC4  # <CJK>
+0x6363 0x7ABF  # <CJK>
+0x6364 0x9083  # <CJK>
+0x6365 0x7AC7  # <CJK>
+0x6366 0x7ACA  # <CJK>
+0x6367 0x7ACD  # <CJK>
+0x6368 0x7ACF  # <CJK>
+0x6369 0x7AD5  # <CJK>
+0x636A 0x7AD3  # <CJK>
+0x636B 0x7AD9  # <CJK>
+0x636C 0x7ADA  # <CJK>
+0x636D 0x7ADD  # <CJK>
+0x636E 0x7AE1  # <CJK>
+0x636F 0x7AE2  # <CJK>
+0x6370 0x7AE6  # <CJK>
+0x6371 0x7AED  # <CJK>
+0x6372 0x7AF0  # <CJK>
+0x6373 0x7B02  # <CJK>
+0x6374 0x7B0F  # <CJK>
+0x6375 0x7B0A  # <CJK>
+0x6376 0x7B06  # <CJK>
+0x6377 0x7B33  # <CJK>
+0x6378 0x7B18  # <CJK>
+0x6379 0x7B19  # <CJK>
+0x637A 0x7B1E  # <CJK>
+0x637B 0x7B35  # <CJK>
+0x637C 0x7B28  # <CJK>
+0x637D 0x7B36  # <CJK>
+0x637E 0x7B50  # <CJK>
+0x6421 0x7B7A  # <CJK>
+0x6422 0x7B04  # <CJK>
+0x6423 0x7B4D  # <CJK>
+0x6424 0x7B0B  # <CJK>
+0x6425 0x7B4C  # <CJK>
+0x6426 0x7B45  # <CJK>
+0x6427 0x7B75  # <CJK>
+0x6428 0x7B65  # <CJK>
+0x6429 0x7B74  # <CJK>
+0x642A 0x7B67  # <CJK>
+0x642B 0x7B70  # <CJK>
+0x642C 0x7B71  # <CJK>
+0x642D 0x7B6C  # <CJK>
+0x642E 0x7B6E  # <CJK>
+0x642F 0x7B9D  # <CJK>
+0x6430 0x7B98  # <CJK>
+0x6431 0x7B9F  # <CJK>
+0x6432 0x7B8D  # <CJK>
+0x6433 0x7B9C  # <CJK>
+0x6434 0x7B9A  # <CJK>
+0x6435 0x7B8B  # <CJK>
+0x6436 0x7B92  # <CJK>
+0x6437 0x7B8F  # <CJK>
+0x6438 0x7B5D  # <CJK>
+0x6439 0x7B99  # <CJK>
+0x643A 0x7BCB  # <CJK>
+0x643B 0x7BC1  # <CJK>
+0x643C 0x7BCC  # <CJK>
+0x643D 0x7BCF  # <CJK>
+0x643E 0x7BB4  # <CJK>
+0x643F 0x7BC6  # <CJK>
+0x6440 0x7BDD  # <CJK>
+0x6441 0x7BE9  # <CJK>
+0x6442 0x7C11  # <CJK>
+0x6443 0x7C14  # <CJK>
+0x6444 0x7BE6  # <CJK>
+0x6445 0x7BE5  # <CJK>
+0x6446 0x7C60  # <CJK>
+0x6447 0x7C00  # <CJK>
+0x6448 0x7C07  # <CJK>
+0x6449 0x7C13  # <CJK>
+0x644A 0x7BF3  # <CJK>
+0x644B 0x7BF7  # <CJK>
+0x644C 0x7C17  # <CJK>
+0x644D 0x7C0D  # <CJK>
+0x644E 0x7BF6  # <CJK>
+0x644F 0x7C23  # <CJK>
+0x6450 0x7C27  # <CJK>
+0x6451 0x7C2A  # <CJK>
+0x6452 0x7C1F  # <CJK>
+0x6453 0x7C37  # <CJK>
+0x6454 0x7C2B  # <CJK>
+0x6455 0x7C3D  # <CJK>
+0x6456 0x7C4C  # <CJK>
+0x6457 0x7C43  # <CJK>
+0x6458 0x7C54  # <CJK>
+0x6459 0x7C4F  # <CJK>
+0x645A 0x7C40  # <CJK>
+0x645B 0x7C50  # <CJK>
+0x645C 0x7C58  # <CJK>
+0x645D 0x7C5F  # <CJK>
+0x645E 0x7C64  # <CJK>
+0x645F 0x7C56  # <CJK>
+0x6460 0x7C65  # <CJK>
+0x6461 0x7C6C  # <CJK>
+0x6462 0x7C75  # <CJK>
+0x6463 0x7C83  # <CJK>
+0x6464 0x7C90  # <CJK>
+0x6465 0x7CA4  # <CJK>
+0x6466 0x7CAD  # <CJK>
+0x6467 0x7CA2  # <CJK>
+0x6468 0x7CAB  # <CJK>
+0x6469 0x7CA1  # <CJK>
+0x646A 0x7CA8  # <CJK>
+0x646B 0x7CB3  # <CJK>
+0x646C 0x7CB2  # <CJK>
+0x646D 0x7CB1  # <CJK>
+0x646E 0x7CAE  # <CJK>
+0x646F 0x7CB9  # <CJK>
+0x6470 0x7CBD  # <CJK>
+0x6471 0x7CC0  # <CJK>
+0x6472 0x7CC5  # <CJK>
+0x6473 0x7CC2  # <CJK>
+0x6474 0x7CD8  # <CJK>
+0x6475 0x7CD2  # <CJK>
+0x6476 0x7CDC  # <CJK>
+0x6477 0x7CE2  # <CJK>
+0x6478 0x9B3B  # <CJK>
+0x6479 0x7CEF  # <CJK>
+0x647A 0x7CF2  # <CJK>
+0x647B 0x7CF4  # <CJK>
+0x647C 0x7CF6  # <CJK>
+0x647D 0x7CFA  # <CJK>
+0x647E 0x7D06  # <CJK>
+0x6521 0x7D02  # <CJK>
+0x6522 0x7D1C  # <CJK>
+0x6523 0x7D15  # <CJK>
+0x6524 0x7D0A  # <CJK>
+0x6525 0x7D45  # <CJK>
+0x6526 0x7D4B  # <CJK>
+0x6527 0x7D2E  # <CJK>
+0x6528 0x7D32  # <CJK>
+0x6529 0x7D3F  # <CJK>
+0x652A 0x7D35  # <CJK>
+0x652B 0x7D46  # <CJK>
+0x652C 0x7D73  # <CJK>
+0x652D 0x7D56  # <CJK>
+0x652E 0x7D4E  # <CJK>
+0x652F 0x7D72  # <CJK>
+0x6530 0x7D68  # <CJK>
+0x6531 0x7D6E  # <CJK>
+0x6532 0x7D4F  # <CJK>
+0x6533 0x7D63  # <CJK>
+0x6534 0x7D93  # <CJK>
+0x6535 0x7D89  # <CJK>
+0x6536 0x7D5B  # <CJK>
+0x6537 0x7D8F  # <CJK>
+0x6538 0x7D7D  # <CJK>
+0x6539 0x7D9B  # <CJK>
+0x653A 0x7DBA  # <CJK>
+0x653B 0x7DAE  # <CJK>
+0x653C 0x7DA3  # <CJK>
+0x653D 0x7DB5  # <CJK>
+0x653E 0x7DC7  # <CJK>
+0x653F 0x7DBD  # <CJK>
+0x6540 0x7DAB  # <CJK>
+0x6541 0x7E3D  # <CJK>
+0x6542 0x7DA2  # <CJK>
+0x6543 0x7DAF  # <CJK>
+0x6544 0x7DDC  # <CJK>
+0x6545 0x7DB8  # <CJK>
+0x6546 0x7D9F  # <CJK>
+0x6547 0x7DB0  # <CJK>
+0x6548 0x7DD8  # <CJK>
+0x6549 0x7DDD  # <CJK>
+0x654A 0x7DE4  # <CJK>
+0x654B 0x7DDE  # <CJK>
+0x654C 0x7DFB  # <CJK>
+0x654D 0x7DF2  # <CJK>
+0x654E 0x7DE1  # <CJK>
+0x654F 0x7E05  # <CJK>
+0x6550 0x7E0A  # <CJK>
+0x6551 0x7E23  # <CJK>
+0x6552 0x7E21  # <CJK>
+0x6553 0x7E12  # <CJK>
+0x6554 0x7E31  # <CJK>
+0x6555 0x7E1F  # <CJK>
+0x6556 0x7E09  # <CJK>
+0x6557 0x7E0B  # <CJK>
+0x6558 0x7E22  # <CJK>
+0x6559 0x7E46  # <CJK>
+0x655A 0x7E66  # <CJK>
+0x655B 0x7E3B  # <CJK>
+0x655C 0x7E35  # <CJK>
+0x655D 0x7E39  # <CJK>
+0x655E 0x7E43  # <CJK>
+0x655F 0x7E37  # <CJK>
+0x6560 0x7E32  # <CJK>
+0x6561 0x7E3A  # <CJK>
+0x6562 0x7E67  # <CJK>
+0x6563 0x7E5D  # <CJK>
+0x6564 0x7E56  # <CJK>
+0x6565 0x7E5E  # <CJK>
+0x6566 0x7E59  # <CJK>
+0x6567 0x7E5A  # <CJK>
+0x6568 0x7E79  # <CJK>
+0x6569 0x7E6A  # <CJK>
+0x656A 0x7E69  # <CJK>
+0x656B 0x7E7C  # <CJK>
+0x656C 0x7E7B  # <CJK>
+0x656D 0x7E83  # <CJK>
+0x656E 0x7DD5  # <CJK>
+0x656F 0x7E7D  # <CJK>
+0x6570 0x8FAE  # <CJK>
+0x6571 0x7E7F  # <CJK>
+0x6572 0x7E88  # <CJK>
+0x6573 0x7E89  # <CJK>
+0x6574 0x7E8C  # <CJK>
+0x6575 0x7E92  # <CJK>
+0x6576 0x7E90  # <CJK>
+0x6577 0x7E93  # <CJK>
+0x6578 0x7E94  # <CJK>
+0x6579 0x7E96  # <CJK>
+0x657A 0x7E8E  # <CJK>
+0x657B 0x7E9B  # <CJK>
+0x657C 0x7E9C  # <CJK>
+0x657D 0x7F38  # <CJK>
+0x657E 0x7F3A  # <CJK>
+0x6621 0x7F45  # <CJK>
+0x6622 0x7F4C  # <CJK>
+0x6623 0x7F4D  # <CJK>
+0x6624 0x7F4E  # <CJK>
+0x6625 0x7F50  # <CJK>
+0x6626 0x7F51  # <CJK>
+0x6627 0x7F55  # <CJK>
+0x6628 0x7F54  # <CJK>
+0x6629 0x7F58  # <CJK>
+0x662A 0x7F5F  # <CJK>
+0x662B 0x7F60  # <CJK>
+0x662C 0x7F68  # <CJK>
+0x662D 0x7F69  # <CJK>
+0x662E 0x7F67  # <CJK>
+0x662F 0x7F78  # <CJK>
+0x6630 0x7F82  # <CJK>
+0x6631 0x7F86  # <CJK>
+0x6632 0x7F83  # <CJK>
+0x6633 0x7F88  # <CJK>
+0x6634 0x7F87  # <CJK>
+0x6635 0x7F8C  # <CJK>
+0x6636 0x7F94  # <CJK>
+0x6637 0x7F9E  # <CJK>
+0x6638 0x7F9D  # <CJK>
+0x6639 0x7F9A  # <CJK>
+0x663A 0x7FA3  # <CJK>
+0x663B 0x7FAF  # <CJK>
+0x663C 0x7FB2  # <CJK>
+0x663D 0x7FB9  # <CJK>
+0x663E 0x7FAE  # <CJK>
+0x663F 0x7FB6  # <CJK>
+0x6640 0x7FB8  # <CJK>
+0x6641 0x8B71  # <CJK>
+0x6642 0x7FC5  # <CJK>
+0x6643 0x7FC6  # <CJK>
+0x6644 0x7FCA  # <CJK>
+0x6645 0x7FD5  # <CJK>
+0x6646 0x7FD4  # <CJK>
+0x6647 0x7FE1  # <CJK>
+0x6648 0x7FE6  # <CJK>
+0x6649 0x7FE9  # <CJK>
+0x664A 0x7FF3  # <CJK>
+0x664B 0x7FF9  # <CJK>
+0x664C 0x98DC  # <CJK>
+0x664D 0x8006  # <CJK>
+0x664E 0x8004  # <CJK>
+0x664F 0x800B  # <CJK>
+0x6650 0x8012  # <CJK>
+0x6651 0x8018  # <CJK>
+0x6652 0x8019  # <CJK>
+0x6653 0x801C  # <CJK>
+0x6654 0x8021  # <CJK>
+0x6655 0x8028  # <CJK>
+0x6656 0x803F  # <CJK>
+0x6657 0x803B  # <CJK>
+0x6658 0x804A  # <CJK>
+0x6659 0x8046  # <CJK>
+0x665A 0x8052  # <CJK>
+0x665B 0x8058  # <CJK>
+0x665C 0x805A  # <CJK>
+0x665D 0x805F  # <CJK>
+0x665E 0x8062  # <CJK>
+0x665F 0x8068  # <CJK>
+0x6660 0x8073  # <CJK>
+0x6661 0x8072  # <CJK>
+0x6662 0x8070  # <CJK>
+0x6663 0x8076  # <CJK>
+0x6664 0x8079  # <CJK>
+0x6665 0x807D  # <CJK>
+0x6666 0x807F  # <CJK>
+0x6667 0x8084  # <CJK>
+0x6668 0x8086  # <CJK>
+0x6669 0x8085  # <CJK>
+0x666A 0x809B  # <CJK>
+0x666B 0x8093  # <CJK>
+0x666C 0x809A  # <CJK>
+0x666D 0x80AD  # <CJK>
+0x666E 0x5190  # <CJK>
+0x666F 0x80AC  # <CJK>
+0x6670 0x80DB  # <CJK>
+0x6671 0x80E5  # <CJK>
+0x6672 0x80D9  # <CJK>
+0x6673 0x80DD  # <CJK>
+0x6674 0x80C4  # <CJK>
+0x6675 0x80DA  # <CJK>
+0x6676 0x80D6  # <CJK>
+0x6677 0x8109  # <CJK>
+0x6678 0x80EF  # <CJK>
+0x6679 0x80F1  # <CJK>
+0x667A 0x811B  # <CJK>
+0x667B 0x8129  # <CJK>
+0x667C 0x8123  # <CJK>
+0x667D 0x812F  # <CJK>
+0x667E 0x814B  # <CJK>
+0x6721 0x968B  # <CJK>
+0x6722 0x8146  # <CJK>
+0x6723 0x813E  # <CJK>
+0x6724 0x8153  # <CJK>
+0x6725 0x8151  # <CJK>
+0x6726 0x80FC  # <CJK>
+0x6727 0x8171  # <CJK>
+0x6728 0x816E  # <CJK>
+0x6729 0x8165  # <CJK>
+0x672A 0x8166  # <CJK>
+0x672B 0x8174  # <CJK>
+0x672C 0x8183  # <CJK>
+0x672D 0x8188  # <CJK>
+0x672E 0x818A  # <CJK>
+0x672F 0x8180  # <CJK>
+0x6730 0x8182  # <CJK>
+0x6731 0x81A0  # <CJK>
+0x6732 0x8195  # <CJK>
+0x6733 0x81A4  # <CJK>
+0x6734 0x81A3  # <CJK>
+0x6735 0x815F  # <CJK>
+0x6736 0x8193  # <CJK>
+0x6737 0x81A9  # <CJK>
+0x6738 0x81B0  # <CJK>
+0x6739 0x81B5  # <CJK>
+0x673A 0x81BE  # <CJK>
+0x673B 0x81B8  # <CJK>
+0x673C 0x81BD  # <CJK>
+0x673D 0x81C0  # <CJK>
+0x673E 0x81C2  # <CJK>
+0x673F 0x81BA  # <CJK>
+0x6740 0x81C9  # <CJK>
+0x6741 0x81CD  # <CJK>
+0x6742 0x81D1  # <CJK>
+0x6743 0x81D9  # <CJK>
+0x6744 0x81D8  # <CJK>
+0x6745 0x81C8  # <CJK>
+0x6746 0x81DA  # <CJK>
+0x6747 0x81DF  # <CJK>
+0x6748 0x81E0  # <CJK>
+0x6749 0x81E7  # <CJK>
+0x674A 0x81FA  # <CJK>
+0x674B 0x81FB  # <CJK>
+0x674C 0x81FE  # <CJK>
+0x674D 0x8201  # <CJK>
+0x674E 0x8202  # <CJK>
+0x674F 0x8205  # <CJK>
+0x6750 0x8207  # <CJK>
+0x6751 0x820A  # <CJK>
+0x6752 0x820D  # <CJK>
+0x6753 0x8210  # <CJK>
+0x6754 0x8216  # <CJK>
+0x6755 0x8229  # <CJK>
+0x6756 0x822B  # <CJK>
+0x6757 0x8238  # <CJK>
+0x6758 0x8233  # <CJK>
+0x6759 0x8240  # <CJK>
+0x675A 0x8259  # <CJK>
+0x675B 0x8258  # <CJK>
+0x675C 0x825D  # <CJK>
+0x675D 0x825A  # <CJK>
+0x675E 0x825F  # <CJK>
+0x675F 0x8264  # <CJK>
+0x6760 0x8262  # <CJK>
+0x6761 0x8268  # <CJK>
+0x6762 0x826A  # <CJK>
+0x6763 0x826B  # <CJK>
+0x6764 0x822E  # <CJK>
+0x6765 0x8271  # <CJK>
+0x6766 0x8277  # <CJK>
+0x6767 0x8278  # <CJK>
+0x6768 0x827E  # <CJK>
+0x6769 0x828D  # <CJK>
+0x676A 0x8292  # <CJK>
+0x676B 0x82AB  # <CJK>
+0x676C 0x829F  # <CJK>
+0x676D 0x82BB  # <CJK>
+0x676E 0x82AC  # <CJK>
+0x676F 0x82E1  # <CJK>
+0x6770 0x82E3  # <CJK>
+0x6771 0x82DF  # <CJK>
+0x6772 0x82D2  # <CJK>
+0x6773 0x82F4  # <CJK>
+0x6774 0x82F3  # <CJK>
+0x6775 0x82FA  # <CJK>
+0x6776 0x8393  # <CJK>
+0x6777 0x8303  # <CJK>
+0x6778 0x82FB  # <CJK>
+0x6779 0x82F9  # <CJK>
+0x677A 0x82DE  # <CJK>
+0x677B 0x8306  # <CJK>
+0x677C 0x82DC  # <CJK>
+0x677D 0x8309  # <CJK>
+0x677E 0x82D9  # <CJK>
+0x6821 0x8335  # <CJK>
+0x6822 0x8334  # <CJK>
+0x6823 0x8316  # <CJK>
+0x6824 0x8332  # <CJK>
+0x6825 0x8331  # <CJK>
+0x6826 0x8340  # <CJK>
+0x6827 0x8339  # <CJK>
+0x6828 0x8350  # <CJK>
+0x6829 0x8345  # <CJK>
+0x682A 0x832F  # <CJK>
+0x682B 0x832B  # <CJK>
+0x682C 0x8317  # <CJK>
+0x682D 0x8318  # <CJK>
+0x682E 0x8385  # <CJK>
+0x682F 0x839A  # <CJK>
+0x6830 0x83AA  # <CJK>
+0x6831 0x839F  # <CJK>
+0x6832 0x83A2  # <CJK>
+0x6833 0x8396  # <CJK>
+0x6834 0x8323  # <CJK>
+0x6835 0x838E  # <CJK>
+0x6836 0x8387  # <CJK>
+0x6837 0x838A  # <CJK>
+0x6838 0x837C  # <CJK>
+0x6839 0x83B5  # <CJK>
+0x683A 0x8373  # <CJK>
+0x683B 0x8375  # <CJK>
+0x683C 0x83A0  # <CJK>
+0x683D 0x8389  # <CJK>
+0x683E 0x83A8  # <CJK>
+0x683F 0x83F4  # <CJK>
+0x6840 0x8413  # <CJK>
+0x6841 0x83EB  # <CJK>
+0x6842 0x83CE  # <CJK>
+0x6843 0x83FD  # <CJK>
+0x6844 0x8403  # <CJK>
+0x6845 0x83D8  # <CJK>
+0x6846 0x840B  # <CJK>
+0x6847 0x83C1  # <CJK>
+0x6848 0x83F7  # <CJK>
+0x6849 0x8407  # <CJK>
+0x684A 0x83E0  # <CJK>
+0x684B 0x83F2  # <CJK>
+0x684C 0x840D  # <CJK>
+0x684D 0x8422  # <CJK>
+0x684E 0x8420  # <CJK>
+0x684F 0x83BD  # <CJK>
+0x6850 0x8438  # <CJK>
+0x6851 0x8506  # <CJK>
+0x6852 0x83FB  # <CJK>
+0x6853 0x846D  # <CJK>
+0x6854 0x842A  # <CJK>
+0x6855 0x843C  # <CJK>
+0x6856 0x855A  # <CJK>
+0x6857 0x8484  # <CJK>
+0x6858 0x8477  # <CJK>
+0x6859 0x846B  # <CJK>
+0x685A 0x84AD  # <CJK>
+0x685B 0x846E  # <CJK>
+0x685C 0x8482  # <CJK>
+0x685D 0x8469  # <CJK>
+0x685E 0x8446  # <CJK>
+0x685F 0x842C  # <CJK>
+0x6860 0x846F  # <CJK>
+0x6861 0x8479  # <CJK>
+0x6862 0x8435  # <CJK>
+0x6863 0x84CA  # <CJK>
+0x6864 0x8462  # <CJK>
+0x6865 0x84B9  # <CJK>
+0x6866 0x84BF  # <CJK>
+0x6867 0x849F  # <CJK>
+0x6868 0x84D9  # <CJK>
+0x6869 0x84CD  # <CJK>
+0x686A 0x84BB  # <CJK>
+0x686B 0x84DA  # <CJK>
+0x686C 0x84D0  # <CJK>
+0x686D 0x84C1  # <CJK>
+0x686E 0x84C6  # <CJK>
+0x686F 0x84D6  # <CJK>
+0x6870 0x84A1  # <CJK>
+0x6871 0x8521  # <CJK>
+0x6872 0x84FF  # <CJK>
+0x6873 0x84F4  # <CJK>
+0x6874 0x8517  # <CJK>
+0x6875 0x8518  # <CJK>
+0x6876 0x852C  # <CJK>
+0x6877 0x851F  # <CJK>
+0x6878 0x8515  # <CJK>
+0x6879 0x8514  # <CJK>
+0x687A 0x84FC  # <CJK>
+0x687B 0x8540  # <CJK>
+0x687C 0x8563  # <CJK>
+0x687D 0x8558  # <CJK>
+0x687E 0x8548  # <CJK>
+0x6921 0x8541  # <CJK>
+0x6922 0x8602  # <CJK>
+0x6923 0x854B  # <CJK>
+0x6924 0x8555  # <CJK>
+0x6925 0x8580  # <CJK>
+0x6926 0x85A4  # <CJK>
+0x6927 0x8588  # <CJK>
+0x6928 0x8591  # <CJK>
+0x6929 0x858A  # <CJK>
+0x692A 0x85A8  # <CJK>
+0x692B 0x856D  # <CJK>
+0x692C 0x8594  # <CJK>
+0x692D 0x859B  # <CJK>
+0x692E 0x85EA  # <CJK>
+0x692F 0x8587  # <CJK>
+0x6930 0x859C  # <CJK>
+0x6931 0x8577  # <CJK>
+0x6932 0x857E  # <CJK>
+0x6933 0x8590  # <CJK>
+0x6934 0x85C9  # <CJK>
+0x6935 0x85BA  # <CJK>
+0x6936 0x85CF  # <CJK>
+0x6937 0x85B9  # <CJK>
+0x6938 0x85D0  # <CJK>
+0x6939 0x85D5  # <CJK>
+0x693A 0x85DD  # <CJK>
+0x693B 0x85E5  # <CJK>
+0x693C 0x85DC  # <CJK>
+0x693D 0x85F9  # <CJK>
+0x693E 0x860A  # <CJK>
+0x693F 0x8613  # <CJK>
+0x6940 0x860B  # <CJK>
+0x6941 0x85FE  # <CJK>
+0x6942 0x85FA  # <CJK>
+0x6943 0x8606  # <CJK>
+0x6944 0x8622  # <CJK>
+0x6945 0x861A  # <CJK>
+0x6946 0x8630  # <CJK>
+0x6947 0x863F  # <CJK>
+0x6948 0x864D  # <CJK>
+0x6949 0x4E55  # <CJK>
+0x694A 0x8654  # <CJK>
+0x694B 0x865F  # <CJK>
+0x694C 0x8667  # <CJK>
+0x694D 0x8671  # <CJK>
+0x694E 0x8693  # <CJK>
+0x694F 0x86A3  # <CJK>
+0x6950 0x86A9  # <CJK>
+0x6951 0x86AA  # <CJK>
+0x6952 0x868B  # <CJK>
+0x6953 0x868C  # <CJK>
+0x6954 0x86B6  # <CJK>
+0x6955 0x86AF  # <CJK>
+0x6956 0x86C4  # <CJK>
+0x6957 0x86C6  # <CJK>
+0x6958 0x86B0  # <CJK>
+0x6959 0x86C9  # <CJK>
+0x695A 0x8823  # <CJK>
+0x695B 0x86AB  # <CJK>
+0x695C 0x86D4  # <CJK>
+0x695D 0x86DE  # <CJK>
+0x695E 0x86E9  # <CJK>
+0x695F 0x86EC  # <CJK>
+0x6960 0x86DF  # <CJK>
+0x6961 0x86DB  # <CJK>
+0x6962 0x86EF  # <CJK>
+0x6963 0x8712  # <CJK>
+0x6964 0x8706  # <CJK>
+0x6965 0x8708  # <CJK>
+0x6966 0x8700  # <CJK>
+0x6967 0x8703  # <CJK>
+0x6968 0x86FB  # <CJK>
+0x6969 0x8711  # <CJK>
+0x696A 0x8709  # <CJK>
+0x696B 0x870D  # <CJK>
+0x696C 0x86F9  # <CJK>
+0x696D 0x870A  # <CJK>
+0x696E 0x8734  # <CJK>
+0x696F 0x873F  # <CJK>
+0x6970 0x8737  # <CJK>
+0x6971 0x873B  # <CJK>
+0x6972 0x8725  # <CJK>
+0x6973 0x8729  # <CJK>
+0x6974 0x871A  # <CJK>
+0x6975 0x8760  # <CJK>
+0x6976 0x875F  # <CJK>
+0x6977 0x8778  # <CJK>
+0x6978 0x874C  # <CJK>
+0x6979 0x874E  # <CJK>
+0x697A 0x8774  # <CJK>
+0x697B 0x8757  # <CJK>
+0x697C 0x8768  # <CJK>
+0x697D 0x876E  # <CJK>
+0x697E 0x8759  # <CJK>
+0x6A21 0x8753  # <CJK>
+0x6A22 0x8763  # <CJK>
+0x6A23 0x876A  # <CJK>
+0x6A24 0x8805  # <CJK>
+0x6A25 0x87A2  # <CJK>
+0x6A26 0x879F  # <CJK>
+0x6A27 0x8782  # <CJK>
+0x6A28 0x87AF  # <CJK>
+0x6A29 0x87CB  # <CJK>
+0x6A2A 0x87BD  # <CJK>
+0x6A2B 0x87C0  # <CJK>
+0x6A2C 0x87D0  # <CJK>
+0x6A2D 0x96D6  # <CJK>
+0x6A2E 0x87AB  # <CJK>
+0x6A2F 0x87C4  # <CJK>
+0x6A30 0x87B3  # <CJK>
+0x6A31 0x87C7  # <CJK>
+0x6A32 0x87C6  # <CJK>
+0x6A33 0x87BB  # <CJK>
+0x6A34 0x87EF  # <CJK>
+0x6A35 0x87F2  # <CJK>
+0x6A36 0x87E0  # <CJK>
+0x6A37 0x880F  # <CJK>
+0x6A38 0x880D  # <CJK>
+0x6A39 0x87FE  # <CJK>
+0x6A3A 0x87F6  # <CJK>
+0x6A3B 0x87F7  # <CJK>
+0x6A3C 0x880E  # <CJK>
+0x6A3D 0x87D2  # <CJK>
+0x6A3E 0x8811  # <CJK>
+0x6A3F 0x8816  # <CJK>
+0x6A40 0x8815  # <CJK>
+0x6A41 0x8822  # <CJK>
+0x6A42 0x8821  # <CJK>
+0x6A43 0x8831  # <CJK>
+0x6A44 0x8836  # <CJK>
+0x6A45 0x8839  # <CJK>
+0x6A46 0x8827  # <CJK>
+0x6A47 0x883B  # <CJK>
+0x6A48 0x8844  # <CJK>
+0x6A49 0x8842  # <CJK>
+0x6A4A 0x8852  # <CJK>
+0x6A4B 0x8859  # <CJK>
+0x6A4C 0x885E  # <CJK>
+0x6A4D 0x8862  # <CJK>
+0x6A4E 0x886B  # <CJK>
+0x6A4F 0x8881  # <CJK>
+0x6A50 0x887E  # <CJK>
+0x6A51 0x889E  # <CJK>
+0x6A52 0x8875  # <CJK>
+0x6A53 0x887D  # <CJK>
+0x6A54 0x88B5  # <CJK>
+0x6A55 0x8872  # <CJK>
+0x6A56 0x8882  # <CJK>
+0x6A57 0x8897  # <CJK>
+0x6A58 0x8892  # <CJK>
+0x6A59 0x88AE  # <CJK>
+0x6A5A 0x8899  # <CJK>
+0x6A5B 0x88A2  # <CJK>
+0x6A5C 0x888D  # <CJK>
+0x6A5D 0x88A4  # <CJK>
+0x6A5E 0x88B0  # <CJK>
+0x6A5F 0x88BF  # <CJK>
+0x6A60 0x88B1  # <CJK>
+0x6A61 0x88C3  # <CJK>
+0x6A62 0x88C4  # <CJK>
+0x6A63 0x88D4  # <CJK>
+0x6A64 0x88D8  # <CJK>
+0x6A65 0x88D9  # <CJK>
+0x6A66 0x88DD  # <CJK>
+0x6A67 0x88F9  # <CJK>
+0x6A68 0x8902  # <CJK>
+0x6A69 0x88FC  # <CJK>
+0x6A6A 0x88F4  # <CJK>
+0x6A6B 0x88E8  # <CJK>
+0x6A6C 0x88F2  # <CJK>
+0x6A6D 0x8904  # <CJK>
+0x6A6E 0x890C  # <CJK>
+0x6A6F 0x890A  # <CJK>
+0x6A70 0x8913  # <CJK>
+0x6A71 0x8943  # <CJK>
+0x6A72 0x891E  # <CJK>
+0x6A73 0x8925  # <CJK>
+0x6A74 0x892A  # <CJK>
+0x6A75 0x892B  # <CJK>
+0x6A76 0x8941  # <CJK>
+0x6A77 0x8944  # <CJK>
+0x6A78 0x893B  # <CJK>
+0x6A79 0x8936  # <CJK>
+0x6A7A 0x8938  # <CJK>
+0x6A7B 0x894C  # <CJK>
+0x6A7C 0x891D  # <CJK>
+0x6A7D 0x8960  # <CJK>
+0x6A7E 0x895E  # <CJK>
+0x6B21 0x8966  # <CJK>
+0x6B22 0x8964  # <CJK>
+0x6B23 0x896D  # <CJK>
+0x6B24 0x896A  # <CJK>
+0x6B25 0x896F  # <CJK>
+0x6B26 0x8974  # <CJK>
+0x6B27 0x8977  # <CJK>
+0x6B28 0x897E  # <CJK>
+0x6B29 0x8983  # <CJK>
+0x6B2A 0x8988  # <CJK>
+0x6B2B 0x898A  # <CJK>
+0x6B2C 0x8993  # <CJK>
+0x6B2D 0x8998  # <CJK>
+0x6B2E 0x89A1  # <CJK>
+0x6B2F 0x89A9  # <CJK>
+0x6B30 0x89A6  # <CJK>
+0x6B31 0x89AC  # <CJK>
+0x6B32 0x89AF  # <CJK>
+0x6B33 0x89B2  # <CJK>
+0x6B34 0x89BA  # <CJK>
+0x6B35 0x89BD  # <CJK>
+0x6B36 0x89BF  # <CJK>
+0x6B37 0x89C0  # <CJK>
+0x6B38 0x89DA  # <CJK>
+0x6B39 0x89DC  # <CJK>
+0x6B3A 0x89DD  # <CJK>
+0x6B3B 0x89E7  # <CJK>
+0x6B3C 0x89F4  # <CJK>
+0x6B3D 0x89F8  # <CJK>
+0x6B3E 0x8A03  # <CJK>
+0x6B3F 0x8A16  # <CJK>
+0x6B40 0x8A10  # <CJK>
+0x6B41 0x8A0C  # <CJK>
+0x6B42 0x8A1B  # <CJK>
+0x6B43 0x8A1D  # <CJK>
+0x6B44 0x8A25  # <CJK>
+0x6B45 0x8A36  # <CJK>
+0x6B46 0x8A41  # <CJK>
+0x6B47 0x8A5B  # <CJK>
+0x6B48 0x8A52  # <CJK>
+0x6B49 0x8A46  # <CJK>
+0x6B4A 0x8A48  # <CJK>
+0x6B4B 0x8A7C  # <CJK>
+0x6B4C 0x8A6D  # <CJK>
+0x6B4D 0x8A6C  # <CJK>
+0x6B4E 0x8A62  # <CJK>
+0x6B4F 0x8A85  # <CJK>
+0x6B50 0x8A82  # <CJK>
+0x6B51 0x8A84  # <CJK>
+0x6B52 0x8AA8  # <CJK>
+0x6B53 0x8AA1  # <CJK>
+0x6B54 0x8A91  # <CJK>
+0x6B55 0x8AA5  # <CJK>
+0x6B56 0x8AA6  # <CJK>
+0x6B57 0x8A9A  # <CJK>
+0x6B58 0x8AA3  # <CJK>
+0x6B59 0x8AC4  # <CJK>
+0x6B5A 0x8ACD  # <CJK>
+0x6B5B 0x8AC2  # <CJK>
+0x6B5C 0x8ADA  # <CJK>
+0x6B5D 0x8AEB  # <CJK>
+0x6B5E 0x8AF3  # <CJK>
+0x6B5F 0x8AE7  # <CJK>
+0x6B60 0x8AE4  # <CJK>
+0x6B61 0x8AF1  # <CJK>
+0x6B62 0x8B14  # <CJK>
+0x6B63 0x8AE0  # <CJK>
+0x6B64 0x8AE2  # <CJK>
+0x6B65 0x8AF7  # <CJK>
+0x6B66 0x8ADE  # <CJK>
+0x6B67 0x8ADB  # <CJK>
+0x6B68 0x8B0C  # <CJK>
+0x6B69 0x8B07  # <CJK>
+0x6B6A 0x8B1A  # <CJK>
+0x6B6B 0x8AE1  # <CJK>
+0x6B6C 0x8B16  # <CJK>
+0x6B6D 0x8B10  # <CJK>
+0x6B6E 0x8B17  # <CJK>
+0x6B6F 0x8B20  # <CJK>
+0x6B70 0x8B33  # <CJK>
+0x6B71 0x97AB  # <CJK>
+0x6B72 0x8B26  # <CJK>
+0x6B73 0x8B2B  # <CJK>
+0x6B74 0x8B3E  # <CJK>
+0x6B75 0x8B28  # <CJK>
+0x6B76 0x8B41  # <CJK>
+0x6B77 0x8B4C  # <CJK>
+0x6B78 0x8B4F  # <CJK>
+0x6B79 0x8B4E  # <CJK>
+0x6B7A 0x8B49  # <CJK>
+0x6B7B 0x8B56  # <CJK>
+0x6B7C 0x8B5B  # <CJK>
+0x6B7D 0x8B5A  # <CJK>
+0x6B7E 0x8B6B  # <CJK>
+0x6C21 0x8B5F  # <CJK>
+0x6C22 0x8B6C  # <CJK>
+0x6C23 0x8B6F  # <CJK>
+0x6C24 0x8B74  # <CJK>
+0x6C25 0x8B7D  # <CJK>
+0x6C26 0x8B80  # <CJK>
+0x6C27 0x8B8C  # <CJK>
+0x6C28 0x8B8E  # <CJK>
+0x6C29 0x8B92  # <CJK>
+0x6C2A 0x8B93  # <CJK>
+0x6C2B 0x8B96  # <CJK>
+0x6C2C 0x8B99  # <CJK>
+0x6C2D 0x8B9A  # <CJK>
+0x6C2E 0x8C3A  # <CJK>
+0x6C2F 0x8C41  # <CJK>
+0x6C30 0x8C3F  # <CJK>
+0x6C31 0x8C48  # <CJK>
+0x6C32 0x8C4C  # <CJK>
+0x6C33 0x8C4E  # <CJK>
+0x6C34 0x8C50  # <CJK>
+0x6C35 0x8C55  # <CJK>
+0x6C36 0x8C62  # <CJK>
+0x6C37 0x8C6C  # <CJK>
+0x6C38 0x8C78  # <CJK>
+0x6C39 0x8C7A  # <CJK>
+0x6C3A 0x8C82  # <CJK>
+0x6C3B 0x8C89  # <CJK>
+0x6C3C 0x8C85  # <CJK>
+0x6C3D 0x8C8A  # <CJK>
+0x6C3E 0x8C8D  # <CJK>
+0x6C3F 0x8C8E  # <CJK>
+0x6C40 0x8C94  # <CJK>
+0x6C41 0x8C7C  # <CJK>
+0x6C42 0x8C98  # <CJK>
+0x6C43 0x621D  # <CJK>
+0x6C44 0x8CAD  # <CJK>
+0x6C45 0x8CAA  # <CJK>
+0x6C46 0x8CBD  # <CJK>
+0x6C47 0x8CB2  # <CJK>
+0x6C48 0x8CB3  # <CJK>
+0x6C49 0x8CAE  # <CJK>
+0x6C4A 0x8CB6  # <CJK>
+0x6C4B 0x8CC8  # <CJK>
+0x6C4C 0x8CC1  # <CJK>
+0x6C4D 0x8CE4  # <CJK>
+0x6C4E 0x8CE3  # <CJK>
+0x6C4F 0x8CDA  # <CJK>
+0x6C50 0x8CFD  # <CJK>
+0x6C51 0x8CFA  # <CJK>
+0x6C52 0x8CFB  # <CJK>
+0x6C53 0x8D04  # <CJK>
+0x6C54 0x8D05  # <CJK>
+0x6C55 0x8D0A  # <CJK>
+0x6C56 0x8D07  # <CJK>
+0x6C57 0x8D0F  # <CJK>
+0x6C58 0x8D0D  # <CJK>
+0x6C59 0x8D10  # <CJK>
+0x6C5A 0x9F4E  # <CJK>
+0x6C5B 0x8D13  # <CJK>
+0x6C5C 0x8CCD  # <CJK>
+0x6C5D 0x8D14  # <CJK>
+0x6C5E 0x8D16  # <CJK>
+0x6C5F 0x8D67  # <CJK>
+0x6C60 0x8D6D  # <CJK>
+0x6C61 0x8D71  # <CJK>
+0x6C62 0x8D73  # <CJK>
+0x6C63 0x8D81  # <CJK>
+0x6C64 0x8D99  # <CJK>
+0x6C65 0x8DC2  # <CJK>
+0x6C66 0x8DBE  # <CJK>
+0x6C67 0x8DBA  # <CJK>
+0x6C68 0x8DCF  # <CJK>
+0x6C69 0x8DDA  # <CJK>
+0x6C6A 0x8DD6  # <CJK>
+0x6C6B 0x8DCC  # <CJK>
+0x6C6C 0x8DDB  # <CJK>
+0x6C6D 0x8DCB  # <CJK>
+0x6C6E 0x8DEA  # <CJK>
+0x6C6F 0x8DEB  # <CJK>
+0x6C70 0x8DDF  # <CJK>
+0x6C71 0x8DE3  # <CJK>
+0x6C72 0x8DFC  # <CJK>
+0x6C73 0x8E08  # <CJK>
+0x6C74 0x8E09  # <CJK>
+0x6C75 0x8DFF  # <CJK>
+0x6C76 0x8E1D  # <CJK>
+0x6C77 0x8E1E  # <CJK>
+0x6C78 0x8E10  # <CJK>
+0x6C79 0x8E1F  # <CJK>
+0x6C7A 0x8E42  # <CJK>
+0x6C7B 0x8E35  # <CJK>
+0x6C7C 0x8E30  # <CJK>
+0x6C7D 0x8E34  # <CJK>
+0x6C7E 0x8E4A  # <CJK>
+0x6D21 0x8E47  # <CJK>
+0x6D22 0x8E49  # <CJK>
+0x6D23 0x8E4C  # <CJK>
+0x6D24 0x8E50  # <CJK>
+0x6D25 0x8E48  # <CJK>
+0x6D26 0x8E59  # <CJK>
+0x6D27 0x8E64  # <CJK>
+0x6D28 0x8E60  # <CJK>
+0x6D29 0x8E2A  # <CJK>
+0x6D2A 0x8E63  # <CJK>
+0x6D2B 0x8E55  # <CJK>
+0x6D2C 0x8E76  # <CJK>
+0x6D2D 0x8E72  # <CJK>
+0x6D2E 0x8E7C  # <CJK>
+0x6D2F 0x8E81  # <CJK>
+0x6D30 0x8E87  # <CJK>
+0x6D31 0x8E85  # <CJK>
+0x6D32 0x8E84  # <CJK>
+0x6D33 0x8E8B  # <CJK>
+0x6D34 0x8E8A  # <CJK>
+0x6D35 0x8E93  # <CJK>
+0x6D36 0x8E91  # <CJK>
+0x6D37 0x8E94  # <CJK>
+0x6D38 0x8E99  # <CJK>
+0x6D39 0x8EAA  # <CJK>
+0x6D3A 0x8EA1  # <CJK>
+0x6D3B 0x8EAC  # <CJK>
+0x6D3C 0x8EB0  # <CJK>
+0x6D3D 0x8EC6  # <CJK>
+0x6D3E 0x8EB1  # <CJK>
+0x6D3F 0x8EBE  # <CJK>
+0x6D40 0x8EC5  # <CJK>
+0x6D41 0x8EC8  # <CJK>
+0x6D42 0x8ECB  # <CJK>
+0x6D43 0x8EDB  # <CJK>
+0x6D44 0x8EE3  # <CJK>
+0x6D45 0x8EFC  # <CJK>
+0x6D46 0x8EFB  # <CJK>
+0x6D47 0x8EEB  # <CJK>
+0x6D48 0x8EFE  # <CJK>
+0x6D49 0x8F0A  # <CJK>
+0x6D4A 0x8F05  # <CJK>
+0x6D4B 0x8F15  # <CJK>
+0x6D4C 0x8F12  # <CJK>
+0x6D4D 0x8F19  # <CJK>
+0x6D4E 0x8F13  # <CJK>
+0x6D4F 0x8F1C  # <CJK>
+0x6D50 0x8F1F  # <CJK>
+0x6D51 0x8F1B  # <CJK>
+0x6D52 0x8F0C  # <CJK>
+0x6D53 0x8F26  # <CJK>
+0x6D54 0x8F33  # <CJK>
+0x6D55 0x8F3B  # <CJK>
+0x6D56 0x8F39  # <CJK>
+0x6D57 0x8F45  # <CJK>
+0x6D58 0x8F42  # <CJK>
+0x6D59 0x8F3E  # <CJK>
+0x6D5A 0x8F4C  # <CJK>
+0x6D5B 0x8F49  # <CJK>
+0x6D5C 0x8F46  # <CJK>
+0x6D5D 0x8F4E  # <CJK>
+0x6D5E 0x8F57  # <CJK>
+0x6D5F 0x8F5C  # <CJK>
+0x6D60 0x8F62  # <CJK>
+0x6D61 0x8F63  # <CJK>
+0x6D62 0x8F64  # <CJK>
+0x6D63 0x8F9C  # <CJK>
+0x6D64 0x8F9F  # <CJK>
+0x6D65 0x8FA3  # <CJK>
+0x6D66 0x8FAD  # <CJK>
+0x6D67 0x8FAF  # <CJK>
+0x6D68 0x8FB7  # <CJK>
+0x6D69 0x8FDA  # <CJK>
+0x6D6A 0x8FE5  # <CJK>
+0x6D6B 0x8FE2  # <CJK>
+0x6D6C 0x8FEA  # <CJK>
+0x6D6D 0x8FEF  # <CJK>
+0x6D6E 0x9087  # <CJK>
+0x6D6F 0x8FF4  # <CJK>
+0x6D70 0x9005  # <CJK>
+0x6D71 0x8FF9  # <CJK>
+0x6D72 0x8FFA  # <CJK>
+0x6D73 0x9011  # <CJK>
+0x6D74 0x9015  # <CJK>
+0x6D75 0x9021  # <CJK>
+0x6D76 0x900D  # <CJK>
+0x6D77 0x901E  # <CJK>
+0x6D78 0x9016  # <CJK>
+0x6D79 0x900B  # <CJK>
+0x6D7A 0x9027  # <CJK>
+0x6D7B 0x9036  # <CJK>
+0x6D7C 0x9035  # <CJK>
+0x6D7D 0x9039  # <CJK>
+0x6D7E 0x8FF8  # <CJK>
+0x6E21 0x904F  # <CJK>
+0x6E22 0x9050  # <CJK>
+0x6E23 0x9051  # <CJK>
+0x6E24 0x9052  # <CJK>
+0x6E25 0x900E  # <CJK>
+0x6E26 0x9049  # <CJK>
+0x6E27 0x903E  # <CJK>
+0x6E28 0x9056  # <CJK>
+0x6E29 0x9058  # <CJK>
+0x6E2A 0x905E  # <CJK>
+0x6E2B 0x9068  # <CJK>
+0x6E2C 0x906F  # <CJK>
+0x6E2D 0x9076  # <CJK>
+0x6E2E 0x96A8  # <CJK>
+0x6E2F 0x9072  # <CJK>
+0x6E30 0x9082  # <CJK>
+0x6E31 0x907D  # <CJK>
+0x6E32 0x9081  # <CJK>
+0x6E33 0x9080  # <CJK>
+0x6E34 0x908A  # <CJK>
+0x6E35 0x9089  # <CJK>
+0x6E36 0x908F  # <CJK>
+0x6E37 0x90A8  # <CJK>
+0x6E38 0x90AF  # <CJK>
+0x6E39 0x90B1  # <CJK>
+0x6E3A 0x90B5  # <CJK>
+0x6E3B 0x90E2  # <CJK>
+0x6E3C 0x90E4  # <CJK>
+0x6E3D 0x6248  # <CJK>
+0x6E3E 0x90DB  # <CJK>
+0x6E3F 0x9102  # <CJK>
+0x6E40 0x9112  # <CJK>
+0x6E41 0x9119  # <CJK>
+0x6E42 0x9132  # <CJK>
+0x6E43 0x9130  # <CJK>
+0x6E44 0x914A  # <CJK>
+0x6E45 0x9156  # <CJK>
+0x6E46 0x9158  # <CJK>
+0x6E47 0x9163  # <CJK>
+0x6E48 0x9165  # <CJK>
+0x6E49 0x9169  # <CJK>
+0x6E4A 0x9173  # <CJK>
+0x6E4B 0x9172  # <CJK>
+0x6E4C 0x918B  # <CJK>
+0x6E4D 0x9189  # <CJK>
+0x6E4E 0x9182  # <CJK>
+0x6E4F 0x91A2  # <CJK>
+0x6E50 0x91AB  # <CJK>
+0x6E51 0x91AF  # <CJK>
+0x6E52 0x91AA  # <CJK>
+0x6E53 0x91B5  # <CJK>
+0x6E54 0x91B4  # <CJK>
+0x6E55 0x91BA  # <CJK>
+0x6E56 0x91C0  # <CJK>
+0x6E57 0x91C1  # <CJK>
+0x6E58 0x91C9  # <CJK>
+0x6E59 0x91CB  # <CJK>
+0x6E5A 0x91D0  # <CJK>
+0x6E5B 0x91D6  # <CJK>
+0x6E5C 0x91DF  # <CJK>
+0x6E5D 0x91E1  # <CJK>
+0x6E5E 0x91DB  # <CJK>
+0x6E5F 0x91FC  # <CJK>
+0x6E60 0x91F5  # <CJK>
+0x6E61 0x91F6  # <CJK>
+0x6E62 0x921E  # <CJK>
+0x6E63 0x91FF  # <CJK>
+0x6E64 0x9214  # <CJK>
+0x6E65 0x922C  # <CJK>
+0x6E66 0x9215  # <CJK>
+0x6E67 0x9211  # <CJK>
+0x6E68 0x925E  # <CJK>
+0x6E69 0x9257  # <CJK>
+0x6E6A 0x9245  # <CJK>
+0x6E6B 0x9249  # <CJK>
+0x6E6C 0x9264  # <CJK>
+0x6E6D 0x9248  # <CJK>
+0x6E6E 0x9295  # <CJK>
+0x6E6F 0x923F  # <CJK>
+0x6E70 0x924B  # <CJK>
+0x6E71 0x9250  # <CJK>
+0x6E72 0x929C  # <CJK>
+0x6E73 0x9296  # <CJK>
+0x6E74 0x9293  # <CJK>
+0x6E75 0x929B  # <CJK>
+0x6E76 0x925A  # <CJK>
+0x6E77 0x92CF  # <CJK>
+0x6E78 0x92B9  # <CJK>
+0x6E79 0x92B7  # <CJK>
+0x6E7A 0x92E9  # <CJK>
+0x6E7B 0x930F  # <CJK>
+0x6E7C 0x92FA  # <CJK>
+0x6E7D 0x9344  # <CJK>
+0x6E7E 0x932E  # <CJK>
+0x6F21 0x9319  # <CJK>
+0x6F22 0x9322  # <CJK>
+0x6F23 0x931A  # <CJK>
+0x6F24 0x9323  # <CJK>
+0x6F25 0x933A  # <CJK>
+0x6F26 0x9335  # <CJK>
+0x6F27 0x933B  # <CJK>
+0x6F28 0x935C  # <CJK>
+0x6F29 0x9360  # <CJK>
+0x6F2A 0x937C  # <CJK>
+0x6F2B 0x936E  # <CJK>
+0x6F2C 0x9356  # <CJK>
+0x6F2D 0x93B0  # <CJK>
+0x6F2E 0x93AC  # <CJK>
+0x6F2F 0x93AD  # <CJK>
+0x6F30 0x9394  # <CJK>
+0x6F31 0x93B9  # <CJK>
+0x6F32 0x93D6  # <CJK>
+0x6F33 0x93D7  # <CJK>
+0x6F34 0x93E8  # <CJK>
+0x6F35 0x93E5  # <CJK>
+0x6F36 0x93D8  # <CJK>
+0x6F37 0x93C3  # <CJK>
+0x6F38 0x93DD  # <CJK>
+0x6F39 0x93D0  # <CJK>
+0x6F3A 0x93C8  # <CJK>
+0x6F3B 0x93E4  # <CJK>
+0x6F3C 0x941A  # <CJK>
+0x6F3D 0x9414  # <CJK>
+0x6F3E 0x9413  # <CJK>
+0x6F3F 0x9403  # <CJK>
+0x6F40 0x9407  # <CJK>
+0x6F41 0x9410  # <CJK>
+0x6F42 0x9436  # <CJK>
+0x6F43 0x942B  # <CJK>
+0x6F44 0x9435  # <CJK>
+0x6F45 0x9421  # <CJK>
+0x6F46 0x943A  # <CJK>
+0x6F47 0x9441  # <CJK>
+0x6F48 0x9452  # <CJK>
+0x6F49 0x9444  # <CJK>
+0x6F4A 0x945B  # <CJK>
+0x6F4B 0x9460  # <CJK>
+0x6F4C 0x9462  # <CJK>
+0x6F4D 0x945E  # <CJK>
+0x6F4E 0x946A  # <CJK>
+0x6F4F 0x9229  # <CJK>
+0x6F50 0x9470  # <CJK>
+0x6F51 0x9475  # <CJK>
+0x6F52 0x9477  # <CJK>
+0x6F53 0x947D  # <CJK>
+0x6F54 0x945A  # <CJK>
+0x6F55 0x947C  # <CJK>
+0x6F56 0x947E  # <CJK>
+0x6F57 0x9481  # <CJK>
+0x6F58 0x947F  # <CJK>
+0x6F59 0x9582  # <CJK>
+0x6F5A 0x9587  # <CJK>
+0x6F5B 0x958A  # <CJK>
+0x6F5C 0x9594  # <CJK>
+0x6F5D 0x9596  # <CJK>
+0x6F5E 0x9598  # <CJK>
+0x6F5F 0x9599  # <CJK>
+0x6F60 0x95A0  # <CJK>
+0x6F61 0x95A8  # <CJK>
+0x6F62 0x95A7  # <CJK>
+0x6F63 0x95AD  # <CJK>
+0x6F64 0x95BC  # <CJK>
+0x6F65 0x95BB  # <CJK>
+0x6F66 0x95B9  # <CJK>
+0x6F67 0x95BE  # <CJK>
+0x6F68 0x95CA  # <CJK>
+0x6F69 0x6FF6  # <CJK>
+0x6F6A 0x95C3  # <CJK>
+0x6F6B 0x95CD  # <CJK>
+0x6F6C 0x95CC  # <CJK>
+0x6F6D 0x95D5  # <CJK>
+0x6F6E 0x95D4  # <CJK>
+0x6F6F 0x95D6  # <CJK>
+0x6F70 0x95DC  # <CJK>
+0x6F71 0x95E1  # <CJK>
+0x6F72 0x95E5  # <CJK>
+0x6F73 0x95E2  # <CJK>
+0x6F74 0x9621  # <CJK>
+0x6F75 0x9628  # <CJK>
+0x6F76 0x962E  # <CJK>
+0x6F77 0x962F  # <CJK>
+0x6F78 0x9642  # <CJK>
+0x6F79 0x964C  # <CJK>
+0x6F7A 0x964F  # <CJK>
+0x6F7B 0x964B  # <CJK>
+0x6F7C 0x9677  # <CJK>
+0x6F7D 0x965C  # <CJK>
+0x6F7E 0x965E  # <CJK>
+0x7021 0x965D  # <CJK>
+0x7022 0x965F  # <CJK>
+0x7023 0x9666  # <CJK>
+0x7024 0x9672  # <CJK>
+0x7025 0x966C  # <CJK>
+0x7026 0x968D  # <CJK>
+0x7027 0x9698  # <CJK>
+0x7028 0x9695  # <CJK>
+0x7029 0x9697  # <CJK>
+0x702A 0x96AA  # <CJK>
+0x702B 0x96A7  # <CJK>
+0x702C 0x96B1  # <CJK>
+0x702D 0x96B2  # <CJK>
+0x702E 0x96B0  # <CJK>
+0x702F 0x96B4  # <CJK>
+0x7030 0x96B6  # <CJK>
+0x7031 0x96B8  # <CJK>
+0x7032 0x96B9  # <CJK>
+0x7033 0x96CE  # <CJK>
+0x7034 0x96CB  # <CJK>
+0x7035 0x96C9  # <CJK>
+0x7036 0x96CD  # <CJK>
+0x7037 0x894D  # <CJK>
+0x7038 0x96DC  # <CJK>
+0x7039 0x970D  # <CJK>
+0x703A 0x96D5  # <CJK>
+0x703B 0x96F9  # <CJK>
+0x703C 0x9704  # <CJK>
+0x703D 0x9706  # <CJK>
+0x703E 0x9708  # <CJK>
+0x703F 0x9713  # <CJK>
+0x7040 0x970E  # <CJK>
+0x7041 0x9711  # <CJK>
+0x7042 0x970F  # <CJK>
+0x7043 0x9716  # <CJK>
+0x7044 0x9719  # <CJK>
+0x7045 0x9724  # <CJK>
+0x7046 0x972A  # <CJK>
+0x7047 0x9730  # <CJK>
+0x7048 0x9739  # <CJK>
+0x7049 0x973D  # <CJK>
+0x704A 0x973E  # <CJK>
+0x704B 0x9744  # <CJK>
+0x704C 0x9746  # <CJK>
+0x704D 0x9748  # <CJK>
+0x704E 0x9742  # <CJK>
+0x704F 0x9749  # <CJK>
+0x7050 0x975C  # <CJK>
+0x7051 0x9760  # <CJK>
+0x7052 0x9764  # <CJK>
+0x7053 0x9766  # <CJK>
+0x7054 0x9768  # <CJK>
+0x7055 0x52D2  # <CJK>
+0x7056 0x976B  # <CJK>
+0x7057 0x9771  # <CJK>
+0x7058 0x9779  # <CJK>
+0x7059 0x9785  # <CJK>
+0x705A 0x977C  # <CJK>
+0x705B 0x9781  # <CJK>
+0x705C 0x977A  # <CJK>
+0x705D 0x9786  # <CJK>
+0x705E 0x978B  # <CJK>
+0x705F 0x978F  # <CJK>
+0x7060 0x9790  # <CJK>
+0x7061 0x979C  # <CJK>
+0x7062 0x97A8  # <CJK>
+0x7063 0x97A6  # <CJK>
+0x7064 0x97A3  # <CJK>
+0x7065 0x97B3  # <CJK>
+0x7066 0x97B4  # <CJK>
+0x7067 0x97C3  # <CJK>
+0x7068 0x97C6  # <CJK>
+0x7069 0x97C8  # <CJK>
+0x706A 0x97CB  # <CJK>
+0x706B 0x97DC  # <CJK>
+0x706C 0x97ED  # <CJK>
+0x706D 0x9F4F  # <CJK>
+0x706E 0x97F2  # <CJK>
+0x706F 0x7ADF  # <CJK>
+0x7070 0x97F6  # <CJK>
+0x7071 0x97F5  # <CJK>
+0x7072 0x980F  # <CJK>
+0x7073 0x980C  # <CJK>
+0x7074 0x9838  # <CJK>
+0x7075 0x9824  # <CJK>
+0x7076 0x9821  # <CJK>
+0x7077 0x9837  # <CJK>
+0x7078 0x983D  # <CJK>
+0x7079 0x9846  # <CJK>
+0x707A 0x984F  # <CJK>
+0x707B 0x984B  # <CJK>
+0x707C 0x986B  # <CJK>
+0x707D 0x986F  # <CJK>
+0x707E 0x9870  # <CJK>
+0x7121 0x9871  # <CJK>
+0x7122 0x9874  # <CJK>
+0x7123 0x9873  # <CJK>
+0x7124 0x98AA  # <CJK>
+0x7125 0x98AF  # <CJK>
+0x7126 0x98B1  # <CJK>
+0x7127 0x98B6  # <CJK>
+0x7128 0x98C4  # <CJK>
+0x7129 0x98C3  # <CJK>
+0x712A 0x98C6  # <CJK>
+0x712B 0x98E9  # <CJK>
+0x712C 0x98EB  # <CJK>
+0x712D 0x9903  # <CJK>
+0x712E 0x9909  # <CJK>
+0x712F 0x9912  # <CJK>
+0x7130 0x9914  # <CJK>
+0x7131 0x9918  # <CJK>
+0x7132 0x9921  # <CJK>
+0x7133 0x991D  # <CJK>
+0x7134 0x991E  # <CJK>
+0x7135 0x9924  # <CJK>
+0x7136 0x9920  # <CJK>
+0x7137 0x992C  # <CJK>
+0x7138 0x992E  # <CJK>
+0x7139 0x993D  # <CJK>
+0x713A 0x993E  # <CJK>
+0x713B 0x9942  # <CJK>
+0x713C 0x9949  # <CJK>
+0x713D 0x9945  # <CJK>
+0x713E 0x9950  # <CJK>
+0x713F 0x994B  # <CJK>
+0x7140 0x9951  # <CJK>
+0x7141 0x9952  # <CJK>
+0x7142 0x994C  # <CJK>
+0x7143 0x9955  # <CJK>
+0x7144 0x9997  # <CJK>
+0x7145 0x9998  # <CJK>
+0x7146 0x99A5  # <CJK>
+0x7147 0x99AD  # <CJK>
+0x7148 0x99AE  # <CJK>
+0x7149 0x99BC  # <CJK>
+0x714A 0x99DF  # <CJK>
+0x714B 0x99DB  # <CJK>
+0x714C 0x99DD  # <CJK>
+0x714D 0x99D8  # <CJK>
+0x714E 0x99D1  # <CJK>
+0x714F 0x99ED  # <CJK>
+0x7150 0x99EE  # <CJK>
+0x7151 0x99F1  # <CJK>
+0x7152 0x99F2  # <CJK>
+0x7153 0x99FB  # <CJK>
+0x7154 0x99F8  # <CJK>
+0x7155 0x9A01  # <CJK>
+0x7156 0x9A0F  # <CJK>
+0x7157 0x9A05  # <CJK>
+0x7158 0x99E2  # <CJK>
+0x7159 0x9A19  # <CJK>
+0x715A 0x9A2B  # <CJK>
+0x715B 0x9A37  # <CJK>
+0x715C 0x9A45  # <CJK>
+0x715D 0x9A42  # <CJK>
+0x715E 0x9A40  # <CJK>
+0x715F 0x9A43  # <CJK>
+0x7160 0x9A3E  # <CJK>
+0x7161 0x9A55  # <CJK>
+0x7162 0x9A4D  # <CJK>
+0x7163 0x9A5B  # <CJK>
+0x7164 0x9A57  # <CJK>
+0x7165 0x9A5F  # <CJK>
+0x7166 0x9A62  # <CJK>
+0x7167 0x9A65  # <CJK>
+0x7168 0x9A64  # <CJK>
+0x7169 0x9A69  # <CJK>
+0x716A 0x9A6B  # <CJK>
+0x716B 0x9A6A  # <CJK>
+0x716C 0x9AAD  # <CJK>
+0x716D 0x9AB0  # <CJK>
+0x716E 0x9ABC  # <CJK>
+0x716F 0x9AC0  # <CJK>
+0x7170 0x9ACF  # <CJK>
+0x7171 0x9AD1  # <CJK>
+0x7172 0x9AD3  # <CJK>
+0x7173 0x9AD4  # <CJK>
+0x7174 0x9ADE  # <CJK>
+0x7175 0x9ADF  # <CJK>
+0x7176 0x9AE2  # <CJK>
+0x7177 0x9AE3  # <CJK>
+0x7178 0x9AE6  # <CJK>
+0x7179 0x9AEF  # <CJK>
+0x717A 0x9AEB  # <CJK>
+0x717B 0x9AEE  # <CJK>
+0x717C 0x9AF4  # <CJK>
+0x717D 0x9AF1  # <CJK>
+0x717E 0x9AF7  # <CJK>
+0x7221 0x9AFB  # <CJK>
+0x7222 0x9B06  # <CJK>
+0x7223 0x9B18  # <CJK>
+0x7224 0x9B1A  # <CJK>
+0x7225 0x9B1F  # <CJK>
+0x7226 0x9B22  # <CJK>
+0x7227 0x9B23  # <CJK>
+0x7228 0x9B25  # <CJK>
+0x7229 0x9B27  # <CJK>
+0x722A 0x9B28  # <CJK>
+0x722B 0x9B29  # <CJK>
+0x722C 0x9B2A  # <CJK>
+0x722D 0x9B2E  # <CJK>
+0x722E 0x9B2F  # <CJK>
+0x722F 0x9B32  # <CJK>
+0x7230 0x9B44  # <CJK>
+0x7231 0x9B43  # <CJK>
+0x7232 0x9B4F  # <CJK>
+0x7233 0x9B4D  # <CJK>
+0x7234 0x9B4E  # <CJK>
+0x7235 0x9B51  # <CJK>
+0x7236 0x9B58  # <CJK>
+0x7237 0x9B74  # <CJK>
+0x7238 0x9B93  # <CJK>
+0x7239 0x9B83  # <CJK>
+0x723A 0x9B91  # <CJK>
+0x723B 0x9B96  # <CJK>
+0x723C 0x9B97  # <CJK>
+0x723D 0x9B9F  # <CJK>
+0x723E 0x9BA0  # <CJK>
+0x723F 0x9BA8  # <CJK>
+0x7240 0x9BB4  # <CJK>
+0x7241 0x9BC0  # <CJK>
+0x7242 0x9BCA  # <CJK>
+0x7243 0x9BB9  # <CJK>
+0x7244 0x9BC6  # <CJK>
+0x7245 0x9BCF  # <CJK>
+0x7246 0x9BD1  # <CJK>
+0x7247 0x9BD2  # <CJK>
+0x7248 0x9BE3  # <CJK>
+0x7249 0x9BE2  # <CJK>
+0x724A 0x9BE4  # <CJK>
+0x724B 0x9BD4  # <CJK>
+0x724C 0x9BE1  # <CJK>
+0x724D 0x9C3A  # <CJK>
+0x724E 0x9BF2  # <CJK>
+0x724F 0x9BF1  # <CJK>
+0x7250 0x9BF0  # <CJK>
+0x7251 0x9C15  # <CJK>
+0x7252 0x9C14  # <CJK>
+0x7253 0x9C09  # <CJK>
+0x7254 0x9C13  # <CJK>
+0x7255 0x9C0C  # <CJK>
+0x7256 0x9C06  # <CJK>
+0x7257 0x9C08  # <CJK>
+0x7258 0x9C12  # <CJK>
+0x7259 0x9C0A  # <CJK>
+0x725A 0x9C04  # <CJK>
+0x725B 0x9C2E  # <CJK>
+0x725C 0x9C1B  # <CJK>
+0x725D 0x9C25  # <CJK>
+0x725E 0x9C24  # <CJK>
+0x725F 0x9C21  # <CJK>
+0x7260 0x9C30  # <CJK>
+0x7261 0x9C47  # <CJK>
+0x7262 0x9C32  # <CJK>
+0x7263 0x9C46  # <CJK>
+0x7264 0x9C3E  # <CJK>
+0x7265 0x9C5A  # <CJK>
+0x7266 0x9C60  # <CJK>
+0x7267 0x9C67  # <CJK>
+0x7268 0x9C76  # <CJK>
+0x7269 0x9C78  # <CJK>
+0x726A 0x9CE7  # <CJK>
+0x726B 0x9CEC  # <CJK>
+0x726C 0x9CF0  # <CJK>
+0x726D 0x9D09  # <CJK>
+0x726E 0x9D08  # <CJK>
+0x726F 0x9CEB  # <CJK>
+0x7270 0x9D03  # <CJK>
+0x7271 0x9D06  # <CJK>
+0x7272 0x9D2A  # <CJK>
+0x7273 0x9D26  # <CJK>
+0x7274 0x9DAF  # <CJK>
+0x7275 0x9D23  # <CJK>
+0x7276 0x9D1F  # <CJK>
+0x7277 0x9D44  # <CJK>
+0x7278 0x9D15  # <CJK>
+0x7279 0x9D12  # <CJK>
+0x727A 0x9D41  # <CJK>
+0x727B 0x9D3F  # <CJK>
+0x727C 0x9D3E  # <CJK>
+0x727D 0x9D46  # <CJK>
+0x727E 0x9D48  # <CJK>
+0x7321 0x9D5D  # <CJK>
+0x7322 0x9D5E  # <CJK>
+0x7323 0x9D64  # <CJK>
+0x7324 0x9D51  # <CJK>
+0x7325 0x9D50  # <CJK>
+0x7326 0x9D59  # <CJK>
+0x7327 0x9D72  # <CJK>
+0x7328 0x9D89  # <CJK>
+0x7329 0x9D87  # <CJK>
+0x732A 0x9DAB  # <CJK>
+0x732B 0x9D6F  # <CJK>
+0x732C 0x9D7A  # <CJK>
+0x732D 0x9D9A  # <CJK>
+0x732E 0x9DA4  # <CJK>
+0x732F 0x9DA9  # <CJK>
+0x7330 0x9DB2  # <CJK>
+0x7331 0x9DC4  # <CJK>
+0x7332 0x9DC1  # <CJK>
+0x7333 0x9DBB  # <CJK>
+0x7334 0x9DB8  # <CJK>
+0x7335 0x9DBA  # <CJK>
+0x7336 0x9DC6  # <CJK>
+0x7337 0x9DCF  # <CJK>
+0x7338 0x9DC2  # <CJK>
+0x7339 0x9DD9  # <CJK>
+0x733A 0x9DD3  # <CJK>
+0x733B 0x9DF8  # <CJK>
+0x733C 0x9DE6  # <CJK>
+0x733D 0x9DED  # <CJK>
+0x733E 0x9DEF  # <CJK>
+0x733F 0x9DFD  # <CJK>
+0x7340 0x9E1A  # <CJK>
+0x7341 0x9E1B  # <CJK>
+0x7342 0x9E1E  # <CJK>
+0x7343 0x9E75  # <CJK>
+0x7344 0x9E79  # <CJK>
+0x7345 0x9E7D  # <CJK>
+0x7346 0x9E81  # <CJK>
+0x7347 0x9E88  # <CJK>
+0x7348 0x9E8B  # <CJK>
+0x7349 0x9E8C  # <CJK>
+0x734A 0x9E92  # <CJK>
+0x734B 0x9E95  # <CJK>
+0x734C 0x9E91  # <CJK>
+0x734D 0x9E9D  # <CJK>
+0x734E 0x9EA5  # <CJK>
+0x734F 0x9EA9  # <CJK>
+0x7350 0x9EB8  # <CJK>
+0x7351 0x9EAA  # <CJK>
+0x7352 0x9EAD  # <CJK>
+0x7353 0x9761  # <CJK>
+0x7354 0x9ECC  # <CJK>
+0x7355 0x9ECE  # <CJK>
+0x7356 0x9ECF  # <CJK>
+0x7357 0x9ED0  # <CJK>
+0x7358 0x9ED4  # <CJK>
+0x7359 0x9EDC  # <CJK>
+0x735A 0x9EDE  # <CJK>
+0x735B 0x9EDD  # <CJK>
+0x735C 0x9EE0  # <CJK>
+0x735D 0x9EE5  # <CJK>
+0x735E 0x9EE8  # <CJK>
+0x735F 0x9EEF  # <CJK>
+0x7360 0x9EF4  # <CJK>
+0x7361 0x9EF6  # <CJK>
+0x7362 0x9EF7  # <CJK>
+0x7363 0x9EF9  # <CJK>
+0x7364 0x9EFB  # <CJK>
+0x7365 0x9EFC  # <CJK>
+0x7366 0x9EFD  # <CJK>
+0x7367 0x9F07  # <CJK>
+0x7368 0x9F08  # <CJK>
+0x7369 0x76B7  # <CJK>
+0x736A 0x9F15  # <CJK>
+0x736B 0x9F21  # <CJK>
+0x736C 0x9F2C  # <CJK>
+0x736D 0x9F3E  # <CJK>
+0x736E 0x9F4A  # <CJK>
+0x736F 0x9F52  # <CJK>
+0x7370 0x9F54  # <CJK>
+0x7371 0x9F63  # <CJK>
+0x7372 0x9F5F  # <CJK>
+0x7373 0x9F60  # <CJK>
+0x7374 0x9F61  # <CJK>
+0x7375 0x9F66  # <CJK>
+0x7376 0x9F67  # <CJK>
+0x7377 0x9F6C  # <CJK>
+0x7378 0x9F6A  # <CJK>
+0x7379 0x9F77  # <CJK>
+0x737A 0x9F72  # <CJK>
+0x737B 0x9F76  # <CJK>
+0x737C 0x9F95  # <CJK>
+0x737D 0x9F9C  # <CJK>
+0x737E 0x9FA0  # <CJK>
+0x7421 0x582F  # <CJK>
+0x7422 0x69C7  # <CJK>
+0x7423 0x9059  # <CJK>
+0x7424 0x7464  # <CJK>
+0x7425 0x51DC  # <CJK>
+0x7426 0x7199  # <CJK>
diff --git a/basis/io/encodings/iso2022/212.txt b/basis/io/encodings/iso2022/212.txt
new file mode 100644 (file)
index 0000000..c1ea9f3
--- /dev/null
@@ -0,0 +1,6153 @@
+#
+#      Name:             JIS X 0212 (1990) to Unicode
+#      Unicode version:  1.1
+#      Table version:    0.9
+#      Table format:     Format A
+#      Date:             8 March 1994
+#
+#      Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#      This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#      No claims are made as to fitness for any particular purpose.  No
+#      warranties of any kind are expressed or implied.  The recipient
+#      agrees to determine applicability of information provided.  If this
+#      file has been provided on magnetic media by Unicode, Inc., the sole
+#      remedy for any claim will be exchange of defective media within 90
+#      days of receipt.
+#
+#      Recipient is granted the right to make copies in any form for
+#      internal distribution and to freely use the information supplied
+#      in the creation of products supporting Unicode.  Unicode, Inc.
+#      specifically excludes the right to re-distribute this file directly
+#      to third parties or other organizations whether for profit or not.
+#
+#      General notes:
+#
+#
+# This table contains one set of mappings from JIS X 0212 into Unicode.
+# Note that these data are *possible* mappings only and may not be the
+# same as those used by actual products, nor may they be the best suited
+# for all uses.  For more information on the mappings between various code
+# pages incorporating the repertoire of JIS X 0212 and Unicode, consult the
+# VENDORS mapping data.  Normative information on the mapping between
+# JIS X 0212 and Unicode may be found in the Unihan.txt file in the
+# latest Unicode Character Database.
+#
+# If you have carefully considered the fact that the mappings in
+# this table are only one possible set of mappings between JIS X 0212 and
+# Unicode and have no normative status, but still feel that you
+# have located an error in the table that requires fixing, you may
+# report any such error to errata@unicode.org.
+#
+#
+#      Format:  Three tab-separated columns
+#               Column #1 is the JIS X 0212 code (in hex as 0xXXXX)
+#               Column #2 is the Unicode (in hex as 0xXXXX)
+#               Column #3 the Unicode name (follows a comment sign, '#')
+#                      The official names for Unicode characters U+4E00
+#                      to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#                      where XXXX is the code point.  Including all these
+#                      names in this file increases its size substantially
+#                      and needlessly.  The token "<CJK>" is used for the
+#                      name of these characters.  If necessary, it can be
+#                      expanded algorithmically by a parser or editor.
+#
+#      The entries are in JIS X 0212 order
+#
+#      The following algorithms can be used to change the hex form
+#              of JIS 0212 to other standard forms:
+#
+#              To change hex to EUC form, add 0x8080
+#              To change hex to kuten form, first subtract 0x2020.  Then
+#                      the high and low bytes correspond to the ku and ten of
+#                      the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
+#                      0x6D63 -> 0x4D43 -> 7767
+#
+#   The kanji mappings are a normative part of ISO/IEC 10646.  The
+#       non-kanji mappings are provisional, pending definition of
+#       official mappings by Japanese standards bodies
+#
+#      Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#      Notes:
+#
+#      1. JIS X 0212 apparently unified the following two symbols
+#         into a single character at 0x2922:
+#      
+#         LATIN CAPITAL LETTER D WITH STROKE
+#         LATIN CAPITAL LETTER ETH
+#
+#         However, JIS X 0212 maintains the distinction between
+#         the lowercase forms of these two elements at 0x2942 and 0x2943.
+#         Given the structre of these JIS encodings, it is clear that
+#         0x2922 and 0x2942 are intended to be a capital/small pair.
+#         Consequently, in the Unicode mapping, 0x2922 is treated as
+#         LATIN CAPITAL LETTER D WITH STROKE.
+#        
+0x222F 0x02D8  # BREVE
+0x2230 0x02C7  # CARON (Mandarin Chinese third tone)
+0x2231 0x00B8  # CEDILLA
+0x2232 0x02D9  # DOT ABOVE (Mandarin Chinese light tone)
+0x2233 0x02DD  # DOUBLE ACUTE ACCENT
+0x2234 0x00AF  # MACRON
+0x2235 0x02DB  # OGONEK
+0x2236 0x02DA  # RING ABOVE
+0x2237 0x007E  # TILDE
+0x2238 0x0384  # GREEK TONOS
+0x2239 0x0385  # GREEK DIALYTIKA TONOS
+0x2242 0x00A1  # INVERTED EXCLAMATION MARK
+0x2243 0x00A6  # BROKEN BAR
+0x2244 0x00BF  # INVERTED QUESTION MARK
+0x226B 0x00BA  # MASCULINE ORDINAL INDICATOR
+0x226C 0x00AA  # FEMININE ORDINAL INDICATOR
+0x226D 0x00A9  # COPYRIGHT SIGN
+0x226E 0x00AE  # REGISTERED SIGN
+0x226F 0x2122  # TRADE MARK SIGN
+0x2270 0x00A4  # CURRENCY SIGN
+0x2271 0x2116  # NUMERO SIGN
+0x2661 0x0386  # GREEK CAPITAL LETTER ALPHA WITH TONOS
+0x2662 0x0388  # GREEK CAPITAL LETTER EPSILON WITH TONOS
+0x2663 0x0389  # GREEK CAPITAL LETTER ETA WITH TONOS
+0x2664 0x038A  # GREEK CAPITAL LETTER IOTA WITH TONOS
+0x2665 0x03AA  # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0x2667 0x038C  # GREEK CAPITAL LETTER OMICRON WITH TONOS
+0x2669 0x038E  # GREEK CAPITAL LETTER UPSILON WITH TONOS
+0x266A 0x03AB  # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0x266C 0x038F  # GREEK CAPITAL LETTER OMEGA WITH TONOS
+0x2671 0x03AC  # GREEK SMALL LETTER ALPHA WITH TONOS
+0x2672 0x03AD  # GREEK SMALL LETTER EPSILON WITH TONOS
+0x2673 0x03AE  # GREEK SMALL LETTER ETA WITH TONOS
+0x2674 0x03AF  # GREEK SMALL LETTER IOTA WITH TONOS
+0x2675 0x03CA  # GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0x2676 0x0390  # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0x2677 0x03CC  # GREEK SMALL LETTER OMICRON WITH TONOS
+0x2678 0x03C2  # GREEK SMALL LETTER FINAL SIGMA
+0x2679 0x03CD  # GREEK SMALL LETTER UPSILON WITH TONOS
+0x267A 0x03CB  # GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0x267B 0x03B0  # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+0x267C 0x03CE  # GREEK SMALL LETTER OMEGA WITH TONOS
+0x2742 0x0402  # CYRILLIC CAPITAL LETTER DJE
+0x2743 0x0403  # CYRILLIC CAPITAL LETTER GJE
+0x2744 0x0404  # CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0x2745 0x0405  # CYRILLIC CAPITAL LETTER DZE
+0x2746 0x0406  # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0x2747 0x0407  # CYRILLIC CAPITAL LETTER YI
+0x2748 0x0408  # CYRILLIC CAPITAL LETTER JE
+0x2749 0x0409  # CYRILLIC CAPITAL LETTER LJE
+0x274A 0x040A  # CYRILLIC CAPITAL LETTER NJE
+0x274B 0x040B  # CYRILLIC CAPITAL LETTER TSHE
+0x274C 0x040C  # CYRILLIC CAPITAL LETTER KJE
+0x274D 0x040E  # CYRILLIC CAPITAL LETTER SHORT U
+0x274E 0x040F  # CYRILLIC CAPITAL LETTER DZHE
+0x2772 0x0452  # CYRILLIC SMALL LETTER DJE
+0x2773 0x0453  # CYRILLIC SMALL LETTER GJE
+0x2774 0x0454  # CYRILLIC SMALL LETTER UKRAINIAN IE
+0x2775 0x0455  # CYRILLIC SMALL LETTER DZE
+0x2776 0x0456  # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0x2777 0x0457  # CYRILLIC SMALL LETTER YI
+0x2778 0x0458  # CYRILLIC SMALL LETTER JE
+0x2779 0x0459  # CYRILLIC SMALL LETTER LJE
+0x277A 0x045A  # CYRILLIC SMALL LETTER NJE
+0x277B 0x045B  # CYRILLIC SMALL LETTER TSHE
+0x277C 0x045C  # CYRILLIC SMALL LETTER KJE
+0x277D 0x045E  # CYRILLIC SMALL LETTER SHORT U
+0x277E 0x045F  # CYRILLIC SMALL LETTER DZHE
+0x2921 0x00C6  # LATIN CAPITAL LIGATURE AE
+0x2922 0x0110  # LATIN CAPITAL LETTER D WITH STROKE
+0x2924 0x0126  # LATIN CAPITAL LETTER H WITH STROKE
+0x2926 0x0132  # LATIN CAPITAL LIGATURE IJ
+0x2928 0x0141  # LATIN CAPITAL LETTER L WITH STROKE
+0x2929 0x013F  # LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0x292B 0x014A  # LATIN CAPITAL LETTER ENG
+0x292C 0x00D8  # LATIN CAPITAL LETTER O WITH STROKE
+0x292D 0x0152  # LATIN CAPITAL LIGATURE OE
+0x292F 0x0166  # LATIN CAPITAL LETTER T WITH STROKE
+0x2930 0x00DE  # LATIN CAPITAL LETTER THORN
+0x2941 0x00E6  # LATIN SMALL LIGATURE AE
+0x2942 0x0111  # LATIN SMALL LETTER D WITH STROKE
+0x2943 0x00F0  # LATIN SMALL LETTER ETH
+0x2944 0x0127  # LATIN SMALL LETTER H WITH STROKE
+0x2945 0x0131  # LATIN SMALL LETTER DOTLESS I
+0x2946 0x0133  # LATIN SMALL LIGATURE IJ
+0x2947 0x0138  # LATIN SMALL LETTER KRA
+0x2948 0x0142  # LATIN SMALL LETTER L WITH STROKE
+0x2949 0x0140  # LATIN SMALL LETTER L WITH MIDDLE DOT
+0x294A 0x0149  # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+0x294B 0x014B  # LATIN SMALL LETTER ENG
+0x294C 0x00F8  # LATIN SMALL LETTER O WITH STROKE
+0x294D 0x0153  # LATIN SMALL LIGATURE OE
+0x294E 0x00DF  # LATIN SMALL LETTER SHARP S
+0x294F 0x0167  # LATIN SMALL LETTER T WITH STROKE
+0x2950 0x00FE  # LATIN SMALL LETTER THORN
+0x2A21 0x00C1  # LATIN CAPITAL LETTER A WITH ACUTE
+0x2A22 0x00C0  # LATIN CAPITAL LETTER A WITH GRAVE
+0x2A23 0x00C4  # LATIN CAPITAL LETTER A WITH DIAERESIS
+0x2A24 0x00C2  # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0x2A25 0x0102  # LATIN CAPITAL LETTER A WITH BREVE
+0x2A26 0x01CD  # LATIN CAPITAL LETTER A WITH CARON
+0x2A27 0x0100  # LATIN CAPITAL LETTER A WITH MACRON
+0x2A28 0x0104  # LATIN CAPITAL LETTER A WITH OGONEK
+0x2A29 0x00C5  # LATIN CAPITAL LETTER A WITH RING ABOVE
+0x2A2A 0x00C3  # LATIN CAPITAL LETTER A WITH TILDE
+0x2A2B 0x0106  # LATIN CAPITAL LETTER C WITH ACUTE
+0x2A2C 0x0108  # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+0x2A2D 0x010C  # LATIN CAPITAL LETTER C WITH CARON
+0x2A2E 0x00C7  # LATIN CAPITAL LETTER C WITH CEDILLA
+0x2A2F 0x010A  # LATIN CAPITAL LETTER C WITH DOT ABOVE
+0x2A30 0x010E  # LATIN CAPITAL LETTER D WITH CARON
+0x2A31 0x00C9  # LATIN CAPITAL LETTER E WITH ACUTE
+0x2A32 0x00C8  # LATIN CAPITAL LETTER E WITH GRAVE
+0x2A33 0x00CB  # LATIN CAPITAL LETTER E WITH DIAERESIS
+0x2A34 0x00CA  # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0x2A35 0x011A  # LATIN CAPITAL LETTER E WITH CARON
+0x2A36 0x0116  # LATIN CAPITAL LETTER E WITH DOT ABOVE
+0x2A37 0x0112  # LATIN CAPITAL LETTER E WITH MACRON
+0x2A38 0x0118  # LATIN CAPITAL LETTER E WITH OGONEK
+0x2A3A 0x011C  # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+0x2A3B 0x011E  # LATIN CAPITAL LETTER G WITH BREVE
+0x2A3C 0x0122  # LATIN CAPITAL LETTER G WITH CEDILLA
+0x2A3D 0x0120  # LATIN CAPITAL LETTER G WITH DOT ABOVE
+0x2A3E 0x0124  # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+0x2A3F 0x00CD  # LATIN CAPITAL LETTER I WITH ACUTE
+0x2A40 0x00CC  # LATIN CAPITAL LETTER I WITH GRAVE
+0x2A41 0x00CF  # LATIN CAPITAL LETTER I WITH DIAERESIS
+0x2A42 0x00CE  # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0x2A43 0x01CF  # LATIN CAPITAL LETTER I WITH CARON
+0x2A44 0x0130  # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0x2A45 0x012A  # LATIN CAPITAL LETTER I WITH MACRON
+0x2A46 0x012E  # LATIN CAPITAL LETTER I WITH OGONEK
+0x2A47 0x0128  # LATIN CAPITAL LETTER I WITH TILDE
+0x2A48 0x0134  # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+0x2A49 0x0136  # LATIN CAPITAL LETTER K WITH CEDILLA
+0x2A4A 0x0139  # LATIN CAPITAL LETTER L WITH ACUTE
+0x2A4B 0x013D  # LATIN CAPITAL LETTER L WITH CARON
+0x2A4C 0x013B  # LATIN CAPITAL LETTER L WITH CEDILLA
+0x2A4D 0x0143  # LATIN CAPITAL LETTER N WITH ACUTE
+0x2A4E 0x0147  # LATIN CAPITAL LETTER N WITH CARON
+0x2A4F 0x0145  # LATIN CAPITAL LETTER N WITH CEDILLA
+0x2A50 0x00D1  # LATIN CAPITAL LETTER N WITH TILDE
+0x2A51 0x00D3  # LATIN CAPITAL LETTER O WITH ACUTE
+0x2A52 0x00D2  # LATIN CAPITAL LETTER O WITH GRAVE
+0x2A53 0x00D6  # LATIN CAPITAL LETTER O WITH DIAERESIS
+0x2A54 0x00D4  # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0x2A55 0x01D1  # LATIN CAPITAL LETTER O WITH CARON
+0x2A56 0x0150  # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0x2A57 0x014C  # LATIN CAPITAL LETTER O WITH MACRON
+0x2A58 0x00D5  # LATIN CAPITAL LETTER O WITH TILDE
+0x2A59 0x0154  # LATIN CAPITAL LETTER R WITH ACUTE
+0x2A5A 0x0158  # LATIN CAPITAL LETTER R WITH CARON
+0x2A5B 0x0156  # LATIN CAPITAL LETTER R WITH CEDILLA
+0x2A5C 0x015A  # LATIN CAPITAL LETTER S WITH ACUTE
+0x2A5D 0x015C  # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+0x2A5E 0x0160  # LATIN CAPITAL LETTER S WITH CARON
+0x2A5F 0x015E  # LATIN CAPITAL LETTER S WITH CEDILLA
+0x2A60 0x0164  # LATIN CAPITAL LETTER T WITH CARON
+0x2A61 0x0162  # LATIN CAPITAL LETTER T WITH CEDILLA
+0x2A62 0x00DA  # LATIN CAPITAL LETTER U WITH ACUTE
+0x2A63 0x00D9  # LATIN CAPITAL LETTER U WITH GRAVE
+0x2A64 0x00DC  # LATIN CAPITAL LETTER U WITH DIAERESIS
+0x2A65 0x00DB  # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0x2A66 0x016C  # LATIN CAPITAL LETTER U WITH BREVE
+0x2A67 0x01D3  # LATIN CAPITAL LETTER U WITH CARON
+0x2A68 0x0170  # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0x2A69 0x016A  # LATIN CAPITAL LETTER U WITH MACRON
+0x2A6A 0x0172  # LATIN CAPITAL LETTER U WITH OGONEK
+0x2A6B 0x016E  # LATIN CAPITAL LETTER U WITH RING ABOVE
+0x2A6C 0x0168  # LATIN CAPITAL LETTER U WITH TILDE
+0x2A6D 0x01D7  # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+0x2A6E 0x01DB  # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+0x2A6F 0x01D9  # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+0x2A70 0x01D5  # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+0x2A71 0x0174  # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+0x2A72 0x00DD  # LATIN CAPITAL LETTER Y WITH ACUTE
+0x2A73 0x0178  # LATIN CAPITAL LETTER Y WITH DIAERESIS
+0x2A74 0x0176  # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+0x2A75 0x0179  # LATIN CAPITAL LETTER Z WITH ACUTE
+0x2A76 0x017D  # LATIN CAPITAL LETTER Z WITH CARON
+0x2A77 0x017B  # LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0x2B21 0x00E1  # LATIN SMALL LETTER A WITH ACUTE
+0x2B22 0x00E0  # LATIN SMALL LETTER A WITH GRAVE
+0x2B23 0x00E4  # LATIN SMALL LETTER A WITH DIAERESIS
+0x2B24 0x00E2  # LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x2B25 0x0103  # LATIN SMALL LETTER A WITH BREVE
+0x2B26 0x01CE  # LATIN SMALL LETTER A WITH CARON
+0x2B27 0x0101  # LATIN SMALL LETTER A WITH MACRON
+0x2B28 0x0105  # LATIN SMALL LETTER A WITH OGONEK
+0x2B29 0x00E5  # LATIN SMALL LETTER A WITH RING ABOVE
+0x2B2A 0x00E3  # LATIN SMALL LETTER A WITH TILDE
+0x2B2B 0x0107  # LATIN SMALL LETTER C WITH ACUTE
+0x2B2C 0x0109  # LATIN SMALL LETTER C WITH CIRCUMFLEX
+0x2B2D 0x010D  # LATIN SMALL LETTER C WITH CARON
+0x2B2E 0x00E7  # LATIN SMALL LETTER C WITH CEDILLA
+0x2B2F 0x010B  # LATIN SMALL LETTER C WITH DOT ABOVE
+0x2B30 0x010F  # LATIN SMALL LETTER D WITH CARON
+0x2B31 0x00E9  # LATIN SMALL LETTER E WITH ACUTE
+0x2B32 0x00E8  # LATIN SMALL LETTER E WITH GRAVE
+0x2B33 0x00EB  # LATIN SMALL LETTER E WITH DIAERESIS
+0x2B34 0x00EA  # LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x2B35 0x011B  # LATIN SMALL LETTER E WITH CARON
+0x2B36 0x0117  # LATIN SMALL LETTER E WITH DOT ABOVE
+0x2B37 0x0113  # LATIN SMALL LETTER E WITH MACRON
+0x2B38 0x0119  # LATIN SMALL LETTER E WITH OGONEK
+0x2B39 0x01F5  # LATIN SMALL LETTER G WITH ACUTE
+0x2B3A 0x011D  # LATIN SMALL LETTER G WITH CIRCUMFLEX
+0x2B3B 0x011F  # LATIN SMALL LETTER G WITH BREVE
+0x2B3D 0x0121  # LATIN SMALL LETTER G WITH DOT ABOVE
+0x2B3E 0x0125  # LATIN SMALL LETTER H WITH CIRCUMFLEX
+0x2B3F 0x00ED  # LATIN SMALL LETTER I WITH ACUTE
+0x2B40 0x00EC  # LATIN SMALL LETTER I WITH GRAVE
+0x2B41 0x00EF  # LATIN SMALL LETTER I WITH DIAERESIS
+0x2B42 0x00EE  # LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x2B43 0x01D0  # LATIN SMALL LETTER I WITH CARON
+0x2B45 0x012B  # LATIN SMALL LETTER I WITH MACRON
+0x2B46 0x012F  # LATIN SMALL LETTER I WITH OGONEK
+0x2B47 0x0129  # LATIN SMALL LETTER I WITH TILDE
+0x2B48 0x0135  # LATIN SMALL LETTER J WITH CIRCUMFLEX
+0x2B49 0x0137  # LATIN SMALL LETTER K WITH CEDILLA
+0x2B4A 0x013A  # LATIN SMALL LETTER L WITH ACUTE
+0x2B4B 0x013E  # LATIN SMALL LETTER L WITH CARON
+0x2B4C 0x013C  # LATIN SMALL LETTER L WITH CEDILLA
+0x2B4D 0x0144  # LATIN SMALL LETTER N WITH ACUTE
+0x2B4E 0x0148  # LATIN SMALL LETTER N WITH CARON
+0x2B4F 0x0146  # LATIN SMALL LETTER N WITH CEDILLA
+0x2B50 0x00F1  # LATIN SMALL LETTER N WITH TILDE
+0x2B51 0x00F3  # LATIN SMALL LETTER O WITH ACUTE
+0x2B52 0x00F2  # LATIN SMALL LETTER O WITH GRAVE
+0x2B53 0x00F6  # LATIN SMALL LETTER O WITH DIAERESIS
+0x2B54 0x00F4  # LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x2B55 0x01D2  # LATIN SMALL LETTER O WITH CARON
+0x2B56 0x0151  # LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0x2B57 0x014D  # LATIN SMALL LETTER O WITH MACRON
+0x2B58 0x00F5  # LATIN SMALL LETTER O WITH TILDE
+0x2B59 0x0155  # LATIN SMALL LETTER R WITH ACUTE
+0x2B5A 0x0159  # LATIN SMALL LETTER R WITH CARON
+0x2B5B 0x0157  # LATIN SMALL LETTER R WITH CEDILLA
+0x2B5C 0x015B  # LATIN SMALL LETTER S WITH ACUTE
+0x2B5D 0x015D  # LATIN SMALL LETTER S WITH CIRCUMFLEX
+0x2B5E 0x0161  # LATIN SMALL LETTER S WITH CARON
+0x2B5F 0x015F  # LATIN SMALL LETTER S WITH CEDILLA
+0x2B60 0x0165  # LATIN SMALL LETTER T WITH CARON
+0x2B61 0x0163  # LATIN SMALL LETTER T WITH CEDILLA
+0x2B62 0x00FA  # LATIN SMALL LETTER U WITH ACUTE
+0x2B63 0x00F9  # LATIN SMALL LETTER U WITH GRAVE
+0x2B64 0x00FC  # LATIN SMALL LETTER U WITH DIAERESIS
+0x2B65 0x00FB  # LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x2B66 0x016D  # LATIN SMALL LETTER U WITH BREVE
+0x2B67 0x01D4  # LATIN SMALL LETTER U WITH CARON
+0x2B68 0x0171  # LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0x2B69 0x016B  # LATIN SMALL LETTER U WITH MACRON
+0x2B6A 0x0173  # LATIN SMALL LETTER U WITH OGONEK
+0x2B6B 0x016F  # LATIN SMALL LETTER U WITH RING ABOVE
+0x2B6C 0x0169  # LATIN SMALL LETTER U WITH TILDE
+0x2B6D 0x01D8  # LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+0x2B6E 0x01DC  # LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+0x2B6F 0x01DA  # LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+0x2B70 0x01D6  # LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+0x2B71 0x0175  # LATIN SMALL LETTER W WITH CIRCUMFLEX
+0x2B72 0x00FD  # LATIN SMALL LETTER Y WITH ACUTE
+0x2B73 0x00FF  # LATIN SMALL LETTER Y WITH DIAERESIS
+0x2B74 0x0177  # LATIN SMALL LETTER Y WITH CIRCUMFLEX
+0x2B75 0x017A  # LATIN SMALL LETTER Z WITH ACUTE
+0x2B76 0x017E  # LATIN SMALL LETTER Z WITH CARON
+0x2B77 0x017C  # LATIN SMALL LETTER Z WITH DOT ABOVE
+0x3021 0x4E02  # <CJK>
+0x3022 0x4E04  # <CJK>
+0x3023 0x4E05  # <CJK>
+0x3024 0x4E0C  # <CJK>
+0x3025 0x4E12  # <CJK>
+0x3026 0x4E1F  # <CJK>
+0x3027 0x4E23  # <CJK>
+0x3028 0x4E24  # <CJK>
+0x3029 0x4E28  # <CJK>
+0x302A 0x4E2B  # <CJK>
+0x302B 0x4E2E  # <CJK>
+0x302C 0x4E2F  # <CJK>
+0x302D 0x4E30  # <CJK>
+0x302E 0x4E35  # <CJK>
+0x302F 0x4E40  # <CJK>
+0x3030 0x4E41  # <CJK>
+0x3031 0x4E44  # <CJK>
+0x3032 0x4E47  # <CJK>
+0x3033 0x4E51  # <CJK>
+0x3034 0x4E5A  # <CJK>
+0x3035 0x4E5C  # <CJK>
+0x3036 0x4E63  # <CJK>
+0x3037 0x4E68  # <CJK>
+0x3038 0x4E69  # <CJK>
+0x3039 0x4E74  # <CJK>
+0x303A 0x4E75  # <CJK>
+0x303B 0x4E79  # <CJK>
+0x303C 0x4E7F  # <CJK>
+0x303D 0x4E8D  # <CJK>
+0x303E 0x4E96  # <CJK>
+0x303F 0x4E97  # <CJK>
+0x3040 0x4E9D  # <CJK>
+0x3041 0x4EAF  # <CJK>
+0x3042 0x4EB9  # <CJK>
+0x3043 0x4EC3  # <CJK>
+0x3044 0x4ED0  # <CJK>
+0x3045 0x4EDA  # <CJK>
+0x3046 0x4EDB  # <CJK>
+0x3047 0x4EE0  # <CJK>
+0x3048 0x4EE1  # <CJK>
+0x3049 0x4EE2  # <CJK>
+0x304A 0x4EE8  # <CJK>
+0x304B 0x4EEF  # <CJK>
+0x304C 0x4EF1  # <CJK>
+0x304D 0x4EF3  # <CJK>
+0x304E 0x4EF5  # <CJK>
+0x304F 0x4EFD  # <CJK>
+0x3050 0x4EFE  # <CJK>
+0x3051 0x4EFF  # <CJK>
+0x3052 0x4F00  # <CJK>
+0x3053 0x4F02  # <CJK>
+0x3054 0x4F03  # <CJK>
+0x3055 0x4F08  # <CJK>
+0x3056 0x4F0B  # <CJK>
+0x3057 0x4F0C  # <CJK>
+0x3058 0x4F12  # <CJK>
+0x3059 0x4F15  # <CJK>
+0x305A 0x4F16  # <CJK>
+0x305B 0x4F17  # <CJK>
+0x305C 0x4F19  # <CJK>
+0x305D 0x4F2E  # <CJK>
+0x305E 0x4F31  # <CJK>
+0x305F 0x4F60  # <CJK>
+0x3060 0x4F33  # <CJK>
+0x3061 0x4F35  # <CJK>
+0x3062 0x4F37  # <CJK>
+0x3063 0x4F39  # <CJK>
+0x3064 0x4F3B  # <CJK>
+0x3065 0x4F3E  # <CJK>
+0x3066 0x4F40  # <CJK>
+0x3067 0x4F42  # <CJK>
+0x3068 0x4F48  # <CJK>
+0x3069 0x4F49  # <CJK>
+0x306A 0x4F4B  # <CJK>
+0x306B 0x4F4C  # <CJK>
+0x306C 0x4F52  # <CJK>
+0x306D 0x4F54  # <CJK>
+0x306E 0x4F56  # <CJK>
+0x306F 0x4F58  # <CJK>
+0x3070 0x4F5F  # <CJK>
+0x3071 0x4F63  # <CJK>
+0x3072 0x4F6A  # <CJK>
+0x3073 0x4F6C  # <CJK>
+0x3074 0x4F6E  # <CJK>
+0x3075 0x4F71  # <CJK>
+0x3076 0x4F77  # <CJK>
+0x3077 0x4F78  # <CJK>
+0x3078 0x4F79  # <CJK>
+0x3079 0x4F7A  # <CJK>
+0x307A 0x4F7D  # <CJK>
+0x307B 0x4F7E  # <CJK>
+0x307C 0x4F81  # <CJK>
+0x307D 0x4F82  # <CJK>
+0x307E 0x4F84  # <CJK>
+0x3121 0x4F85  # <CJK>
+0x3122 0x4F89  # <CJK>
+0x3123 0x4F8A  # <CJK>
+0x3124 0x4F8C  # <CJK>
+0x3125 0x4F8E  # <CJK>
+0x3126 0x4F90  # <CJK>
+0x3127 0x4F92  # <CJK>
+0x3128 0x4F93  # <CJK>
+0x3129 0x4F94  # <CJK>
+0x312A 0x4F97  # <CJK>
+0x312B 0x4F99  # <CJK>
+0x312C 0x4F9A  # <CJK>
+0x312D 0x4F9E  # <CJK>
+0x312E 0x4F9F  # <CJK>
+0x312F 0x4FB2  # <CJK>
+0x3130 0x4FB7  # <CJK>
+0x3131 0x4FB9  # <CJK>
+0x3132 0x4FBB  # <CJK>
+0x3133 0x4FBC  # <CJK>
+0x3134 0x4FBD  # <CJK>
+0x3135 0x4FBE  # <CJK>
+0x3136 0x4FC0  # <CJK>
+0x3137 0x4FC1  # <CJK>
+0x3138 0x4FC5  # <CJK>
+0x3139 0x4FC6  # <CJK>
+0x313A 0x4FC8  # <CJK>
+0x313B 0x4FC9  # <CJK>
+0x313C 0x4FCB  # <CJK>
+0x313D 0x4FCC  # <CJK>
+0x313E 0x4FCD  # <CJK>
+0x313F 0x4FCF  # <CJK>
+0x3140 0x4FD2  # <CJK>
+0x3141 0x4FDC  # <CJK>
+0x3142 0x4FE0  # <CJK>
+0x3143 0x4FE2  # <CJK>
+0x3144 0x4FF0  # <CJK>
+0x3145 0x4FF2  # <CJK>
+0x3146 0x4FFC  # <CJK>
+0x3147 0x4FFD  # <CJK>
+0x3148 0x4FFF  # <CJK>
+0x3149 0x5000  # <CJK>
+0x314A 0x5001  # <CJK>
+0x314B 0x5004  # <CJK>
+0x314C 0x5007  # <CJK>
+0x314D 0x500A  # <CJK>
+0x314E 0x500C  # <CJK>
+0x314F 0x500E  # <CJK>
+0x3150 0x5010  # <CJK>
+0x3151 0x5013  # <CJK>
+0x3152 0x5017  # <CJK>
+0x3153 0x5018  # <CJK>
+0x3154 0x501B  # <CJK>
+0x3155 0x501C  # <CJK>
+0x3156 0x501D  # <CJK>
+0x3157 0x501E  # <CJK>
+0x3158 0x5022  # <CJK>
+0x3159 0x5027  # <CJK>
+0x315A 0x502E  # <CJK>
+0x315B 0x5030  # <CJK>
+0x315C 0x5032  # <CJK>
+0x315D 0x5033  # <CJK>
+0x315E 0x5035  # <CJK>
+0x315F 0x5040  # <CJK>
+0x3160 0x5041  # <CJK>
+0x3161 0x5042  # <CJK>
+0x3162 0x5045  # <CJK>
+0x3163 0x5046  # <CJK>
+0x3164 0x504A  # <CJK>
+0x3165 0x504C  # <CJK>
+0x3166 0x504E  # <CJK>
+0x3167 0x5051  # <CJK>
+0x3168 0x5052  # <CJK>
+0x3169 0x5053  # <CJK>
+0x316A 0x5057  # <CJK>
+0x316B 0x5059  # <CJK>
+0x316C 0x505F  # <CJK>
+0x316D 0x5060  # <CJK>
+0x316E 0x5062  # <CJK>
+0x316F 0x5063  # <CJK>
+0x3170 0x5066  # <CJK>
+0x3171 0x5067  # <CJK>
+0x3172 0x506A  # <CJK>
+0x3173 0x506D  # <CJK>
+0x3174 0x5070  # <CJK>
+0x3175 0x5071  # <CJK>
+0x3176 0x503B  # <CJK>
+0x3177 0x5081  # <CJK>
+0x3178 0x5083  # <CJK>
+0x3179 0x5084  # <CJK>
+0x317A 0x5086  # <CJK>
+0x317B 0x508A  # <CJK>
+0x317C 0x508E  # <CJK>
+0x317D 0x508F  # <CJK>
+0x317E 0x5090  # <CJK>
+0x3221 0x5092  # <CJK>
+0x3222 0x5093  # <CJK>
+0x3223 0x5094  # <CJK>
+0x3224 0x5096  # <CJK>
+0x3225 0x509B  # <CJK>
+0x3226 0x509C  # <CJK>
+0x3227 0x509E  # <CJK>
+0x3228 0x509F  # <CJK>
+0x3229 0x50A0  # <CJK>
+0x322A 0x50A1  # <CJK>
+0x322B 0x50A2  # <CJK>
+0x322C 0x50AA  # <CJK>
+0x322D 0x50AF  # <CJK>
+0x322E 0x50B0  # <CJK>
+0x322F 0x50B9  # <CJK>
+0x3230 0x50BA  # <CJK>
+0x3231 0x50BD  # <CJK>
+0x3232 0x50C0  # <CJK>
+0x3233 0x50C3  # <CJK>
+0x3234 0x50C4  # <CJK>
+0x3235 0x50C7  # <CJK>
+0x3236 0x50CC  # <CJK>
+0x3237 0x50CE  # <CJK>
+0x3238 0x50D0  # <CJK>
+0x3239 0x50D3  # <CJK>
+0x323A 0x50D4  # <CJK>
+0x323B 0x50D8  # <CJK>
+0x323C 0x50DC  # <CJK>
+0x323D 0x50DD  # <CJK>
+0x323E 0x50DF  # <CJK>
+0x323F 0x50E2  # <CJK>
+0x3240 0x50E4  # <CJK>
+0x3241 0x50E6  # <CJK>
+0x3242 0x50E8  # <CJK>
+0x3243 0x50E9  # <CJK>
+0x3244 0x50EF  # <CJK>
+0x3245 0x50F1  # <CJK>
+0x3246 0x50F6  # <CJK>
+0x3247 0x50FA  # <CJK>
+0x3248 0x50FE  # <CJK>
+0x3249 0x5103  # <CJK>
+0x324A 0x5106  # <CJK>
+0x324B 0x5107  # <CJK>
+0x324C 0x5108  # <CJK>
+0x324D 0x510B  # <CJK>
+0x324E 0x510C  # <CJK>
+0x324F 0x510D  # <CJK>
+0x3250 0x510E  # <CJK>
+0x3251 0x50F2  # <CJK>
+0x3252 0x5110  # <CJK>
+0x3253 0x5117  # <CJK>
+0x3254 0x5119  # <CJK>
+0x3255 0x511B  # <CJK>
+0x3256 0x511C  # <CJK>
+0x3257 0x511D  # <CJK>
+0x3258 0x511E  # <CJK>
+0x3259 0x5123  # <CJK>
+0x325A 0x5127  # <CJK>
+0x325B 0x5128  # <CJK>
+0x325C 0x512C  # <CJK>
+0x325D 0x512D  # <CJK>
+0x325E 0x512F  # <CJK>
+0x325F 0x5131  # <CJK>
+0x3260 0x5133  # <CJK>
+0x3261 0x5134  # <CJK>
+0x3262 0x5135  # <CJK>
+0x3263 0x5138  # <CJK>
+0x3264 0x5139  # <CJK>
+0x3265 0x5142  # <CJK>
+0x3266 0x514A  # <CJK>
+0x3267 0x514F  # <CJK>
+0x3268 0x5153  # <CJK>
+0x3269 0x5155  # <CJK>
+0x326A 0x5157  # <CJK>
+0x326B 0x5158  # <CJK>
+0x326C 0x515F  # <CJK>
+0x326D 0x5164  # <CJK>
+0x326E 0x5166  # <CJK>
+0x326F 0x517E  # <CJK>
+0x3270 0x5183  # <CJK>
+0x3271 0x5184  # <CJK>
+0x3272 0x518B  # <CJK>
+0x3273 0x518E  # <CJK>
+0x3274 0x5198  # <CJK>
+0x3275 0x519D  # <CJK>
+0x3276 0x51A1  # <CJK>
+0x3277 0x51A3  # <CJK>
+0x3278 0x51AD  # <CJK>
+0x3279 0x51B8  # <CJK>
+0x327A 0x51BA  # <CJK>
+0x327B 0x51BC  # <CJK>
+0x327C 0x51BE  # <CJK>
+0x327D 0x51BF  # <CJK>
+0x327E 0x51C2  # <CJK>
+0x3321 0x51C8  # <CJK>
+0x3322 0x51CF  # <CJK>
+0x3323 0x51D1  # <CJK>
+0x3324 0x51D2  # <CJK>
+0x3325 0x51D3  # <CJK>
+0x3326 0x51D5  # <CJK>
+0x3327 0x51D8  # <CJK>
+0x3328 0x51DE  # <CJK>
+0x3329 0x51E2  # <CJK>
+0x332A 0x51E5  # <CJK>
+0x332B 0x51EE  # <CJK>
+0x332C 0x51F2  # <CJK>
+0x332D 0x51F3  # <CJK>
+0x332E 0x51F4  # <CJK>
+0x332F 0x51F7  # <CJK>
+0x3330 0x5201  # <CJK>
+0x3331 0x5202  # <CJK>
+0x3332 0x5205  # <CJK>
+0x3333 0x5212  # <CJK>
+0x3334 0x5213  # <CJK>
+0x3335 0x5215  # <CJK>
+0x3336 0x5216  # <CJK>
+0x3337 0x5218  # <CJK>
+0x3338 0x5222  # <CJK>
+0x3339 0x5228  # <CJK>
+0x333A 0x5231  # <CJK>
+0x333B 0x5232  # <CJK>
+0x333C 0x5235  # <CJK>
+0x333D 0x523C  # <CJK>
+0x333E 0x5245  # <CJK>
+0x333F 0x5249  # <CJK>
+0x3340 0x5255  # <CJK>
+0x3341 0x5257  # <CJK>
+0x3342 0x5258  # <CJK>
+0x3343 0x525A  # <CJK>
+0x3344 0x525C  # <CJK>
+0x3345 0x525F  # <CJK>
+0x3346 0x5260  # <CJK>
+0x3347 0x5261  # <CJK>
+0x3348 0x5266  # <CJK>
+0x3349 0x526E  # <CJK>
+0x334A 0x5277  # <CJK>
+0x334B 0x5278  # <CJK>
+0x334C 0x5279  # <CJK>
+0x334D 0x5280  # <CJK>
+0x334E 0x5282  # <CJK>
+0x334F 0x5285  # <CJK>
+0x3350 0x528A  # <CJK>
+0x3351 0x528C  # <CJK>
+0x3352 0x5293  # <CJK>
+0x3353 0x5295  # <CJK>
+0x3354 0x5296  # <CJK>
+0x3355 0x5297  # <CJK>
+0x3356 0x5298  # <CJK>
+0x3357 0x529A  # <CJK>
+0x3358 0x529C  # <CJK>
+0x3359 0x52A4  # <CJK>
+0x335A 0x52A5  # <CJK>
+0x335B 0x52A6  # <CJK>
+0x335C 0x52A7  # <CJK>
+0x335D 0x52AF  # <CJK>
+0x335E 0x52B0  # <CJK>
+0x335F 0x52B6  # <CJK>
+0x3360 0x52B7  # <CJK>
+0x3361 0x52B8  # <CJK>
+0x3362 0x52BA  # <CJK>
+0x3363 0x52BB  # <CJK>
+0x3364 0x52BD  # <CJK>
+0x3365 0x52C0  # <CJK>
+0x3366 0x52C4  # <CJK>
+0x3367 0x52C6  # <CJK>
+0x3368 0x52C8  # <CJK>
+0x3369 0x52CC  # <CJK>
+0x336A 0x52CF  # <CJK>
+0x336B 0x52D1  # <CJK>
+0x336C 0x52D4  # <CJK>
+0x336D 0x52D6  # <CJK>
+0x336E 0x52DB  # <CJK>
+0x336F 0x52DC  # <CJK>
+0x3370 0x52E1  # <CJK>
+0x3371 0x52E5  # <CJK>
+0x3372 0x52E8  # <CJK>
+0x3373 0x52E9  # <CJK>
+0x3374 0x52EA  # <CJK>
+0x3375 0x52EC  # <CJK>
+0x3376 0x52F0  # <CJK>
+0x3377 0x52F1  # <CJK>
+0x3378 0x52F4  # <CJK>
+0x3379 0x52F6  # <CJK>
+0x337A 0x52F7  # <CJK>
+0x337B 0x5300  # <CJK>
+0x337C 0x5303  # <CJK>
+0x337D 0x530A  # <CJK>
+0x337E 0x530B  # <CJK>
+0x3421 0x530C  # <CJK>
+0x3422 0x5311  # <CJK>
+0x3423 0x5313  # <CJK>
+0x3424 0x5318  # <CJK>
+0x3425 0x531B  # <CJK>
+0x3426 0x531C  # <CJK>
+0x3427 0x531E  # <CJK>
+0x3428 0x531F  # <CJK>
+0x3429 0x5325  # <CJK>
+0x342A 0x5327  # <CJK>
+0x342B 0x5328  # <CJK>
+0x342C 0x5329  # <CJK>
+0x342D 0x532B  # <CJK>
+0x342E 0x532C  # <CJK>
+0x342F 0x532D  # <CJK>
+0x3430 0x5330  # <CJK>
+0x3431 0x5332  # <CJK>
+0x3432 0x5335  # <CJK>
+0x3433 0x533C  # <CJK>
+0x3434 0x533D  # <CJK>
+0x3435 0x533E  # <CJK>
+0x3436 0x5342  # <CJK>
+0x3437 0x534C  # <CJK>
+0x3438 0x534B  # <CJK>
+0x3439 0x5359  # <CJK>
+0x343A 0x535B  # <CJK>
+0x343B 0x5361  # <CJK>
+0x343C 0x5363  # <CJK>
+0x343D 0x5365  # <CJK>
+0x343E 0x536C  # <CJK>
+0x343F 0x536D  # <CJK>
+0x3440 0x5372  # <CJK>
+0x3441 0x5379  # <CJK>
+0x3442 0x537E  # <CJK>
+0x3443 0x5383  # <CJK>
+0x3444 0x5387  # <CJK>
+0x3445 0x5388  # <CJK>
+0x3446 0x538E  # <CJK>
+0x3447 0x5393  # <CJK>
+0x3448 0x5394  # <CJK>
+0x3449 0x5399  # <CJK>
+0x344A 0x539D  # <CJK>
+0x344B 0x53A1  # <CJK>
+0x344C 0x53A4  # <CJK>
+0x344D 0x53AA  # <CJK>
+0x344E 0x53AB  # <CJK>
+0x344F 0x53AF  # <CJK>
+0x3450 0x53B2  # <CJK>
+0x3451 0x53B4  # <CJK>
+0x3452 0x53B5  # <CJK>
+0x3453 0x53B7  # <CJK>
+0x3454 0x53B8  # <CJK>
+0x3455 0x53BA  # <CJK>
+0x3456 0x53BD  # <CJK>
+0x3457 0x53C0  # <CJK>
+0x3458 0x53C5  # <CJK>
+0x3459 0x53CF  # <CJK>
+0x345A 0x53D2  # <CJK>
+0x345B 0x53D3  # <CJK>
+0x345C 0x53D5  # <CJK>
+0x345D 0x53DA  # <CJK>
+0x345E 0x53DD  # <CJK>
+0x345F 0x53DE  # <CJK>
+0x3460 0x53E0  # <CJK>
+0x3461 0x53E6  # <CJK>
+0x3462 0x53E7  # <CJK>
+0x3463 0x53F5  # <CJK>
+0x3464 0x5402  # <CJK>
+0x3465 0x5413  # <CJK>
+0x3466 0x541A  # <CJK>
+0x3467 0x5421  # <CJK>
+0x3468 0x5427  # <CJK>
+0x3469 0x5428  # <CJK>
+0x346A 0x542A  # <CJK>
+0x346B 0x542F  # <CJK>
+0x346C 0x5431  # <CJK>
+0x346D 0x5434  # <CJK>
+0x346E 0x5435  # <CJK>
+0x346F 0x5443  # <CJK>
+0x3470 0x5444  # <CJK>
+0x3471 0x5447  # <CJK>
+0x3472 0x544D  # <CJK>
+0x3473 0x544F  # <CJK>
+0x3474 0x545E  # <CJK>
+0x3475 0x5462  # <CJK>
+0x3476 0x5464  # <CJK>
+0x3477 0x5466  # <CJK>
+0x3478 0x5467  # <CJK>
+0x3479 0x5469  # <CJK>
+0x347A 0x546B  # <CJK>
+0x347B 0x546D  # <CJK>
+0x347C 0x546E  # <CJK>
+0x347D 0x5474  # <CJK>
+0x347E 0x547F  # <CJK>
+0x3521 0x5481  # <CJK>
+0x3522 0x5483  # <CJK>
+0x3523 0x5485  # <CJK>
+0x3524 0x5488  # <CJK>
+0x3525 0x5489  # <CJK>
+0x3526 0x548D  # <CJK>
+0x3527 0x5491  # <CJK>
+0x3528 0x5495  # <CJK>
+0x3529 0x5496  # <CJK>
+0x352A 0x549C  # <CJK>
+0x352B 0x549F  # <CJK>
+0x352C 0x54A1  # <CJK>
+0x352D 0x54A6  # <CJK>
+0x352E 0x54A7  # <CJK>
+0x352F 0x54A9  # <CJK>
+0x3530 0x54AA  # <CJK>
+0x3531 0x54AD  # <CJK>
+0x3532 0x54AE  # <CJK>
+0x3533 0x54B1  # <CJK>
+0x3534 0x54B7  # <CJK>
+0x3535 0x54B9  # <CJK>
+0x3536 0x54BA  # <CJK>
+0x3537 0x54BB  # <CJK>
+0x3538 0x54BF  # <CJK>
+0x3539 0x54C6  # <CJK>
+0x353A 0x54CA  # <CJK>
+0x353B 0x54CD  # <CJK>
+0x353C 0x54CE  # <CJK>
+0x353D 0x54E0  # <CJK>
+0x353E 0x54EA  # <CJK>
+0x353F 0x54EC  # <CJK>
+0x3540 0x54EF  # <CJK>
+0x3541 0x54F6  # <CJK>
+0x3542 0x54FC  # <CJK>
+0x3543 0x54FE  # <CJK>
+0x3544 0x54FF  # <CJK>
+0x3545 0x5500  # <CJK>
+0x3546 0x5501  # <CJK>
+0x3547 0x5505  # <CJK>
+0x3548 0x5508  # <CJK>
+0x3549 0x5509  # <CJK>
+0x354A 0x550C  # <CJK>
+0x354B 0x550D  # <CJK>
+0x354C 0x550E  # <CJK>
+0x354D 0x5515  # <CJK>
+0x354E 0x552A  # <CJK>
+0x354F 0x552B  # <CJK>
+0x3550 0x5532  # <CJK>
+0x3551 0x5535  # <CJK>
+0x3552 0x5536  # <CJK>
+0x3553 0x553B  # <CJK>
+0x3554 0x553C  # <CJK>
+0x3555 0x553D  # <CJK>
+0x3556 0x5541  # <CJK>
+0x3557 0x5547  # <CJK>
+0x3558 0x5549  # <CJK>
+0x3559 0x554A  # <CJK>
+0x355A 0x554D  # <CJK>
+0x355B 0x5550  # <CJK>
+0x355C 0x5551  # <CJK>
+0x355D 0x5558  # <CJK>
+0x355E 0x555A  # <CJK>
+0x355F 0x555B  # <CJK>
+0x3560 0x555E  # <CJK>
+0x3561 0x5560  # <CJK>
+0x3562 0x5561  # <CJK>
+0x3563 0x5564  # <CJK>
+0x3564 0x5566  # <CJK>
+0x3565 0x557F  # <CJK>
+0x3566 0x5581  # <CJK>
+0x3567 0x5582  # <CJK>
+0x3568 0x5586  # <CJK>
+0x3569 0x5588  # <CJK>
+0x356A 0x558E  # <CJK>
+0x356B 0x558F  # <CJK>
+0x356C 0x5591  # <CJK>
+0x356D 0x5592  # <CJK>
+0x356E 0x5593  # <CJK>
+0x356F 0x5594  # <CJK>
+0x3570 0x5597  # <CJK>
+0x3571 0x55A3  # <CJK>
+0x3572 0x55A4  # <CJK>
+0x3573 0x55AD  # <CJK>
+0x3574 0x55B2  # <CJK>
+0x3575 0x55BF  # <CJK>
+0x3576 0x55C1  # <CJK>
+0x3577 0x55C3  # <CJK>
+0x3578 0x55C6  # <CJK>
+0x3579 0x55C9  # <CJK>
+0x357A 0x55CB  # <CJK>
+0x357B 0x55CC  # <CJK>
+0x357C 0x55CE  # <CJK>
+0x357D 0x55D1  # <CJK>
+0x357E 0x55D2  # <CJK>
+0x3621 0x55D3  # <CJK>
+0x3622 0x55D7  # <CJK>
+0x3623 0x55D8  # <CJK>
+0x3624 0x55DB  # <CJK>
+0x3625 0x55DE  # <CJK>
+0x3626 0x55E2  # <CJK>
+0x3627 0x55E9  # <CJK>
+0x3628 0x55F6  # <CJK>
+0x3629 0x55FF  # <CJK>
+0x362A 0x5605  # <CJK>
+0x362B 0x5608  # <CJK>
+0x362C 0x560A  # <CJK>
+0x362D 0x560D  # <CJK>
+0x362E 0x560E  # <CJK>
+0x362F 0x560F  # <CJK>
+0x3630 0x5610  # <CJK>
+0x3631 0x5611  # <CJK>
+0x3632 0x5612  # <CJK>
+0x3633 0x5619  # <CJK>
+0x3634 0x562C  # <CJK>
+0x3635 0x5630  # <CJK>
+0x3636 0x5633  # <CJK>
+0x3637 0x5635  # <CJK>
+0x3638 0x5637  # <CJK>
+0x3639 0x5639  # <CJK>
+0x363A 0x563B  # <CJK>
+0x363B 0x563C  # <CJK>
+0x363C 0x563D  # <CJK>
+0x363D 0x563F  # <CJK>
+0x363E 0x5640  # <CJK>
+0x363F 0x5641  # <CJK>
+0x3640 0x5643  # <CJK>
+0x3641 0x5644  # <CJK>
+0x3642 0x5646  # <CJK>
+0x3643 0x5649  # <CJK>
+0x3644 0x564B  # <CJK>
+0x3645 0x564D  # <CJK>
+0x3646 0x564F  # <CJK>
+0x3647 0x5654  # <CJK>
+0x3648 0x565E  # <CJK>
+0x3649 0x5660  # <CJK>
+0x364A 0x5661  # <CJK>
+0x364B 0x5662  # <CJK>
+0x364C 0x5663  # <CJK>
+0x364D 0x5666  # <CJK>
+0x364E 0x5669  # <CJK>
+0x364F 0x566D  # <CJK>
+0x3650 0x566F  # <CJK>
+0x3651 0x5671  # <CJK>
+0x3652 0x5672  # <CJK>
+0x3653 0x5675  # <CJK>
+0x3654 0x5684  # <CJK>
+0x3655 0x5685  # <CJK>
+0x3656 0x5688  # <CJK>
+0x3657 0x568B  # <CJK>
+0x3658 0x568C  # <CJK>
+0x3659 0x5695  # <CJK>
+0x365A 0x5699  # <CJK>
+0x365B 0x569A  # <CJK>
+0x365C 0x569D  # <CJK>
+0x365D 0x569E  # <CJK>
+0x365E 0x569F  # <CJK>
+0x365F 0x56A6  # <CJK>
+0x3660 0x56A7  # <CJK>
+0x3661 0x56A8  # <CJK>
+0x3662 0x56A9  # <CJK>
+0x3663 0x56AB  # <CJK>
+0x3664 0x56AC  # <CJK>
+0x3665 0x56AD  # <CJK>
+0x3666 0x56B1  # <CJK>
+0x3667 0x56B3  # <CJK>
+0x3668 0x56B7  # <CJK>
+0x3669 0x56BE  # <CJK>
+0x366A 0x56C5  # <CJK>
+0x366B 0x56C9  # <CJK>
+0x366C 0x56CA  # <CJK>
+0x366D 0x56CB  # <CJK>
+0x366E 0x56CF  # <CJK>
+0x366F 0x56D0  # <CJK>
+0x3670 0x56CC  # <CJK>
+0x3671 0x56CD  # <CJK>
+0x3672 0x56D9  # <CJK>
+0x3673 0x56DC  # <CJK>
+0x3674 0x56DD  # <CJK>
+0x3675 0x56DF  # <CJK>
+0x3676 0x56E1  # <CJK>
+0x3677 0x56E4  # <CJK>
+0x3678 0x56E5  # <CJK>
+0x3679 0x56E6  # <CJK>
+0x367A 0x56E7  # <CJK>
+0x367B 0x56E8  # <CJK>
+0x367C 0x56F1  # <CJK>
+0x367D 0x56EB  # <CJK>
+0x367E 0x56ED  # <CJK>
+0x3721 0x56F6  # <CJK>
+0x3722 0x56F7  # <CJK>
+0x3723 0x5701  # <CJK>
+0x3724 0x5702  # <CJK>
+0x3725 0x5707  # <CJK>
+0x3726 0x570A  # <CJK>
+0x3727 0x570C  # <CJK>
+0x3728 0x5711  # <CJK>
+0x3729 0x5715  # <CJK>
+0x372A 0x571A  # <CJK>
+0x372B 0x571B  # <CJK>
+0x372C 0x571D  # <CJK>
+0x372D 0x5720  # <CJK>
+0x372E 0x5722  # <CJK>
+0x372F 0x5723  # <CJK>
+0x3730 0x5724  # <CJK>
+0x3731 0x5725  # <CJK>
+0x3732 0x5729  # <CJK>
+0x3733 0x572A  # <CJK>
+0x3734 0x572C  # <CJK>
+0x3735 0x572E  # <CJK>
+0x3736 0x572F  # <CJK>
+0x3737 0x5733  # <CJK>
+0x3738 0x5734  # <CJK>
+0x3739 0x573D  # <CJK>
+0x373A 0x573E  # <CJK>
+0x373B 0x573F  # <CJK>
+0x373C 0x5745  # <CJK>
+0x373D 0x5746  # <CJK>
+0x373E 0x574C  # <CJK>
+0x373F 0x574D  # <CJK>
+0x3740 0x5752  # <CJK>
+0x3741 0x5762  # <CJK>
+0x3742 0x5765  # <CJK>
+0x3743 0x5767  # <CJK>
+0x3744 0x5768  # <CJK>
+0x3745 0x576B  # <CJK>
+0x3746 0x576D  # <CJK>
+0x3747 0x576E  # <CJK>
+0x3748 0x576F  # <CJK>
+0x3749 0x5770  # <CJK>
+0x374A 0x5771  # <CJK>
+0x374B 0x5773  # <CJK>
+0x374C 0x5774  # <CJK>
+0x374D 0x5775  # <CJK>
+0x374E 0x5777  # <CJK>
+0x374F 0x5779  # <CJK>
+0x3750 0x577A  # <CJK>
+0x3751 0x577B  # <CJK>
+0x3752 0x577C  # <CJK>
+0x3753 0x577E  # <CJK>
+0x3754 0x5781  # <CJK>
+0x3755 0x5783  # <CJK>
+0x3756 0x578C  # <CJK>
+0x3757 0x5794  # <CJK>
+0x3758 0x5797  # <CJK>
+0x3759 0x5799  # <CJK>
+0x375A 0x579A  # <CJK>
+0x375B 0x579C  # <CJK>
+0x375C 0x579D  # <CJK>
+0x375D 0x579E  # <CJK>
+0x375E 0x579F  # <CJK>
+0x375F 0x57A1  # <CJK>
+0x3760 0x5795  # <CJK>
+0x3761 0x57A7  # <CJK>
+0x3762 0x57A8  # <CJK>
+0x3763 0x57A9  # <CJK>
+0x3764 0x57AC  # <CJK>
+0x3765 0x57B8  # <CJK>
+0x3766 0x57BD  # <CJK>
+0x3767 0x57C7  # <CJK>
+0x3768 0x57C8  # <CJK>
+0x3769 0x57CC  # <CJK>
+0x376A 0x57CF  # <CJK>
+0x376B 0x57D5  # <CJK>
+0x376C 0x57DD  # <CJK>
+0x376D 0x57DE  # <CJK>
+0x376E 0x57E4  # <CJK>
+0x376F 0x57E6  # <CJK>
+0x3770 0x57E7  # <CJK>
+0x3771 0x57E9  # <CJK>
+0x3772 0x57ED  # <CJK>
+0x3773 0x57F0  # <CJK>
+0x3774 0x57F5  # <CJK>
+0x3775 0x57F6  # <CJK>
+0x3776 0x57F8  # <CJK>
+0x3777 0x57FD  # <CJK>
+0x3778 0x57FE  # <CJK>
+0x3779 0x57FF  # <CJK>
+0x377A 0x5803  # <CJK>
+0x377B 0x5804  # <CJK>
+0x377C 0x5808  # <CJK>
+0x377D 0x5809  # <CJK>
+0x377E 0x57E1  # <CJK>
+0x3821 0x580C  # <CJK>
+0x3822 0x580D  # <CJK>
+0x3823 0x581B  # <CJK>
+0x3824 0x581E  # <CJK>
+0x3825 0x581F  # <CJK>
+0x3826 0x5820  # <CJK>
+0x3827 0x5826  # <CJK>
+0x3828 0x5827  # <CJK>
+0x3829 0x582D  # <CJK>
+0x382A 0x5832  # <CJK>
+0x382B 0x5839  # <CJK>
+0x382C 0x583F  # <CJK>
+0x382D 0x5849  # <CJK>
+0x382E 0x584C  # <CJK>
+0x382F 0x584D  # <CJK>
+0x3830 0x584F  # <CJK>
+0x3831 0x5850  # <CJK>
+0x3832 0x5855  # <CJK>
+0x3833 0x585F  # <CJK>
+0x3834 0x5861  # <CJK>
+0x3835 0x5864  # <CJK>
+0x3836 0x5867  # <CJK>
+0x3837 0x5868  # <CJK>
+0x3838 0x5878  # <CJK>
+0x3839 0x587C  # <CJK>
+0x383A 0x587F  # <CJK>
+0x383B 0x5880  # <CJK>
+0x383C 0x5881  # <CJK>
+0x383D 0x5887  # <CJK>
+0x383E 0x5888  # <CJK>
+0x383F 0x5889  # <CJK>
+0x3840 0x588A  # <CJK>
+0x3841 0x588C  # <CJK>
+0x3842 0x588D  # <CJK>
+0x3843 0x588F  # <CJK>
+0x3844 0x5890  # <CJK>
+0x3845 0x5894  # <CJK>
+0x3846 0x5896  # <CJK>
+0x3847 0x589D  # <CJK>
+0x3848 0x58A0  # <CJK>
+0x3849 0x58A1  # <CJK>
+0x384A 0x58A2  # <CJK>
+0x384B 0x58A6  # <CJK>
+0x384C 0x58A9  # <CJK>
+0x384D 0x58B1  # <CJK>
+0x384E 0x58B2  # <CJK>
+0x384F 0x58C4  # <CJK>
+0x3850 0x58BC  # <CJK>
+0x3851 0x58C2  # <CJK>
+0x3852 0x58C8  # <CJK>
+0x3853 0x58CD  # <CJK>
+0x3854 0x58CE  # <CJK>
+0x3855 0x58D0  # <CJK>
+0x3856 0x58D2  # <CJK>
+0x3857 0x58D4  # <CJK>
+0x3858 0x58D6  # <CJK>
+0x3859 0x58DA  # <CJK>
+0x385A 0x58DD  # <CJK>
+0x385B 0x58E1  # <CJK>
+0x385C 0x58E2  # <CJK>
+0x385D 0x58E9  # <CJK>
+0x385E 0x58F3  # <CJK>
+0x385F 0x5905  # <CJK>
+0x3860 0x5906  # <CJK>
+0x3861 0x590B  # <CJK>
+0x3862 0x590C  # <CJK>
+0x3863 0x5912  # <CJK>
+0x3864 0x5913  # <CJK>
+0x3865 0x5914  # <CJK>
+0x3866 0x8641  # <CJK>
+0x3867 0x591D  # <CJK>
+0x3868 0x5921  # <CJK>
+0x3869 0x5923  # <CJK>
+0x386A 0x5924  # <CJK>
+0x386B 0x5928  # <CJK>
+0x386C 0x592F  # <CJK>
+0x386D 0x5930  # <CJK>
+0x386E 0x5933  # <CJK>
+0x386F 0x5935  # <CJK>
+0x3870 0x5936  # <CJK>
+0x3871 0x593F  # <CJK>
+0x3872 0x5943  # <CJK>
+0x3873 0x5946  # <CJK>
+0x3874 0x5952  # <CJK>
+0x3875 0x5953  # <CJK>
+0x3876 0x5959  # <CJK>
+0x3877 0x595B  # <CJK>
+0x3878 0x595D  # <CJK>
+0x3879 0x595E  # <CJK>
+0x387A 0x595F  # <CJK>
+0x387B 0x5961  # <CJK>
+0x387C 0x5963  # <CJK>
+0x387D 0x596B  # <CJK>
+0x387E 0x596D  # <CJK>
+0x3921 0x596F  # <CJK>
+0x3922 0x5972  # <CJK>
+0x3923 0x5975  # <CJK>
+0x3924 0x5976  # <CJK>
+0x3925 0x5979  # <CJK>
+0x3926 0x597B  # <CJK>
+0x3927 0x597C  # <CJK>
+0x3928 0x598B  # <CJK>
+0x3929 0x598C  # <CJK>
+0x392A 0x598E  # <CJK>
+0x392B 0x5992  # <CJK>
+0x392C 0x5995  # <CJK>
+0x392D 0x5997  # <CJK>
+0x392E 0x599F  # <CJK>
+0x392F 0x59A4  # <CJK>
+0x3930 0x59A7  # <CJK>
+0x3931 0x59AD  # <CJK>
+0x3932 0x59AE  # <CJK>
+0x3933 0x59AF  # <CJK>
+0x3934 0x59B0  # <CJK>
+0x3935 0x59B3  # <CJK>
+0x3936 0x59B7  # <CJK>
+0x3937 0x59BA  # <CJK>
+0x3938 0x59BC  # <CJK>
+0x3939 0x59C1  # <CJK>
+0x393A 0x59C3  # <CJK>
+0x393B 0x59C4  # <CJK>
+0x393C 0x59C8  # <CJK>
+0x393D 0x59CA  # <CJK>
+0x393E 0x59CD  # <CJK>
+0x393F 0x59D2  # <CJK>
+0x3940 0x59DD  # <CJK>
+0x3941 0x59DE  # <CJK>
+0x3942 0x59DF  # <CJK>
+0x3943 0x59E3  # <CJK>
+0x3944 0x59E4  # <CJK>
+0x3945 0x59E7  # <CJK>
+0x3946 0x59EE  # <CJK>
+0x3947 0x59EF  # <CJK>
+0x3948 0x59F1  # <CJK>
+0x3949 0x59F2  # <CJK>
+0x394A 0x59F4  # <CJK>
+0x394B 0x59F7  # <CJK>
+0x394C 0x5A00  # <CJK>
+0x394D 0x5A04  # <CJK>
+0x394E 0x5A0C  # <CJK>
+0x394F 0x5A0D  # <CJK>
+0x3950 0x5A0E  # <CJK>
+0x3951 0x5A12  # <CJK>
+0x3952 0x5A13  # <CJK>
+0x3953 0x5A1E  # <CJK>
+0x3954 0x5A23  # <CJK>
+0x3955 0x5A24  # <CJK>
+0x3956 0x5A27  # <CJK>
+0x3957 0x5A28  # <CJK>
+0x3958 0x5A2A  # <CJK>
+0x3959 0x5A2D  # <CJK>
+0x395A 0x5A30  # <CJK>
+0x395B 0x5A44  # <CJK>
+0x395C 0x5A45  # <CJK>
+0x395D 0x5A47  # <CJK>
+0x395E 0x5A48  # <CJK>
+0x395F 0x5A4C  # <CJK>
+0x3960 0x5A50  # <CJK>
+0x3961 0x5A55  # <CJK>
+0x3962 0x5A5E  # <CJK>
+0x3963 0x5A63  # <CJK>
+0x3964 0x5A65  # <CJK>
+0x3965 0x5A67  # <CJK>
+0x3966 0x5A6D  # <CJK>
+0x3967 0x5A77  # <CJK>
+0x3968 0x5A7A  # <CJK>
+0x3969 0x5A7B  # <CJK>
+0x396A 0x5A7E  # <CJK>
+0x396B 0x5A8B  # <CJK>
+0x396C 0x5A90  # <CJK>
+0x396D 0x5A93  # <CJK>
+0x396E 0x5A96  # <CJK>
+0x396F 0x5A99  # <CJK>
+0x3970 0x5A9C  # <CJK>
+0x3971 0x5A9E  # <CJK>
+0x3972 0x5A9F  # <CJK>
+0x3973 0x5AA0  # <CJK>
+0x3974 0x5AA2  # <CJK>
+0x3975 0x5AA7  # <CJK>
+0x3976 0x5AAC  # <CJK>
+0x3977 0x5AB1  # <CJK>
+0x3978 0x5AB2  # <CJK>
+0x3979 0x5AB3  # <CJK>
+0x397A 0x5AB5  # <CJK>
+0x397B 0x5AB8  # <CJK>
+0x397C 0x5ABA  # <CJK>
+0x397D 0x5ABB  # <CJK>
+0x397E 0x5ABF  # <CJK>
+0x3A21 0x5AC4  # <CJK>
+0x3A22 0x5AC6  # <CJK>
+0x3A23 0x5AC8  # <CJK>
+0x3A24 0x5ACF  # <CJK>
+0x3A25 0x5ADA  # <CJK>
+0x3A26 0x5ADC  # <CJK>
+0x3A27 0x5AE0  # <CJK>
+0x3A28 0x5AE5  # <CJK>
+0x3A29 0x5AEA  # <CJK>
+0x3A2A 0x5AEE  # <CJK>
+0x3A2B 0x5AF5  # <CJK>
+0x3A2C 0x5AF6  # <CJK>
+0x3A2D 0x5AFD  # <CJK>
+0x3A2E 0x5B00  # <CJK>
+0x3A2F 0x5B01  # <CJK>
+0x3A30 0x5B08  # <CJK>
+0x3A31 0x5B17  # <CJK>
+0x3A32 0x5B34  # <CJK>
+0x3A33 0x5B19  # <CJK>
+0x3A34 0x5B1B  # <CJK>
+0x3A35 0x5B1D  # <CJK>
+0x3A36 0x5B21  # <CJK>
+0x3A37 0x5B25  # <CJK>
+0x3A38 0x5B2D  # <CJK>
+0x3A39 0x5B38  # <CJK>
+0x3A3A 0x5B41  # <CJK>
+0x3A3B 0x5B4B  # <CJK>
+0x3A3C 0x5B4C  # <CJK>
+0x3A3D 0x5B52  # <CJK>
+0x3A3E 0x5B56  # <CJK>
+0x3A3F 0x5B5E  # <CJK>
+0x3A40 0x5B68  # <CJK>
+0x3A41 0x5B6E  # <CJK>
+0x3A42 0x5B6F  # <CJK>
+0x3A43 0x5B7C  # <CJK>
+0x3A44 0x5B7D  # <CJK>
+0x3A45 0x5B7E  # <CJK>
+0x3A46 0x5B7F  # <CJK>
+0x3A47 0x5B81  # <CJK>
+0x3A48 0x5B84  # <CJK>
+0x3A49 0x5B86  # <CJK>
+0x3A4A 0x5B8A  # <CJK>
+0x3A4B 0x5B8E  # <CJK>
+0x3A4C 0x5B90  # <CJK>
+0x3A4D 0x5B91  # <CJK>
+0x3A4E 0x5B93  # <CJK>
+0x3A4F 0x5B94  # <CJK>
+0x3A50 0x5B96  # <CJK>
+0x3A51 0x5BA8  # <CJK>
+0x3A52 0x5BA9  # <CJK>
+0x3A53 0x5BAC  # <CJK>
+0x3A54 0x5BAD  # <CJK>
+0x3A55 0x5BAF  # <CJK>
+0x3A56 0x5BB1  # <CJK>
+0x3A57 0x5BB2  # <CJK>
+0x3A58 0x5BB7  # <CJK>
+0x3A59 0x5BBA  # <CJK>
+0x3A5A 0x5BBC  # <CJK>
+0x3A5B 0x5BC0  # <CJK>
+0x3A5C 0x5BC1  # <CJK>
+0x3A5D 0x5BCD  # <CJK>
+0x3A5E 0x5BCF  # <CJK>
+0x3A5F 0x5BD6  # <CJK>
+0x3A60 0x5BD7  # <CJK>
+0x3A61 0x5BD8  # <CJK>
+0x3A62 0x5BD9  # <CJK>
+0x3A63 0x5BDA  # <CJK>
+0x3A64 0x5BE0  # <CJK>
+0x3A65 0x5BEF  # <CJK>
+0x3A66 0x5BF1  # <CJK>
+0x3A67 0x5BF4  # <CJK>
+0x3A68 0x5BFD  # <CJK>
+0x3A69 0x5C0C  # <CJK>
+0x3A6A 0x5C17  # <CJK>
+0x3A6B 0x5C1E  # <CJK>
+0x3A6C 0x5C1F  # <CJK>
+0x3A6D 0x5C23  # <CJK>
+0x3A6E 0x5C26  # <CJK>
+0x3A6F 0x5C29  # <CJK>
+0x3A70 0x5C2B  # <CJK>
+0x3A71 0x5C2C  # <CJK>
+0x3A72 0x5C2E  # <CJK>
+0x3A73 0x5C30  # <CJK>
+0x3A74 0x5C32  # <CJK>
+0x3A75 0x5C35  # <CJK>
+0x3A76 0x5C36  # <CJK>
+0x3A77 0x5C59  # <CJK>
+0x3A78 0x5C5A  # <CJK>
+0x3A79 0x5C5C  # <CJK>
+0x3A7A 0x5C62  # <CJK>
+0x3A7B 0x5C63  # <CJK>
+0x3A7C 0x5C67  # <CJK>
+0x3A7D 0x5C68  # <CJK>
+0x3A7E 0x5C69  # <CJK>
+0x3B21 0x5C6D  # <CJK>
+0x3B22 0x5C70  # <CJK>
+0x3B23 0x5C74  # <CJK>
+0x3B24 0x5C75  # <CJK>
+0x3B25 0x5C7A  # <CJK>
+0x3B26 0x5C7B  # <CJK>
+0x3B27 0x5C7C  # <CJK>
+0x3B28 0x5C7D  # <CJK>
+0x3B29 0x5C87  # <CJK>
+0x3B2A 0x5C88  # <CJK>
+0x3B2B 0x5C8A  # <CJK>
+0x3B2C 0x5C8F  # <CJK>
+0x3B2D 0x5C92  # <CJK>
+0x3B2E 0x5C9D  # <CJK>
+0x3B2F 0x5C9F  # <CJK>
+0x3B30 0x5CA0  # <CJK>
+0x3B31 0x5CA2  # <CJK>
+0x3B32 0x5CA3  # <CJK>
+0x3B33 0x5CA6  # <CJK>
+0x3B34 0x5CAA  # <CJK>
+0x3B35 0x5CB2  # <CJK>
+0x3B36 0x5CB4  # <CJK>
+0x3B37 0x5CB5  # <CJK>
+0x3B38 0x5CBA  # <CJK>
+0x3B39 0x5CC9  # <CJK>
+0x3B3A 0x5CCB  # <CJK>
+0x3B3B 0x5CD2  # <CJK>
+0x3B3C 0x5CDD  # <CJK>
+0x3B3D 0x5CD7  # <CJK>
+0x3B3E 0x5CEE  # <CJK>
+0x3B3F 0x5CF1  # <CJK>
+0x3B40 0x5CF2  # <CJK>
+0x3B41 0x5CF4  # <CJK>
+0x3B42 0x5D01  # <CJK>
+0x3B43 0x5D06  # <CJK>
+0x3B44 0x5D0D  # <CJK>
+0x3B45 0x5D12  # <CJK>
+0x3B46 0x5D2B  # <CJK>
+0x3B47 0x5D23  # <CJK>
+0x3B48 0x5D24  # <CJK>
+0x3B49 0x5D26  # <CJK>
+0x3B4A 0x5D27  # <CJK>
+0x3B4B 0x5D31  # <CJK>
+0x3B4C 0x5D34  # <CJK>
+0x3B4D 0x5D39  # <CJK>
+0x3B4E 0x5D3D  # <CJK>
+0x3B4F 0x5D3F  # <CJK>
+0x3B50 0x5D42  # <CJK>
+0x3B51 0x5D43  # <CJK>
+0x3B52 0x5D46  # <CJK>
+0x3B53 0x5D48  # <CJK>
+0x3B54 0x5D55  # <CJK>
+0x3B55 0x5D51  # <CJK>
+0x3B56 0x5D59  # <CJK>
+0x3B57 0x5D4A  # <CJK>
+0x3B58 0x5D5F  # <CJK>
+0x3B59 0x5D60  # <CJK>
+0x3B5A 0x5D61  # <CJK>
+0x3B5B 0x5D62  # <CJK>
+0x3B5C 0x5D64  # <CJK>
+0x3B5D 0x5D6A  # <CJK>
+0x3B5E 0x5D6D  # <CJK>
+0x3B5F 0x5D70  # <CJK>
+0x3B60 0x5D79  # <CJK>
+0x3B61 0x5D7A  # <CJK>
+0x3B62 0x5D7E  # <CJK>
+0x3B63 0x5D7F  # <CJK>
+0x3B64 0x5D81  # <CJK>
+0x3B65 0x5D83  # <CJK>
+0x3B66 0x5D88  # <CJK>
+0x3B67 0x5D8A  # <CJK>
+0x3B68 0x5D92  # <CJK>
+0x3B69 0x5D93  # <CJK>
+0x3B6A 0x5D94  # <CJK>
+0x3B6B 0x5D95  # <CJK>
+0x3B6C 0x5D99  # <CJK>
+0x3B6D 0x5D9B  # <CJK>
+0x3B6E 0x5D9F  # <CJK>
+0x3B6F 0x5DA0  # <CJK>
+0x3B70 0x5DA7  # <CJK>
+0x3B71 0x5DAB  # <CJK>
+0x3B72 0x5DB0  # <CJK>
+0x3B73 0x5DB4  # <CJK>
+0x3B74 0x5DB8  # <CJK>
+0x3B75 0x5DB9  # <CJK>
+0x3B76 0x5DC3  # <CJK>
+0x3B77 0x5DC7  # <CJK>
+0x3B78 0x5DCB  # <CJK>
+0x3B79 0x5DD0  # <CJK>
+0x3B7A 0x5DCE  # <CJK>
+0x3B7B 0x5DD8  # <CJK>
+0x3B7C 0x5DD9  # <CJK>
+0x3B7D 0x5DE0  # <CJK>
+0x3B7E 0x5DE4  # <CJK>
+0x3C21 0x5DE9  # <CJK>
+0x3C22 0x5DF8  # <CJK>
+0x3C23 0x5DF9  # <CJK>
+0x3C24 0x5E00  # <CJK>
+0x3C25 0x5E07  # <CJK>
+0x3C26 0x5E0D  # <CJK>
+0x3C27 0x5E12  # <CJK>
+0x3C28 0x5E14  # <CJK>
+0x3C29 0x5E15  # <CJK>
+0x3C2A 0x5E18  # <CJK>
+0x3C2B 0x5E1F  # <CJK>
+0x3C2C 0x5E20  # <CJK>
+0x3C2D 0x5E2E  # <CJK>
+0x3C2E 0x5E28  # <CJK>
+0x3C2F 0x5E32  # <CJK>
+0x3C30 0x5E35  # <CJK>
+0x3C31 0x5E3E  # <CJK>
+0x3C32 0x5E4B  # <CJK>
+0x3C33 0x5E50  # <CJK>
+0x3C34 0x5E49  # <CJK>
+0x3C35 0x5E51  # <CJK>
+0x3C36 0x5E56  # <CJK>
+0x3C37 0x5E58  # <CJK>
+0x3C38 0x5E5B  # <CJK>
+0x3C39 0x5E5C  # <CJK>
+0x3C3A 0x5E5E  # <CJK>
+0x3C3B 0x5E68  # <CJK>
+0x3C3C 0x5E6A  # <CJK>
+0x3C3D 0x5E6B  # <CJK>
+0x3C3E 0x5E6C  # <CJK>
+0x3C3F 0x5E6D  # <CJK>
+0x3C40 0x5E6E  # <CJK>
+0x3C41 0x5E70  # <CJK>
+0x3C42 0x5E80  # <CJK>
+0x3C43 0x5E8B  # <CJK>
+0x3C44 0x5E8E  # <CJK>
+0x3C45 0x5EA2  # <CJK>
+0x3C46 0x5EA4  # <CJK>
+0x3C47 0x5EA5  # <CJK>
+0x3C48 0x5EA8  # <CJK>
+0x3C49 0x5EAA  # <CJK>
+0x3C4A 0x5EAC  # <CJK>
+0x3C4B 0x5EB1  # <CJK>
+0x3C4C 0x5EB3  # <CJK>
+0x3C4D 0x5EBD  # <CJK>
+0x3C4E 0x5EBE  # <CJK>
+0x3C4F 0x5EBF  # <CJK>
+0x3C50 0x5EC6  # <CJK>
+0x3C51 0x5ECC  # <CJK>
+0x3C52 0x5ECB  # <CJK>
+0x3C53 0x5ECE  # <CJK>
+0x3C54 0x5ED1  # <CJK>
+0x3C55 0x5ED2  # <CJK>
+0x3C56 0x5ED4  # <CJK>
+0x3C57 0x5ED5  # <CJK>
+0x3C58 0x5EDC  # <CJK>
+0x3C59 0x5EDE  # <CJK>
+0x3C5A 0x5EE5  # <CJK>
+0x3C5B 0x5EEB  # <CJK>
+0x3C5C 0x5F02  # <CJK>
+0x3C5D 0x5F06  # <CJK>
+0x3C5E 0x5F07  # <CJK>
+0x3C5F 0x5F08  # <CJK>
+0x3C60 0x5F0E  # <CJK>
+0x3C61 0x5F19  # <CJK>
+0x3C62 0x5F1C  # <CJK>
+0x3C63 0x5F1D  # <CJK>
+0x3C64 0x5F21  # <CJK>
+0x3C65 0x5F22  # <CJK>
+0x3C66 0x5F23  # <CJK>
+0x3C67 0x5F24  # <CJK>
+0x3C68 0x5F28  # <CJK>
+0x3C69 0x5F2B  # <CJK>
+0x3C6A 0x5F2C  # <CJK>
+0x3C6B 0x5F2E  # <CJK>
+0x3C6C 0x5F30  # <CJK>
+0x3C6D 0x5F34  # <CJK>
+0x3C6E 0x5F36  # <CJK>
+0x3C6F 0x5F3B  # <CJK>
+0x3C70 0x5F3D  # <CJK>
+0x3C71 0x5F3F  # <CJK>
+0x3C72 0x5F40  # <CJK>
+0x3C73 0x5F44  # <CJK>
+0x3C74 0x5F45  # <CJK>
+0x3C75 0x5F47  # <CJK>
+0x3C76 0x5F4D  # <CJK>
+0x3C77 0x5F50  # <CJK>
+0x3C78 0x5F54  # <CJK>
+0x3C79 0x5F58  # <CJK>
+0x3C7A 0x5F5B  # <CJK>
+0x3C7B 0x5F60  # <CJK>
+0x3C7C 0x5F63  # <CJK>
+0x3C7D 0x5F64  # <CJK>
+0x3C7E 0x5F67  # <CJK>
+0x3D21 0x5F6F  # <CJK>
+0x3D22 0x5F72  # <CJK>
+0x3D23 0x5F74  # <CJK>
+0x3D24 0x5F75  # <CJK>
+0x3D25 0x5F78  # <CJK>
+0x3D26 0x5F7A  # <CJK>
+0x3D27 0x5F7D  # <CJK>
+0x3D28 0x5F7E  # <CJK>
+0x3D29 0x5F89  # <CJK>
+0x3D2A 0x5F8D  # <CJK>
+0x3D2B 0x5F8F  # <CJK>
+0x3D2C 0x5F96  # <CJK>
+0x3D2D 0x5F9C  # <CJK>
+0x3D2E 0x5F9D  # <CJK>
+0x3D2F 0x5FA2  # <CJK>
+0x3D30 0x5FA7  # <CJK>
+0x3D31 0x5FAB  # <CJK>
+0x3D32 0x5FA4  # <CJK>
+0x3D33 0x5FAC  # <CJK>
+0x3D34 0x5FAF  # <CJK>
+0x3D35 0x5FB0  # <CJK>
+0x3D36 0x5FB1  # <CJK>
+0x3D37 0x5FB8  # <CJK>
+0x3D38 0x5FC4  # <CJK>
+0x3D39 0x5FC7  # <CJK>
+0x3D3A 0x5FC8  # <CJK>
+0x3D3B 0x5FC9  # <CJK>
+0x3D3C 0x5FCB  # <CJK>
+0x3D3D 0x5FD0  # <CJK>
+0x3D3E 0x5FD1  # <CJK>
+0x3D3F 0x5FD2  # <CJK>
+0x3D40 0x5FD3  # <CJK>
+0x3D41 0x5FD4  # <CJK>
+0x3D42 0x5FDE  # <CJK>
+0x3D43 0x5FE1  # <CJK>
+0x3D44 0x5FE2  # <CJK>
+0x3D45 0x5FE8  # <CJK>
+0x3D46 0x5FE9  # <CJK>
+0x3D47 0x5FEA  # <CJK>
+0x3D48 0x5FEC  # <CJK>
+0x3D49 0x5FED  # <CJK>
+0x3D4A 0x5FEE  # <CJK>
+0x3D4B 0x5FEF  # <CJK>
+0x3D4C 0x5FF2  # <CJK>
+0x3D4D 0x5FF3  # <CJK>
+0x3D4E 0x5FF6  # <CJK>
+0x3D4F 0x5FFA  # <CJK>
+0x3D50 0x5FFC  # <CJK>
+0x3D51 0x6007  # <CJK>
+0x3D52 0x600A  # <CJK>
+0x3D53 0x600D  # <CJK>
+0x3D54 0x6013  # <CJK>
+0x3D55 0x6014  # <CJK>
+0x3D56 0x6017  # <CJK>
+0x3D57 0x6018  # <CJK>
+0x3D58 0x601A  # <CJK>
+0x3D59 0x601F  # <CJK>
+0x3D5A 0x6024  # <CJK>
+0x3D5B 0x602D  # <CJK>
+0x3D5C 0x6033  # <CJK>
+0x3D5D 0x6035  # <CJK>
+0x3D5E 0x6040  # <CJK>
+0x3D5F 0x6047  # <CJK>
+0x3D60 0x6048  # <CJK>
+0x3D61 0x6049  # <CJK>
+0x3D62 0x604C  # <CJK>
+0x3D63 0x6051  # <CJK>
+0x3D64 0x6054  # <CJK>
+0x3D65 0x6056  # <CJK>
+0x3D66 0x6057  # <CJK>
+0x3D67 0x605D  # <CJK>
+0x3D68 0x6061  # <CJK>
+0x3D69 0x6067  # <CJK>
+0x3D6A 0x6071  # <CJK>
+0x3D6B 0x607E  # <CJK>
+0x3D6C 0x607F  # <CJK>
+0x3D6D 0x6082  # <CJK>
+0x3D6E 0x6086  # <CJK>
+0x3D6F 0x6088  # <CJK>
+0x3D70 0x608A  # <CJK>
+0x3D71 0x608E  # <CJK>
+0x3D72 0x6091  # <CJK>
+0x3D73 0x6093  # <CJK>
+0x3D74 0x6095  # <CJK>
+0x3D75 0x6098  # <CJK>
+0x3D76 0x609D  # <CJK>
+0x3D77 0x609E  # <CJK>
+0x3D78 0x60A2  # <CJK>
+0x3D79 0x60A4  # <CJK>
+0x3D7A 0x60A5  # <CJK>
+0x3D7B 0x60A8  # <CJK>
+0x3D7C 0x60B0  # <CJK>
+0x3D7D 0x60B1  # <CJK>
+0x3D7E 0x60B7  # <CJK>
+0x3E21 0x60BB  # <CJK>
+0x3E22 0x60BE  # <CJK>
+0x3E23 0x60C2  # <CJK>
+0x3E24 0x60C4  # <CJK>
+0x3E25 0x60C8  # <CJK>
+0x3E26 0x60C9  # <CJK>
+0x3E27 0x60CA  # <CJK>
+0x3E28 0x60CB  # <CJK>
+0x3E29 0x60CE  # <CJK>
+0x3E2A 0x60CF  # <CJK>
+0x3E2B 0x60D4  # <CJK>
+0x3E2C 0x60D5  # <CJK>
+0x3E2D 0x60D9  # <CJK>
+0x3E2E 0x60DB  # <CJK>
+0x3E2F 0x60DD  # <CJK>
+0x3E30 0x60DE  # <CJK>
+0x3E31 0x60E2  # <CJK>
+0x3E32 0x60E5  # <CJK>
+0x3E33 0x60F2  # <CJK>
+0x3E34 0x60F5  # <CJK>
+0x3E35 0x60F8  # <CJK>
+0x3E36 0x60FC  # <CJK>
+0x3E37 0x60FD  # <CJK>
+0x3E38 0x6102  # <CJK>
+0x3E39 0x6107  # <CJK>
+0x3E3A 0x610A  # <CJK>
+0x3E3B 0x610C  # <CJK>
+0x3E3C 0x6110  # <CJK>
+0x3E3D 0x6111  # <CJK>
+0x3E3E 0x6112  # <CJK>
+0x3E3F 0x6113  # <CJK>
+0x3E40 0x6114  # <CJK>
+0x3E41 0x6116  # <CJK>
+0x3E42 0x6117  # <CJK>
+0x3E43 0x6119  # <CJK>
+0x3E44 0x611C  # <CJK>
+0x3E45 0x611E  # <CJK>
+0x3E46 0x6122  # <CJK>
+0x3E47 0x612A  # <CJK>
+0x3E48 0x612B  # <CJK>
+0x3E49 0x6130  # <CJK>
+0x3E4A 0x6131  # <CJK>
+0x3E4B 0x6135  # <CJK>
+0x3E4C 0x6136  # <CJK>
+0x3E4D 0x6137  # <CJK>
+0x3E4E 0x6139  # <CJK>
+0x3E4F 0x6141  # <CJK>
+0x3E50 0x6145  # <CJK>
+0x3E51 0x6146  # <CJK>
+0x3E52 0x6149  # <CJK>
+0x3E53 0x615E  # <CJK>
+0x3E54 0x6160  # <CJK>
+0x3E55 0x616C  # <CJK>
+0x3E56 0x6172  # <CJK>
+0x3E57 0x6178  # <CJK>
+0x3E58 0x617B  # <CJK>
+0x3E59 0x617C  # <CJK>
+0x3E5A 0x617F  # <CJK>
+0x3E5B 0x6180  # <CJK>
+0x3E5C 0x6181  # <CJK>
+0x3E5D 0x6183  # <CJK>
+0x3E5E 0x6184  # <CJK>
+0x3E5F 0x618B  # <CJK>
+0x3E60 0x618D  # <CJK>
+0x3E61 0x6192  # <CJK>
+0x3E62 0x6193  # <CJK>
+0x3E63 0x6197  # <CJK>
+0x3E64 0x6198  # <CJK>
+0x3E65 0x619C  # <CJK>
+0x3E66 0x619D  # <CJK>
+0x3E67 0x619F  # <CJK>
+0x3E68 0x61A0  # <CJK>
+0x3E69 0x61A5  # <CJK>
+0x3E6A 0x61A8  # <CJK>
+0x3E6B 0x61AA  # <CJK>
+0x3E6C 0x61AD  # <CJK>
+0x3E6D 0x61B8  # <CJK>
+0x3E6E 0x61B9  # <CJK>
+0x3E6F 0x61BC  # <CJK>
+0x3E70 0x61C0  # <CJK>
+0x3E71 0x61C1  # <CJK>
+0x3E72 0x61C2  # <CJK>
+0x3E73 0x61CE  # <CJK>
+0x3E74 0x61CF  # <CJK>
+0x3E75 0x61D5  # <CJK>
+0x3E76 0x61DC  # <CJK>
+0x3E77 0x61DD  # <CJK>
+0x3E78 0x61DE  # <CJK>
+0x3E79 0x61DF  # <CJK>
+0x3E7A 0x61E1  # <CJK>
+0x3E7B 0x61E2  # <CJK>
+0x3E7C 0x61E7  # <CJK>
+0x3E7D 0x61E9  # <CJK>
+0x3E7E 0x61E5  # <CJK>
+0x3F21 0x61EC  # <CJK>
+0x3F22 0x61ED  # <CJK>
+0x3F23 0x61EF  # <CJK>
+0x3F24 0x6201  # <CJK>
+0x3F25 0x6203  # <CJK>
+0x3F26 0x6204  # <CJK>
+0x3F27 0x6207  # <CJK>
+0x3F28 0x6213  # <CJK>
+0x3F29 0x6215  # <CJK>
+0x3F2A 0x621C  # <CJK>
+0x3F2B 0x6220  # <CJK>
+0x3F2C 0x6222  # <CJK>
+0x3F2D 0x6223  # <CJK>
+0x3F2E 0x6227  # <CJK>
+0x3F2F 0x6229  # <CJK>
+0x3F30 0x622B  # <CJK>
+0x3F31 0x6239  # <CJK>
+0x3F32 0x623D  # <CJK>
+0x3F33 0x6242  # <CJK>
+0x3F34 0x6243  # <CJK>
+0x3F35 0x6244  # <CJK>
+0x3F36 0x6246  # <CJK>
+0x3F37 0x624C  # <CJK>
+0x3F38 0x6250  # <CJK>
+0x3F39 0x6251  # <CJK>
+0x3F3A 0x6252  # <CJK>
+0x3F3B 0x6254  # <CJK>
+0x3F3C 0x6256  # <CJK>
+0x3F3D 0x625A  # <CJK>
+0x3F3E 0x625C  # <CJK>
+0x3F3F 0x6264  # <CJK>
+0x3F40 0x626D  # <CJK>
+0x3F41 0x626F  # <CJK>
+0x3F42 0x6273  # <CJK>
+0x3F43 0x627A  # <CJK>
+0x3F44 0x627D  # <CJK>
+0x3F45 0x628D  # <CJK>
+0x3F46 0x628E  # <CJK>
+0x3F47 0x628F  # <CJK>
+0x3F48 0x6290  # <CJK>
+0x3F49 0x62A6  # <CJK>
+0x3F4A 0x62A8  # <CJK>
+0x3F4B 0x62B3  # <CJK>
+0x3F4C 0x62B6  # <CJK>
+0x3F4D 0x62B7  # <CJK>
+0x3F4E 0x62BA  # <CJK>
+0x3F4F 0x62BE  # <CJK>
+0x3F50 0x62BF  # <CJK>
+0x3F51 0x62C4  # <CJK>
+0x3F52 0x62CE  # <CJK>
+0x3F53 0x62D5  # <CJK>
+0x3F54 0x62D6  # <CJK>
+0x3F55 0x62DA  # <CJK>
+0x3F56 0x62EA  # <CJK>
+0x3F57 0x62F2  # <CJK>
+0x3F58 0x62F4  # <CJK>
+0x3F59 0x62FC  # <CJK>
+0x3F5A 0x62FD  # <CJK>
+0x3F5B 0x6303  # <CJK>
+0x3F5C 0x6304  # <CJK>
+0x3F5D 0x630A  # <CJK>
+0x3F5E 0x630B  # <CJK>
+0x3F5F 0x630D  # <CJK>
+0x3F60 0x6310  # <CJK>
+0x3F61 0x6313  # <CJK>
+0x3F62 0x6316  # <CJK>
+0x3F63 0x6318  # <CJK>
+0x3F64 0x6329  # <CJK>
+0x3F65 0x632A  # <CJK>
+0x3F66 0x632D  # <CJK>
+0x3F67 0x6335  # <CJK>
+0x3F68 0x6336  # <CJK>
+0x3F69 0x6339  # <CJK>
+0x3F6A 0x633C  # <CJK>
+0x3F6B 0x6341  # <CJK>
+0x3F6C 0x6342  # <CJK>
+0x3F6D 0x6343  # <CJK>
+0x3F6E 0x6344  # <CJK>
+0x3F6F 0x6346  # <CJK>
+0x3F70 0x634A  # <CJK>
+0x3F71 0x634B  # <CJK>
+0x3F72 0x634E  # <CJK>
+0x3F73 0x6352  # <CJK>
+0x3F74 0x6353  # <CJK>
+0x3F75 0x6354  # <CJK>
+0x3F76 0x6358  # <CJK>
+0x3F77 0x635B  # <CJK>
+0x3F78 0x6365  # <CJK>
+0x3F79 0x6366  # <CJK>
+0x3F7A 0x636C  # <CJK>
+0x3F7B 0x636D  # <CJK>
+0x3F7C 0x6371  # <CJK>
+0x3F7D 0x6374  # <CJK>
+0x3F7E 0x6375  # <CJK>
+0x4021 0x6378  # <CJK>
+0x4022 0x637C  # <CJK>
+0x4023 0x637D  # <CJK>
+0x4024 0x637F  # <CJK>
+0x4025 0x6382  # <CJK>
+0x4026 0x6384  # <CJK>
+0x4027 0x6387  # <CJK>
+0x4028 0x638A  # <CJK>
+0x4029 0x6390  # <CJK>
+0x402A 0x6394  # <CJK>
+0x402B 0x6395  # <CJK>
+0x402C 0x6399  # <CJK>
+0x402D 0x639A  # <CJK>
+0x402E 0x639E  # <CJK>
+0x402F 0x63A4  # <CJK>
+0x4030 0x63A6  # <CJK>
+0x4031 0x63AD  # <CJK>
+0x4032 0x63AE  # <CJK>
+0x4033 0x63AF  # <CJK>
+0x4034 0x63BD  # <CJK>
+0x4035 0x63C1  # <CJK>
+0x4036 0x63C5  # <CJK>
+0x4037 0x63C8  # <CJK>
+0x4038 0x63CE  # <CJK>
+0x4039 0x63D1  # <CJK>
+0x403A 0x63D3  # <CJK>
+0x403B 0x63D4  # <CJK>
+0x403C 0x63D5  # <CJK>
+0x403D 0x63DC  # <CJK>
+0x403E 0x63E0  # <CJK>
+0x403F 0x63E5  # <CJK>
+0x4040 0x63EA  # <CJK>
+0x4041 0x63EC  # <CJK>
+0x4042 0x63F2  # <CJK>
+0x4043 0x63F3  # <CJK>
+0x4044 0x63F5  # <CJK>
+0x4045 0x63F8  # <CJK>
+0x4046 0x63F9  # <CJK>
+0x4047 0x6409  # <CJK>
+0x4048 0x640A  # <CJK>
+0x4049 0x6410  # <CJK>
+0x404A 0x6412  # <CJK>
+0x404B 0x6414  # <CJK>
+0x404C 0x6418  # <CJK>
+0x404D 0x641E  # <CJK>
+0x404E 0x6420  # <CJK>
+0x404F 0x6422  # <CJK>
+0x4050 0x6424  # <CJK>
+0x4051 0x6425  # <CJK>
+0x4052 0x6429  # <CJK>
+0x4053 0x642A  # <CJK>
+0x4054 0x642F  # <CJK>
+0x4055 0x6430  # <CJK>
+0x4056 0x6435  # <CJK>
+0x4057 0x643D  # <CJK>
+0x4058 0x643F  # <CJK>
+0x4059 0x644B  # <CJK>
+0x405A 0x644F  # <CJK>
+0x405B 0x6451  # <CJK>
+0x405C 0x6452  # <CJK>
+0x405D 0x6453  # <CJK>
+0x405E 0x6454  # <CJK>
+0x405F 0x645A  # <CJK>
+0x4060 0x645B  # <CJK>
+0x4061 0x645C  # <CJK>
+0x4062 0x645D  # <CJK>
+0x4063 0x645F  # <CJK>
+0x4064 0x6460  # <CJK>
+0x4065 0x6461  # <CJK>
+0x4066 0x6463  # <CJK>
+0x4067 0x646D  # <CJK>
+0x4068 0x6473  # <CJK>
+0x4069 0x6474  # <CJK>
+0x406A 0x647B  # <CJK>
+0x406B 0x647D  # <CJK>
+0x406C 0x6485  # <CJK>
+0x406D 0x6487  # <CJK>
+0x406E 0x648F  # <CJK>
+0x406F 0x6490  # <CJK>
+0x4070 0x6491  # <CJK>
+0x4071 0x6498  # <CJK>
+0x4072 0x6499  # <CJK>
+0x4073 0x649B  # <CJK>
+0x4074 0x649D  # <CJK>
+0x4075 0x649F  # <CJK>
+0x4076 0x64A1  # <CJK>
+0x4077 0x64A3  # <CJK>
+0x4078 0x64A6  # <CJK>
+0x4079 0x64A8  # <CJK>
+0x407A 0x64AC  # <CJK>
+0x407B 0x64B3  # <CJK>
+0x407C 0x64BD  # <CJK>
+0x407D 0x64BE  # <CJK>
+0x407E 0x64BF  # <CJK>
+0x4121 0x64C4  # <CJK>
+0x4122 0x64C9  # <CJK>
+0x4123 0x64CA  # <CJK>
+0x4124 0x64CB  # <CJK>
+0x4125 0x64CC  # <CJK>
+0x4126 0x64CE  # <CJK>
+0x4127 0x64D0  # <CJK>
+0x4128 0x64D1  # <CJK>
+0x4129 0x64D5  # <CJK>
+0x412A 0x64D7  # <CJK>
+0x412B 0x64E4  # <CJK>
+0x412C 0x64E5  # <CJK>
+0x412D 0x64E9  # <CJK>
+0x412E 0x64EA  # <CJK>
+0x412F 0x64ED  # <CJK>
+0x4130 0x64F0  # <CJK>
+0x4131 0x64F5  # <CJK>
+0x4132 0x64F7  # <CJK>
+0x4133 0x64FB  # <CJK>
+0x4134 0x64FF  # <CJK>
+0x4135 0x6501  # <CJK>
+0x4136 0x6504  # <CJK>
+0x4137 0x6508  # <CJK>
+0x4138 0x6509  # <CJK>
+0x4139 0x650A  # <CJK>
+0x413A 0x650F  # <CJK>
+0x413B 0x6513  # <CJK>
+0x413C 0x6514  # <CJK>
+0x413D 0x6516  # <CJK>
+0x413E 0x6519  # <CJK>
+0x413F 0x651B  # <CJK>
+0x4140 0x651E  # <CJK>
+0x4141 0x651F  # <CJK>
+0x4142 0x6522  # <CJK>
+0x4143 0x6526  # <CJK>
+0x4144 0x6529  # <CJK>
+0x4145 0x652E  # <CJK>
+0x4146 0x6531  # <CJK>
+0x4147 0x653A  # <CJK>
+0x4148 0x653C  # <CJK>
+0x4149 0x653D  # <CJK>
+0x414A 0x6543  # <CJK>
+0x414B 0x6547  # <CJK>
+0x414C 0x6549  # <CJK>
+0x414D 0x6550  # <CJK>
+0x414E 0x6552  # <CJK>
+0x414F 0x6554  # <CJK>
+0x4150 0x655F  # <CJK>
+0x4151 0x6560  # <CJK>
+0x4152 0x6567  # <CJK>
+0x4153 0x656B  # <CJK>
+0x4154 0x657A  # <CJK>
+0x4155 0x657D  # <CJK>
+0x4156 0x6581  # <CJK>
+0x4157 0x6585  # <CJK>
+0x4158 0x658A  # <CJK>
+0x4159 0x6592  # <CJK>
+0x415A 0x6595  # <CJK>
+0x415B 0x6598  # <CJK>
+0x415C 0x659D  # <CJK>
+0x415D 0x65A0  # <CJK>
+0x415E 0x65A3  # <CJK>
+0x415F 0x65A6  # <CJK>
+0x4160 0x65AE  # <CJK>
+0x4161 0x65B2  # <CJK>
+0x4162 0x65B3  # <CJK>
+0x4163 0x65B4  # <CJK>
+0x4164 0x65BF  # <CJK>
+0x4165 0x65C2  # <CJK>
+0x4166 0x65C8  # <CJK>
+0x4167 0x65C9  # <CJK>
+0x4168 0x65CE  # <CJK>
+0x4169 0x65D0  # <CJK>
+0x416A 0x65D4  # <CJK>
+0x416B 0x65D6  # <CJK>
+0x416C 0x65D8  # <CJK>
+0x416D 0x65DF  # <CJK>
+0x416E 0x65F0  # <CJK>
+0x416F 0x65F2  # <CJK>
+0x4170 0x65F4  # <CJK>
+0x4171 0x65F5  # <CJK>
+0x4172 0x65F9  # <CJK>
+0x4173 0x65FE  # <CJK>
+0x4174 0x65FF  # <CJK>
+0x4175 0x6600  # <CJK>
+0x4176 0x6604  # <CJK>
+0x4177 0x6608  # <CJK>
+0x4178 0x6609  # <CJK>
+0x4179 0x660D  # <CJK>
+0x417A 0x6611  # <CJK>
+0x417B 0x6612  # <CJK>
+0x417C 0x6615  # <CJK>
+0x417D 0x6616  # <CJK>
+0x417E 0x661D  # <CJK>
+0x4221 0x661E  # <CJK>
+0x4222 0x6621  # <CJK>
+0x4223 0x6622  # <CJK>
+0x4224 0x6623  # <CJK>
+0x4225 0x6624  # <CJK>
+0x4226 0x6626  # <CJK>
+0x4227 0x6629  # <CJK>
+0x4228 0x662A  # <CJK>
+0x4229 0x662B  # <CJK>
+0x422A 0x662C  # <CJK>
+0x422B 0x662E  # <CJK>
+0x422C 0x6630  # <CJK>
+0x422D 0x6631  # <CJK>
+0x422E 0x6633  # <CJK>
+0x422F 0x6639  # <CJK>
+0x4230 0x6637  # <CJK>
+0x4231 0x6640  # <CJK>
+0x4232 0x6645  # <CJK>
+0x4233 0x6646  # <CJK>
+0x4234 0x664A  # <CJK>
+0x4235 0x664C  # <CJK>
+0x4236 0x6651  # <CJK>
+0x4237 0x664E  # <CJK>
+0x4238 0x6657  # <CJK>
+0x4239 0x6658  # <CJK>
+0x423A 0x6659  # <CJK>
+0x423B 0x665B  # <CJK>
+0x423C 0x665C  # <CJK>
+0x423D 0x6660  # <CJK>
+0x423E 0x6661  # <CJK>
+0x423F 0x66FB  # <CJK>
+0x4240 0x666A  # <CJK>
+0x4241 0x666B  # <CJK>
+0x4242 0x666C  # <CJK>
+0x4243 0x667E  # <CJK>
+0x4244 0x6673  # <CJK>
+0x4245 0x6675  # <CJK>
+0x4246 0x667F  # <CJK>
+0x4247 0x6677  # <CJK>
+0x4248 0x6678  # <CJK>
+0x4249 0x6679  # <CJK>
+0x424A 0x667B  # <CJK>
+0x424B 0x6680  # <CJK>
+0x424C 0x667C  # <CJK>
+0x424D 0x668B  # <CJK>
+0x424E 0x668C  # <CJK>
+0x424F 0x668D  # <CJK>
+0x4250 0x6690  # <CJK>
+0x4251 0x6692  # <CJK>
+0x4252 0x6699  # <CJK>
+0x4253 0x669A  # <CJK>
+0x4254 0x669B  # <CJK>
+0x4255 0x669C  # <CJK>
+0x4256 0x669F  # <CJK>
+0x4257 0x66A0  # <CJK>
+0x4258 0x66A4  # <CJK>
+0x4259 0x66AD  # <CJK>
+0x425A 0x66B1  # <CJK>
+0x425B 0x66B2  # <CJK>
+0x425C 0x66B5  # <CJK>
+0x425D 0x66BB  # <CJK>
+0x425E 0x66BF  # <CJK>
+0x425F 0x66C0  # <CJK>
+0x4260 0x66C2  # <CJK>
+0x4261 0x66C3  # <CJK>
+0x4262 0x66C8  # <CJK>
+0x4263 0x66CC  # <CJK>
+0x4264 0x66CE  # <CJK>
+0x4265 0x66CF  # <CJK>
+0x4266 0x66D4  # <CJK>
+0x4267 0x66DB  # <CJK>
+0x4268 0x66DF  # <CJK>
+0x4269 0x66E8  # <CJK>
+0x426A 0x66EB  # <CJK>
+0x426B 0x66EC  # <CJK>
+0x426C 0x66EE  # <CJK>
+0x426D 0x66FA  # <CJK>
+0x426E 0x6705  # <CJK>
+0x426F 0x6707  # <CJK>
+0x4270 0x670E  # <CJK>
+0x4271 0x6713  # <CJK>
+0x4272 0x6719  # <CJK>
+0x4273 0x671C  # <CJK>
+0x4274 0x6720  # <CJK>
+0x4275 0x6722  # <CJK>
+0x4276 0x6733  # <CJK>
+0x4277 0x673E  # <CJK>
+0x4278 0x6745  # <CJK>
+0x4279 0x6747  # <CJK>
+0x427A 0x6748  # <CJK>
+0x427B 0x674C  # <CJK>
+0x427C 0x6754  # <CJK>
+0x427D 0x6755  # <CJK>
+0x427E 0x675D  # <CJK>
+0x4321 0x6766  # <CJK>
+0x4322 0x676C  # <CJK>
+0x4323 0x676E  # <CJK>
+0x4324 0x6774  # <CJK>
+0x4325 0x6776  # <CJK>
+0x4326 0x677B  # <CJK>
+0x4327 0x6781  # <CJK>
+0x4328 0x6784  # <CJK>
+0x4329 0x678E  # <CJK>
+0x432A 0x678F  # <CJK>
+0x432B 0x6791  # <CJK>
+0x432C 0x6793  # <CJK>
+0x432D 0x6796  # <CJK>
+0x432E 0x6798  # <CJK>
+0x432F 0x6799  # <CJK>
+0x4330 0x679B  # <CJK>
+0x4331 0x67B0  # <CJK>
+0x4332 0x67B1  # <CJK>
+0x4333 0x67B2  # <CJK>
+0x4334 0x67B5  # <CJK>
+0x4335 0x67BB  # <CJK>
+0x4336 0x67BC  # <CJK>
+0x4337 0x67BD  # <CJK>
+0x4338 0x67F9  # <CJK>
+0x4339 0x67C0  # <CJK>
+0x433A 0x67C2  # <CJK>
+0x433B 0x67C3  # <CJK>
+0x433C 0x67C5  # <CJK>
+0x433D 0x67C8  # <CJK>
+0x433E 0x67C9  # <CJK>
+0x433F 0x67D2  # <CJK>
+0x4340 0x67D7  # <CJK>
+0x4341 0x67D9  # <CJK>
+0x4342 0x67DC  # <CJK>
+0x4343 0x67E1  # <CJK>
+0x4344 0x67E6  # <CJK>
+0x4345 0x67F0  # <CJK>
+0x4346 0x67F2  # <CJK>
+0x4347 0x67F6  # <CJK>
+0x4348 0x67F7  # <CJK>
+0x4349 0x6852  # <CJK>
+0x434A 0x6814  # <CJK>
+0x434B 0x6819  # <CJK>
+0x434C 0x681D  # <CJK>
+0x434D 0x681F  # <CJK>
+0x434E 0x6828  # <CJK>
+0x434F 0x6827  # <CJK>
+0x4350 0x682C  # <CJK>
+0x4351 0x682D  # <CJK>
+0x4352 0x682F  # <CJK>
+0x4353 0x6830  # <CJK>
+0x4354 0x6831  # <CJK>
+0x4355 0x6833  # <CJK>
+0x4356 0x683B  # <CJK>
+0x4357 0x683F  # <CJK>
+0x4358 0x6844  # <CJK>
+0x4359 0x6845  # <CJK>
+0x435A 0x684A  # <CJK>
+0x435B 0x684C  # <CJK>
+0x435C 0x6855  # <CJK>
+0x435D 0x6857  # <CJK>
+0x435E 0x6858  # <CJK>
+0x435F 0x685B  # <CJK>
+0x4360 0x686B  # <CJK>
+0x4361 0x686E  # <CJK>
+0x4362 0x686F  # <CJK>
+0x4363 0x6870  # <CJK>
+0x4364 0x6871  # <CJK>
+0x4365 0x6872  # <CJK>
+0x4366 0x6875  # <CJK>
+0x4367 0x6879  # <CJK>
+0x4368 0x687A  # <CJK>
+0x4369 0x687B  # <CJK>
+0x436A 0x687C  # <CJK>
+0x436B 0x6882  # <CJK>
+0x436C 0x6884  # <CJK>
+0x436D 0x6886  # <CJK>
+0x436E 0x6888  # <CJK>
+0x436F 0x6896  # <CJK>
+0x4370 0x6898  # <CJK>
+0x4371 0x689A  # <CJK>
+0x4372 0x689C  # <CJK>
+0x4373 0x68A1  # <CJK>
+0x4374 0x68A3  # <CJK>
+0x4375 0x68A5  # <CJK>
+0x4376 0x68A9  # <CJK>
+0x4377 0x68AA  # <CJK>
+0x4378 0x68AE  # <CJK>
+0x4379 0x68B2  # <CJK>
+0x437A 0x68BB  # <CJK>
+0x437B 0x68C5  # <CJK>
+0x437C 0x68C8  # <CJK>
+0x437D 0x68CC  # <CJK>
+0x437E 0x68CF  # <CJK>
+0x4421 0x68D0  # <CJK>
+0x4422 0x68D1  # <CJK>
+0x4423 0x68D3  # <CJK>
+0x4424 0x68D6  # <CJK>
+0x4425 0x68D9  # <CJK>
+0x4426 0x68DC  # <CJK>
+0x4427 0x68DD  # <CJK>
+0x4428 0x68E5  # <CJK>
+0x4429 0x68E8  # <CJK>
+0x442A 0x68EA  # <CJK>
+0x442B 0x68EB  # <CJK>
+0x442C 0x68EC  # <CJK>
+0x442D 0x68ED  # <CJK>
+0x442E 0x68F0  # <CJK>
+0x442F 0x68F1  # <CJK>
+0x4430 0x68F5  # <CJK>
+0x4431 0x68F6  # <CJK>
+0x4432 0x68FB  # <CJK>
+0x4433 0x68FC  # <CJK>
+0x4434 0x68FD  # <CJK>
+0x4435 0x6906  # <CJK>
+0x4436 0x6909  # <CJK>
+0x4437 0x690A  # <CJK>
+0x4438 0x6910  # <CJK>
+0x4439 0x6911  # <CJK>
+0x443A 0x6913  # <CJK>
+0x443B 0x6916  # <CJK>
+0x443C 0x6917  # <CJK>
+0x443D 0x6931  # <CJK>
+0x443E 0x6933  # <CJK>
+0x443F 0x6935  # <CJK>
+0x4440 0x6938  # <CJK>
+0x4441 0x693B  # <CJK>
+0x4442 0x6942  # <CJK>
+0x4443 0x6945  # <CJK>
+0x4444 0x6949  # <CJK>
+0x4445 0x694E  # <CJK>
+0x4446 0x6957  # <CJK>
+0x4447 0x695B  # <CJK>
+0x4448 0x6963  # <CJK>
+0x4449 0x6964  # <CJK>
+0x444A 0x6965  # <CJK>
+0x444B 0x6966  # <CJK>
+0x444C 0x6968  # <CJK>
+0x444D 0x6969  # <CJK>
+0x444E 0x696C  # <CJK>
+0x444F 0x6970  # <CJK>
+0x4450 0x6971  # <CJK>
+0x4451 0x6972  # <CJK>
+0x4452 0x697A  # <CJK>
+0x4453 0x697B  # <CJK>
+0x4454 0x697F  # <CJK>
+0x4455 0x6980  # <CJK>
+0x4456 0x698D  # <CJK>
+0x4457 0x6992  # <CJK>
+0x4458 0x6996  # <CJK>
+0x4459 0x6998  # <CJK>
+0x445A 0x69A1  # <CJK>
+0x445B 0x69A5  # <CJK>
+0x445C 0x69A6  # <CJK>
+0x445D 0x69A8  # <CJK>
+0x445E 0x69AB  # <CJK>
+0x445F 0x69AD  # <CJK>
+0x4460 0x69AF  # <CJK>
+0x4461 0x69B7  # <CJK>
+0x4462 0x69B8  # <CJK>
+0x4463 0x69BA  # <CJK>
+0x4464 0x69BC  # <CJK>
+0x4465 0x69C5  # <CJK>
+0x4466 0x69C8  # <CJK>
+0x4467 0x69D1  # <CJK>
+0x4468 0x69D6  # <CJK>
+0x4469 0x69D7  # <CJK>
+0x446A 0x69E2  # <CJK>
+0x446B 0x69E5  # <CJK>
+0x446C 0x69EE  # <CJK>
+0x446D 0x69EF  # <CJK>
+0x446E 0x69F1  # <CJK>
+0x446F 0x69F3  # <CJK>
+0x4470 0x69F5  # <CJK>
+0x4471 0x69FE  # <CJK>
+0x4472 0x6A00  # <CJK>
+0x4473 0x6A01  # <CJK>
+0x4474 0x6A03  # <CJK>
+0x4475 0x6A0F  # <CJK>
+0x4476 0x6A11  # <CJK>
+0x4477 0x6A15  # <CJK>
+0x4478 0x6A1A  # <CJK>
+0x4479 0x6A1D  # <CJK>
+0x447A 0x6A20  # <CJK>
+0x447B 0x6A24  # <CJK>
+0x447C 0x6A28  # <CJK>
+0x447D 0x6A30  # <CJK>
+0x447E 0x6A32  # <CJK>
+0x4521 0x6A34  # <CJK>
+0x4522 0x6A37  # <CJK>
+0x4523 0x6A3B  # <CJK>
+0x4524 0x6A3E  # <CJK>
+0x4525 0x6A3F  # <CJK>
+0x4526 0x6A45  # <CJK>
+0x4527 0x6A46  # <CJK>
+0x4528 0x6A49  # <CJK>
+0x4529 0x6A4A  # <CJK>
+0x452A 0x6A4E  # <CJK>
+0x452B 0x6A50  # <CJK>
+0x452C 0x6A51  # <CJK>
+0x452D 0x6A52  # <CJK>
+0x452E 0x6A55  # <CJK>
+0x452F 0x6A56  # <CJK>
+0x4530 0x6A5B  # <CJK>
+0x4531 0x6A64  # <CJK>
+0x4532 0x6A67  # <CJK>
+0x4533 0x6A6A  # <CJK>
+0x4534 0x6A71  # <CJK>
+0x4535 0x6A73  # <CJK>
+0x4536 0x6A7E  # <CJK>
+0x4537 0x6A81  # <CJK>
+0x4538 0x6A83  # <CJK>
+0x4539 0x6A86  # <CJK>
+0x453A 0x6A87  # <CJK>
+0x453B 0x6A89  # <CJK>
+0x453C 0x6A8B  # <CJK>
+0x453D 0x6A91  # <CJK>
+0x453E 0x6A9B  # <CJK>
+0x453F 0x6A9D  # <CJK>
+0x4540 0x6A9E  # <CJK>
+0x4541 0x6A9F  # <CJK>
+0x4542 0x6AA5  # <CJK>
+0x4543 0x6AAB  # <CJK>
+0x4544 0x6AAF  # <CJK>
+0x4545 0x6AB0  # <CJK>
+0x4546 0x6AB1  # <CJK>
+0x4547 0x6AB4  # <CJK>
+0x4548 0x6ABD  # <CJK>
+0x4549 0x6ABE  # <CJK>
+0x454A 0x6ABF  # <CJK>
+0x454B 0x6AC6  # <CJK>
+0x454C 0x6AC9  # <CJK>
+0x454D 0x6AC8  # <CJK>
+0x454E 0x6ACC  # <CJK>
+0x454F 0x6AD0  # <CJK>
+0x4550 0x6AD4  # <CJK>
+0x4551 0x6AD5  # <CJK>
+0x4552 0x6AD6  # <CJK>
+0x4553 0x6ADC  # <CJK>
+0x4554 0x6ADD  # <CJK>
+0x4555 0x6AE4  # <CJK>
+0x4556 0x6AE7  # <CJK>
+0x4557 0x6AEC  # <CJK>
+0x4558 0x6AF0  # <CJK>
+0x4559 0x6AF1  # <CJK>
+0x455A 0x6AF2  # <CJK>
+0x455B 0x6AFC  # <CJK>
+0x455C 0x6AFD  # <CJK>
+0x455D 0x6B02  # <CJK>
+0x455E 0x6B03  # <CJK>
+0x455F 0x6B06  # <CJK>
+0x4560 0x6B07  # <CJK>
+0x4561 0x6B09  # <CJK>
+0x4562 0x6B0F  # <CJK>
+0x4563 0x6B10  # <CJK>
+0x4564 0x6B11  # <CJK>
+0x4565 0x6B17  # <CJK>
+0x4566 0x6B1B  # <CJK>
+0x4567 0x6B1E  # <CJK>
+0x4568 0x6B24  # <CJK>
+0x4569 0x6B28  # <CJK>
+0x456A 0x6B2B  # <CJK>
+0x456B 0x6B2C  # <CJK>
+0x456C 0x6B2F  # <CJK>
+0x456D 0x6B35  # <CJK>
+0x456E 0x6B36  # <CJK>
+0x456F 0x6B3B  # <CJK>
+0x4570 0x6B3F  # <CJK>
+0x4571 0x6B46  # <CJK>
+0x4572 0x6B4A  # <CJK>
+0x4573 0x6B4D  # <CJK>
+0x4574 0x6B52  # <CJK>
+0x4575 0x6B56  # <CJK>
+0x4576 0x6B58  # <CJK>
+0x4577 0x6B5D  # <CJK>
+0x4578 0x6B60  # <CJK>
+0x4579 0x6B67  # <CJK>
+0x457A 0x6B6B  # <CJK>
+0x457B 0x6B6E  # <CJK>
+0x457C 0x6B70  # <CJK>
+0x457D 0x6B75  # <CJK>
+0x457E 0x6B7D  # <CJK>
+0x4621 0x6B7E  # <CJK>
+0x4622 0x6B82  # <CJK>
+0x4623 0x6B85  # <CJK>
+0x4624 0x6B97  # <CJK>
+0x4625 0x6B9B  # <CJK>
+0x4626 0x6B9F  # <CJK>
+0x4627 0x6BA0  # <CJK>
+0x4628 0x6BA2  # <CJK>
+0x4629 0x6BA3  # <CJK>
+0x462A 0x6BA8  # <CJK>
+0x462B 0x6BA9  # <CJK>
+0x462C 0x6BAC  # <CJK>
+0x462D 0x6BAD  # <CJK>
+0x462E 0x6BAE  # <CJK>
+0x462F 0x6BB0  # <CJK>
+0x4630 0x6BB8  # <CJK>
+0x4631 0x6BB9  # <CJK>
+0x4632 0x6BBD  # <CJK>
+0x4633 0x6BBE  # <CJK>
+0x4634 0x6BC3  # <CJK>
+0x4635 0x6BC4  # <CJK>
+0x4636 0x6BC9  # <CJK>
+0x4637 0x6BCC  # <CJK>
+0x4638 0x6BD6  # <CJK>
+0x4639 0x6BDA  # <CJK>
+0x463A 0x6BE1  # <CJK>
+0x463B 0x6BE3  # <CJK>
+0x463C 0x6BE6  # <CJK>
+0x463D 0x6BE7  # <CJK>
+0x463E 0x6BEE  # <CJK>
+0x463F 0x6BF1  # <CJK>
+0x4640 0x6BF7  # <CJK>
+0x4641 0x6BF9  # <CJK>
+0x4642 0x6BFF  # <CJK>
+0x4643 0x6C02  # <CJK>
+0x4644 0x6C04  # <CJK>
+0x4645 0x6C05  # <CJK>
+0x4646 0x6C09  # <CJK>
+0x4647 0x6C0D  # <CJK>
+0x4648 0x6C0E  # <CJK>
+0x4649 0x6C10  # <CJK>
+0x464A 0x6C12  # <CJK>
+0x464B 0x6C19  # <CJK>
+0x464C 0x6C1F  # <CJK>
+0x464D 0x6C26  # <CJK>
+0x464E 0x6C27  # <CJK>
+0x464F 0x6C28  # <CJK>
+0x4650 0x6C2C  # <CJK>
+0x4651 0x6C2E  # <CJK>
+0x4652 0x6C33  # <CJK>
+0x4653 0x6C35  # <CJK>
+0x4654 0x6C36  # <CJK>
+0x4655 0x6C3A  # <CJK>
+0x4656 0x6C3B  # <CJK>
+0x4657 0x6C3F  # <CJK>
+0x4658 0x6C4A  # <CJK>
+0x4659 0x6C4B  # <CJK>
+0x465A 0x6C4D  # <CJK>
+0x465B 0x6C4F  # <CJK>
+0x465C 0x6C52  # <CJK>
+0x465D 0x6C54  # <CJK>
+0x465E 0x6C59  # <CJK>
+0x465F 0x6C5B  # <CJK>
+0x4660 0x6C5C  # <CJK>
+0x4661 0x6C6B  # <CJK>
+0x4662 0x6C6D  # <CJK>
+0x4663 0x6C6F  # <CJK>
+0x4664 0x6C74  # <CJK>
+0x4665 0x6C76  # <CJK>
+0x4666 0x6C78  # <CJK>
+0x4667 0x6C79  # <CJK>
+0x4668 0x6C7B  # <CJK>
+0x4669 0x6C85  # <CJK>
+0x466A 0x6C86  # <CJK>
+0x466B 0x6C87  # <CJK>
+0x466C 0x6C89  # <CJK>
+0x466D 0x6C94  # <CJK>
+0x466E 0x6C95  # <CJK>
+0x466F 0x6C97  # <CJK>
+0x4670 0x6C98  # <CJK>
+0x4671 0x6C9C  # <CJK>
+0x4672 0x6C9F  # <CJK>
+0x4673 0x6CB0  # <CJK>
+0x4674 0x6CB2  # <CJK>
+0x4675 0x6CB4  # <CJK>
+0x4676 0x6CC2  # <CJK>
+0x4677 0x6CC6  # <CJK>
+0x4678 0x6CCD  # <CJK>
+0x4679 0x6CCF  # <CJK>
+0x467A 0x6CD0  # <CJK>
+0x467B 0x6CD1  # <CJK>
+0x467C 0x6CD2  # <CJK>
+0x467D 0x6CD4  # <CJK>
+0x467E 0x6CD6  # <CJK>
+0x4721 0x6CDA  # <CJK>
+0x4722 0x6CDC  # <CJK>
+0x4723 0x6CE0  # <CJK>
+0x4724 0x6CE7  # <CJK>
+0x4725 0x6CE9  # <CJK>
+0x4726 0x6CEB  # <CJK>
+0x4727 0x6CEC  # <CJK>
+0x4728 0x6CEE  # <CJK>
+0x4729 0x6CF2  # <CJK>
+0x472A 0x6CF4  # <CJK>
+0x472B 0x6D04  # <CJK>
+0x472C 0x6D07  # <CJK>
+0x472D 0x6D0A  # <CJK>
+0x472E 0x6D0E  # <CJK>
+0x472F 0x6D0F  # <CJK>
+0x4730 0x6D11  # <CJK>
+0x4731 0x6D13  # <CJK>
+0x4732 0x6D1A  # <CJK>
+0x4733 0x6D26  # <CJK>
+0x4734 0x6D27  # <CJK>
+0x4735 0x6D28  # <CJK>
+0x4736 0x6C67  # <CJK>
+0x4737 0x6D2E  # <CJK>
+0x4738 0x6D2F  # <CJK>
+0x4739 0x6D31  # <CJK>
+0x473A 0x6D39  # <CJK>
+0x473B 0x6D3C  # <CJK>
+0x473C 0x6D3F  # <CJK>
+0x473D 0x6D57  # <CJK>
+0x473E 0x6D5E  # <CJK>
+0x473F 0x6D5F  # <CJK>
+0x4740 0x6D61  # <CJK>
+0x4741 0x6D65  # <CJK>
+0x4742 0x6D67  # <CJK>
+0x4743 0x6D6F  # <CJK>
+0x4744 0x6D70  # <CJK>
+0x4745 0x6D7C  # <CJK>
+0x4746 0x6D82  # <CJK>
+0x4747 0x6D87  # <CJK>
+0x4748 0x6D91  # <CJK>
+0x4749 0x6D92  # <CJK>
+0x474A 0x6D94  # <CJK>
+0x474B 0x6D96  # <CJK>
+0x474C 0x6D97  # <CJK>
+0x474D 0x6D98  # <CJK>
+0x474E 0x6DAA  # <CJK>
+0x474F 0x6DAC  # <CJK>
+0x4750 0x6DB4  # <CJK>
+0x4751 0x6DB7  # <CJK>
+0x4752 0x6DB9  # <CJK>
+0x4753 0x6DBD  # <CJK>
+0x4754 0x6DBF  # <CJK>
+0x4755 0x6DC4  # <CJK>
+0x4756 0x6DC8  # <CJK>
+0x4757 0x6DCA  # <CJK>
+0x4758 0x6DCE  # <CJK>
+0x4759 0x6DCF  # <CJK>
+0x475A 0x6DD6  # <CJK>
+0x475B 0x6DDB  # <CJK>
+0x475C 0x6DDD  # <CJK>
+0x475D 0x6DDF  # <CJK>
+0x475E 0x6DE0  # <CJK>
+0x475F 0x6DE2  # <CJK>
+0x4760 0x6DE5  # <CJK>
+0x4761 0x6DE9  # <CJK>
+0x4762 0x6DEF  # <CJK>
+0x4763 0x6DF0  # <CJK>
+0x4764 0x6DF4  # <CJK>
+0x4765 0x6DF6  # <CJK>
+0x4766 0x6DFC  # <CJK>
+0x4767 0x6E00  # <CJK>
+0x4768 0x6E04  # <CJK>
+0x4769 0x6E1E  # <CJK>
+0x476A 0x6E22  # <CJK>
+0x476B 0x6E27  # <CJK>
+0x476C 0x6E32  # <CJK>
+0x476D 0x6E36  # <CJK>
+0x476E 0x6E39  # <CJK>
+0x476F 0x6E3B  # <CJK>
+0x4770 0x6E3C  # <CJK>
+0x4771 0x6E44  # <CJK>
+0x4772 0x6E45  # <CJK>
+0x4773 0x6E48  # <CJK>
+0x4774 0x6E49  # <CJK>
+0x4775 0x6E4B  # <CJK>
+0x4776 0x6E4F  # <CJK>
+0x4777 0x6E51  # <CJK>
+0x4778 0x6E52  # <CJK>
+0x4779 0x6E53  # <CJK>
+0x477A 0x6E54  # <CJK>
+0x477B 0x6E57  # <CJK>
+0x477C 0x6E5C  # <CJK>
+0x477D 0x6E5D  # <CJK>
+0x477E 0x6E5E  # <CJK>
+0x4821 0x6E62  # <CJK>
+0x4822 0x6E63  # <CJK>
+0x4823 0x6E68  # <CJK>
+0x4824 0x6E73  # <CJK>
+0x4825 0x6E7B  # <CJK>
+0x4826 0x6E7D  # <CJK>
+0x4827 0x6E8D  # <CJK>
+0x4828 0x6E93  # <CJK>
+0x4829 0x6E99  # <CJK>
+0x482A 0x6EA0  # <CJK>
+0x482B 0x6EA7  # <CJK>
+0x482C 0x6EAD  # <CJK>
+0x482D 0x6EAE  # <CJK>
+0x482E 0x6EB1  # <CJK>
+0x482F 0x6EB3  # <CJK>
+0x4830 0x6EBB  # <CJK>
+0x4831 0x6EBF  # <CJK>
+0x4832 0x6EC0  # <CJK>
+0x4833 0x6EC1  # <CJK>
+0x4834 0x6EC3  # <CJK>
+0x4835 0x6EC7  # <CJK>
+0x4836 0x6EC8  # <CJK>
+0x4837 0x6ECA  # <CJK>
+0x4838 0x6ECD  # <CJK>
+0x4839 0x6ECE  # <CJK>
+0x483A 0x6ECF  # <CJK>
+0x483B 0x6EEB  # <CJK>
+0x483C 0x6EED  # <CJK>
+0x483D 0x6EEE  # <CJK>
+0x483E 0x6EF9  # <CJK>
+0x483F 0x6EFB  # <CJK>
+0x4840 0x6EFD  # <CJK>
+0x4841 0x6F04  # <CJK>
+0x4842 0x6F08  # <CJK>
+0x4843 0x6F0A  # <CJK>
+0x4844 0x6F0C  # <CJK>
+0x4845 0x6F0D  # <CJK>
+0x4846 0x6F16  # <CJK>
+0x4847 0x6F18  # <CJK>
+0x4848 0x6F1A  # <CJK>
+0x4849 0x6F1B  # <CJK>
+0x484A 0x6F26  # <CJK>
+0x484B 0x6F29  # <CJK>
+0x484C 0x6F2A  # <CJK>
+0x484D 0x6F2F  # <CJK>
+0x484E 0x6F30  # <CJK>
+0x484F 0x6F33  # <CJK>
+0x4850 0x6F36  # <CJK>
+0x4851 0x6F3B  # <CJK>
+0x4852 0x6F3C  # <CJK>
+0x4853 0x6F2D  # <CJK>
+0x4854 0x6F4F  # <CJK>
+0x4855 0x6F51  # <CJK>
+0x4856 0x6F52  # <CJK>
+0x4857 0x6F53  # <CJK>
+0x4858 0x6F57  # <CJK>
+0x4859 0x6F59  # <CJK>
+0x485A 0x6F5A  # <CJK>
+0x485B 0x6F5D  # <CJK>
+0x485C 0x6F5E  # <CJK>
+0x485D 0x6F61  # <CJK>
+0x485E 0x6F62  # <CJK>
+0x485F 0x6F68  # <CJK>
+0x4860 0x6F6C  # <CJK>
+0x4861 0x6F7D  # <CJK>
+0x4862 0x6F7E  # <CJK>
+0x4863 0x6F83  # <CJK>
+0x4864 0x6F87  # <CJK>
+0x4865 0x6F88  # <CJK>
+0x4866 0x6F8B  # <CJK>
+0x4867 0x6F8C  # <CJK>
+0x4868 0x6F8D  # <CJK>
+0x4869 0x6F90  # <CJK>
+0x486A 0x6F92  # <CJK>
+0x486B 0x6F93  # <CJK>
+0x486C 0x6F94  # <CJK>
+0x486D 0x6F96  # <CJK>
+0x486E 0x6F9A  # <CJK>
+0x486F 0x6F9F  # <CJK>
+0x4870 0x6FA0  # <CJK>
+0x4871 0x6FA5  # <CJK>
+0x4872 0x6FA6  # <CJK>
+0x4873 0x6FA7  # <CJK>
+0x4874 0x6FA8  # <CJK>
+0x4875 0x6FAE  # <CJK>
+0x4876 0x6FAF  # <CJK>
+0x4877 0x6FB0  # <CJK>
+0x4878 0x6FB5  # <CJK>
+0x4879 0x6FB6  # <CJK>
+0x487A 0x6FBC  # <CJK>
+0x487B 0x6FC5  # <CJK>
+0x487C 0x6FC7  # <CJK>
+0x487D 0x6FC8  # <CJK>
+0x487E 0x6FCA  # <CJK>
+0x4921 0x6FDA  # <CJK>
+0x4922 0x6FDE  # <CJK>
+0x4923 0x6FE8  # <CJK>
+0x4924 0x6FE9  # <CJK>
+0x4925 0x6FF0  # <CJK>
+0x4926 0x6FF5  # <CJK>
+0x4927 0x6FF9  # <CJK>
+0x4928 0x6FFC  # <CJK>
+0x4929 0x6FFD  # <CJK>
+0x492A 0x7000  # <CJK>
+0x492B 0x7005  # <CJK>
+0x492C 0x7006  # <CJK>
+0x492D 0x7007  # <CJK>
+0x492E 0x700D  # <CJK>
+0x492F 0x7017  # <CJK>
+0x4930 0x7020  # <CJK>
+0x4931 0x7023  # <CJK>
+0x4932 0x702F  # <CJK>
+0x4933 0x7034  # <CJK>
+0x4934 0x7037  # <CJK>
+0x4935 0x7039  # <CJK>
+0x4936 0x703C  # <CJK>
+0x4937 0x7043  # <CJK>
+0x4938 0x7044  # <CJK>
+0x4939 0x7048  # <CJK>
+0x493A 0x7049  # <CJK>
+0x493B 0x704A  # <CJK>
+0x493C 0x704B  # <CJK>
+0x493D 0x7054  # <CJK>
+0x493E 0x7055  # <CJK>
+0x493F 0x705D  # <CJK>
+0x4940 0x705E  # <CJK>
+0x4941 0x704E  # <CJK>
+0x4942 0x7064  # <CJK>
+0x4943 0x7065  # <CJK>
+0x4944 0x706C  # <CJK>
+0x4945 0x706E  # <CJK>
+0x4946 0x7075  # <CJK>
+0x4947 0x7076  # <CJK>
+0x4948 0x707E  # <CJK>
+0x4949 0x7081  # <CJK>
+0x494A 0x7085  # <CJK>
+0x494B 0x7086  # <CJK>
+0x494C 0x7094  # <CJK>
+0x494D 0x7095  # <CJK>
+0x494E 0x7096  # <CJK>
+0x494F 0x7097  # <CJK>
+0x4950 0x7098  # <CJK>
+0x4951 0x709B  # <CJK>
+0x4952 0x70A4  # <CJK>
+0x4953 0x70AB  # <CJK>
+0x4954 0x70B0  # <CJK>
+0x4955 0x70B1  # <CJK>
+0x4956 0x70B4  # <CJK>
+0x4957 0x70B7  # <CJK>
+0x4958 0x70CA  # <CJK>
+0x4959 0x70D1  # <CJK>
+0x495A 0x70D3  # <CJK>
+0x495B 0x70D4  # <CJK>
+0x495C 0x70D5  # <CJK>
+0x495D 0x70D6  # <CJK>
+0x495E 0x70D8  # <CJK>
+0x495F 0x70DC  # <CJK>
+0x4960 0x70E4  # <CJK>
+0x4961 0x70FA  # <CJK>
+0x4962 0x7103  # <CJK>
+0x4963 0x7104  # <CJK>
+0x4964 0x7105  # <CJK>
+0x4965 0x7106  # <CJK>
+0x4966 0x7107  # <CJK>
+0x4967 0x710B  # <CJK>
+0x4968 0x710C  # <CJK>
+0x4969 0x710F  # <CJK>
+0x496A 0x711E  # <CJK>
+0x496B 0x7120  # <CJK>
+0x496C 0x712B  # <CJK>
+0x496D 0x712D  # <CJK>
+0x496E 0x712F  # <CJK>
+0x496F 0x7130  # <CJK>
+0x4970 0x7131  # <CJK>
+0x4971 0x7138  # <CJK>
+0x4972 0x7141  # <CJK>
+0x4973 0x7145  # <CJK>
+0x4974 0x7146  # <CJK>
+0x4975 0x7147  # <CJK>
+0x4976 0x714A  # <CJK>
+0x4977 0x714B  # <CJK>
+0x4978 0x7150  # <CJK>
+0x4979 0x7152  # <CJK>
+0x497A 0x7157  # <CJK>
+0x497B 0x715A  # <CJK>
+0x497C 0x715C  # <CJK>
+0x497D 0x715E  # <CJK>
+0x497E 0x7160  # <CJK>
+0x4A21 0x7168  # <CJK>
+0x4A22 0x7179  # <CJK>
+0x4A23 0x7180  # <CJK>
+0x4A24 0x7185  # <CJK>
+0x4A25 0x7187  # <CJK>
+0x4A26 0x718C  # <CJK>
+0x4A27 0x7192  # <CJK>
+0x4A28 0x719A  # <CJK>
+0x4A29 0x719B  # <CJK>
+0x4A2A 0x71A0  # <CJK>
+0x4A2B 0x71A2  # <CJK>
+0x4A2C 0x71AF  # <CJK>
+0x4A2D 0x71B0  # <CJK>
+0x4A2E 0x71B2  # <CJK>
+0x4A2F 0x71B3  # <CJK>
+0x4A30 0x71BA  # <CJK>
+0x4A31 0x71BF  # <CJK>
+0x4A32 0x71C0  # <CJK>
+0x4A33 0x71C1  # <CJK>
+0x4A34 0x71C4  # <CJK>
+0x4A35 0x71CB  # <CJK>
+0x4A36 0x71CC  # <CJK>
+0x4A37 0x71D3  # <CJK>
+0x4A38 0x71D6  # <CJK>
+0x4A39 0x71D9  # <CJK>
+0x4A3A 0x71DA  # <CJK>
+0x4A3B 0x71DC  # <CJK>
+0x4A3C 0x71F8  # <CJK>
+0x4A3D 0x71FE  # <CJK>
+0x4A3E 0x7200  # <CJK>
+0x4A3F 0x7207  # <CJK>
+0x4A40 0x7208  # <CJK>
+0x4A41 0x7209  # <CJK>
+0x4A42 0x7213  # <CJK>
+0x4A43 0x7217  # <CJK>
+0x4A44 0x721A  # <CJK>
+0x4A45 0x721D  # <CJK>
+0x4A46 0x721F  # <CJK>
+0x4A47 0x7224  # <CJK>
+0x4A48 0x722B  # <CJK>
+0x4A49 0x722F  # <CJK>
+0x4A4A 0x7234  # <CJK>
+0x4A4B 0x7238  # <CJK>
+0x4A4C 0x7239  # <CJK>
+0x4A4D 0x7241  # <CJK>
+0x4A4E 0x7242  # <CJK>
+0x4A4F 0x7243  # <CJK>
+0x4A50 0x7245  # <CJK>
+0x4A51 0x724E  # <CJK>
+0x4A52 0x724F  # <CJK>
+0x4A53 0x7250  # <CJK>
+0x4A54 0x7253  # <CJK>
+0x4A55 0x7255  # <CJK>
+0x4A56 0x7256  # <CJK>
+0x4A57 0x725A  # <CJK>
+0x4A58 0x725C  # <CJK>
+0x4A59 0x725E  # <CJK>
+0x4A5A 0x7260  # <CJK>
+0x4A5B 0x7263  # <CJK>
+0x4A5C 0x7268  # <CJK>
+0x4A5D 0x726B  # <CJK>
+0x4A5E 0x726E  # <CJK>
+0x4A5F 0x726F  # <CJK>
+0x4A60 0x7271  # <CJK>
+0x4A61 0x7277  # <CJK>
+0x4A62 0x7278  # <CJK>
+0x4A63 0x727B  # <CJK>
+0x4A64 0x727C  # <CJK>
+0x4A65 0x727F  # <CJK>
+0x4A66 0x7284  # <CJK>
+0x4A67 0x7289  # <CJK>
+0x4A68 0x728D  # <CJK>
+0x4A69 0x728E  # <CJK>
+0x4A6A 0x7293  # <CJK>
+0x4A6B 0x729B  # <CJK>
+0x4A6C 0x72A8  # <CJK>
+0x4A6D 0x72AD  # <CJK>
+0x4A6E 0x72AE  # <CJK>
+0x4A6F 0x72B1  # <CJK>
+0x4A70 0x72B4  # <CJK>
+0x4A71 0x72BE  # <CJK>
+0x4A72 0x72C1  # <CJK>
+0x4A73 0x72C7  # <CJK>
+0x4A74 0x72C9  # <CJK>
+0x4A75 0x72CC  # <CJK>
+0x4A76 0x72D5  # <CJK>
+0x4A77 0x72D6  # <CJK>
+0x4A78 0x72D8  # <CJK>
+0x4A79 0x72DF  # <CJK>
+0x4A7A 0x72E5  # <CJK>
+0x4A7B 0x72F3  # <CJK>
+0x4A7C 0x72F4  # <CJK>
+0x4A7D 0x72FA  # <CJK>
+0x4A7E 0x72FB  # <CJK>
+0x4B21 0x72FE  # <CJK>
+0x4B22 0x7302  # <CJK>
+0x4B23 0x7304  # <CJK>
+0x4B24 0x7305  # <CJK>
+0x4B25 0x7307  # <CJK>
+0x4B26 0x730B  # <CJK>
+0x4B27 0x730D  # <CJK>
+0x4B28 0x7312  # <CJK>
+0x4B29 0x7313  # <CJK>
+0x4B2A 0x7318  # <CJK>
+0x4B2B 0x7319  # <CJK>
+0x4B2C 0x731E  # <CJK>
+0x4B2D 0x7322  # <CJK>
+0x4B2E 0x7324  # <CJK>
+0x4B2F 0x7327  # <CJK>
+0x4B30 0x7328  # <CJK>
+0x4B31 0x732C  # <CJK>
+0x4B32 0x7331  # <CJK>
+0x4B33 0x7332  # <CJK>
+0x4B34 0x7335  # <CJK>
+0x4B35 0x733A  # <CJK>
+0x4B36 0x733B  # <CJK>
+0x4B37 0x733D  # <CJK>
+0x4B38 0x7343  # <CJK>
+0x4B39 0x734D  # <CJK>
+0x4B3A 0x7350  # <CJK>
+0x4B3B 0x7352  # <CJK>
+0x4B3C 0x7356  # <CJK>
+0x4B3D 0x7358  # <CJK>
+0x4B3E 0x735D  # <CJK>
+0x4B3F 0x735E  # <CJK>
+0x4B40 0x735F  # <CJK>
+0x4B41 0x7360  # <CJK>
+0x4B42 0x7366  # <CJK>
+0x4B43 0x7367  # <CJK>
+0x4B44 0x7369  # <CJK>
+0x4B45 0x736B  # <CJK>
+0x4B46 0x736C  # <CJK>
+0x4B47 0x736E  # <CJK>
+0x4B48 0x736F  # <CJK>
+0x4B49 0x7371  # <CJK>
+0x4B4A 0x7377  # <CJK>
+0x4B4B 0x7379  # <CJK>
+0x4B4C 0x737C  # <CJK>
+0x4B4D 0x7380  # <CJK>
+0x4B4E 0x7381  # <CJK>
+0x4B4F 0x7383  # <CJK>
+0x4B50 0x7385  # <CJK>
+0x4B51 0x7386  # <CJK>
+0x4B52 0x738E  # <CJK>
+0x4B53 0x7390  # <CJK>
+0x4B54 0x7393  # <CJK>
+0x4B55 0x7395  # <CJK>
+0x4B56 0x7397  # <CJK>
+0x4B57 0x7398  # <CJK>
+0x4B58 0x739C  # <CJK>
+0x4B59 0x739E  # <CJK>
+0x4B5A 0x739F  # <CJK>
+0x4B5B 0x73A0  # <CJK>
+0x4B5C 0x73A2  # <CJK>
+0x4B5D 0x73A5  # <CJK>
+0x4B5E 0x73A6  # <CJK>
+0x4B5F 0x73AA  # <CJK>
+0x4B60 0x73AB  # <CJK>
+0x4B61 0x73AD  # <CJK>
+0x4B62 0x73B5  # <CJK>
+0x4B63 0x73B7  # <CJK>
+0x4B64 0x73B9  # <CJK>
+0x4B65 0x73BC  # <CJK>
+0x4B66 0x73BD  # <CJK>
+0x4B67 0x73BF  # <CJK>
+0x4B68 0x73C5  # <CJK>
+0x4B69 0x73C6  # <CJK>
+0x4B6A 0x73C9  # <CJK>
+0x4B6B 0x73CB  # <CJK>
+0x4B6C 0x73CC  # <CJK>
+0x4B6D 0x73CF  # <CJK>
+0x4B6E 0x73D2  # <CJK>
+0x4B6F 0x73D3  # <CJK>
+0x4B70 0x73D6  # <CJK>
+0x4B71 0x73D9  # <CJK>
+0x4B72 0x73DD  # <CJK>
+0x4B73 0x73E1  # <CJK>
+0x4B74 0x73E3  # <CJK>
+0x4B75 0x73E6  # <CJK>
+0x4B76 0x73E7  # <CJK>
+0x4B77 0x73E9  # <CJK>
+0x4B78 0x73F4  # <CJK>
+0x4B79 0x73F5  # <CJK>
+0x4B7A 0x73F7  # <CJK>
+0x4B7B 0x73F9  # <CJK>
+0x4B7C 0x73FA  # <CJK>
+0x4B7D 0x73FB  # <CJK>
+0x4B7E 0x73FD  # <CJK>
+0x4C21 0x73FF  # <CJK>
+0x4C22 0x7400  # <CJK>
+0x4C23 0x7401  # <CJK>
+0x4C24 0x7404  # <CJK>
+0x4C25 0x7407  # <CJK>
+0x4C26 0x740A  # <CJK>
+0x4C27 0x7411  # <CJK>
+0x4C28 0x741A  # <CJK>
+0x4C29 0x741B  # <CJK>
+0x4C2A 0x7424  # <CJK>
+0x4C2B 0x7426  # <CJK>
+0x4C2C 0x7428  # <CJK>
+0x4C2D 0x7429  # <CJK>
+0x4C2E 0x742A  # <CJK>
+0x4C2F 0x742B  # <CJK>
+0x4C30 0x742C  # <CJK>
+0x4C31 0x742D  # <CJK>
+0x4C32 0x742E  # <CJK>
+0x4C33 0x742F  # <CJK>
+0x4C34 0x7430  # <CJK>
+0x4C35 0x7431  # <CJK>
+0x4C36 0x7439  # <CJK>
+0x4C37 0x7440  # <CJK>
+0x4C38 0x7443  # <CJK>
+0x4C39 0x7444  # <CJK>
+0x4C3A 0x7446  # <CJK>
+0x4C3B 0x7447  # <CJK>
+0x4C3C 0x744B  # <CJK>
+0x4C3D 0x744D  # <CJK>
+0x4C3E 0x7451  # <CJK>
+0x4C3F 0x7452  # <CJK>
+0x4C40 0x7457  # <CJK>
+0x4C41 0x745D  # <CJK>
+0x4C42 0x7462  # <CJK>
+0x4C43 0x7466  # <CJK>
+0x4C44 0x7467  # <CJK>
+0x4C45 0x7468  # <CJK>
+0x4C46 0x746B  # <CJK>
+0x4C47 0x746D  # <CJK>
+0x4C48 0x746E  # <CJK>
+0x4C49 0x7471  # <CJK>
+0x4C4A 0x7472  # <CJK>
+0x4C4B 0x7480  # <CJK>
+0x4C4C 0x7481  # <CJK>
+0x4C4D 0x7485  # <CJK>
+0x4C4E 0x7486  # <CJK>
+0x4C4F 0x7487  # <CJK>
+0x4C50 0x7489  # <CJK>
+0x4C51 0x748F  # <CJK>
+0x4C52 0x7490  # <CJK>
+0x4C53 0x7491  # <CJK>
+0x4C54 0x7492  # <CJK>
+0x4C55 0x7498  # <CJK>
+0x4C56 0x7499  # <CJK>
+0x4C57 0x749A  # <CJK>
+0x4C58 0x749C  # <CJK>
+0x4C59 0x749F  # <CJK>
+0x4C5A 0x74A0  # <CJK>
+0x4C5B 0x74A1  # <CJK>
+0x4C5C 0x74A3  # <CJK>
+0x4C5D 0x74A6  # <CJK>
+0x4C5E 0x74A8  # <CJK>
+0x4C5F 0x74A9  # <CJK>
+0x4C60 0x74AA  # <CJK>
+0x4C61 0x74AB  # <CJK>
+0x4C62 0x74AE  # <CJK>
+0x4C63 0x74AF  # <CJK>
+0x4C64 0x74B1  # <CJK>
+0x4C65 0x74B2  # <CJK>
+0x4C66 0x74B5  # <CJK>
+0x4C67 0x74B9  # <CJK>
+0x4C68 0x74BB  # <CJK>
+0x4C69 0x74BF  # <CJK>
+0x4C6A 0x74C8  # <CJK>
+0x4C6B 0x74C9  # <CJK>
+0x4C6C 0x74CC  # <CJK>
+0x4C6D 0x74D0  # <CJK>
+0x4C6E 0x74D3  # <CJK>
+0x4C6F 0x74D8  # <CJK>
+0x4C70 0x74DA  # <CJK>
+0x4C71 0x74DB  # <CJK>
+0x4C72 0x74DE  # <CJK>
+0x4C73 0x74DF  # <CJK>
+0x4C74 0x74E4  # <CJK>
+0x4C75 0x74E8  # <CJK>
+0x4C76 0x74EA  # <CJK>
+0x4C77 0x74EB  # <CJK>
+0x4C78 0x74EF  # <CJK>
+0x4C79 0x74F4  # <CJK>
+0x4C7A 0x74FA  # <CJK>
+0x4C7B 0x74FB  # <CJK>
+0x4C7C 0x74FC  # <CJK>
+0x4C7D 0x74FF  # <CJK>
+0x4C7E 0x7506  # <CJK>
+0x4D21 0x7512  # <CJK>
+0x4D22 0x7516  # <CJK>
+0x4D23 0x7517  # <CJK>
+0x4D24 0x7520  # <CJK>
+0x4D25 0x7521  # <CJK>
+0x4D26 0x7524  # <CJK>
+0x4D27 0x7527  # <CJK>
+0x4D28 0x7529  # <CJK>
+0x4D29 0x752A  # <CJK>
+0x4D2A 0x752F  # <CJK>
+0x4D2B 0x7536  # <CJK>
+0x4D2C 0x7539  # <CJK>
+0x4D2D 0x753D  # <CJK>
+0x4D2E 0x753E  # <CJK>
+0x4D2F 0x753F  # <CJK>
+0x4D30 0x7540  # <CJK>
+0x4D31 0x7543  # <CJK>
+0x4D32 0x7547  # <CJK>
+0x4D33 0x7548  # <CJK>
+0x4D34 0x754E  # <CJK>
+0x4D35 0x7550  # <CJK>
+0x4D36 0x7552  # <CJK>
+0x4D37 0x7557  # <CJK>
+0x4D38 0x755E  # <CJK>
+0x4D39 0x755F  # <CJK>
+0x4D3A 0x7561  # <CJK>
+0x4D3B 0x756F  # <CJK>
+0x4D3C 0x7571  # <CJK>
+0x4D3D 0x7579  # <CJK>
+0x4D3E 0x757A  # <CJK>
+0x4D3F 0x757B  # <CJK>
+0x4D40 0x757C  # <CJK>
+0x4D41 0x757D  # <CJK>
+0x4D42 0x757E  # <CJK>
+0x4D43 0x7581  # <CJK>
+0x4D44 0x7585  # <CJK>
+0x4D45 0x7590  # <CJK>
+0x4D46 0x7592  # <CJK>
+0x4D47 0x7593  # <CJK>
+0x4D48 0x7595  # <CJK>
+0x4D49 0x7599  # <CJK>
+0x4D4A 0x759C  # <CJK>
+0x4D4B 0x75A2  # <CJK>
+0x4D4C 0x75A4  # <CJK>
+0x4D4D 0x75B4  # <CJK>
+0x4D4E 0x75BA  # <CJK>
+0x4D4F 0x75BF  # <CJK>
+0x4D50 0x75C0  # <CJK>
+0x4D51 0x75C1  # <CJK>
+0x4D52 0x75C4  # <CJK>
+0x4D53 0x75C6  # <CJK>
+0x4D54 0x75CC  # <CJK>
+0x4D55 0x75CE  # <CJK>
+0x4D56 0x75CF  # <CJK>
+0x4D57 0x75D7  # <CJK>
+0x4D58 0x75DC  # <CJK>
+0x4D59 0x75DF  # <CJK>
+0x4D5A 0x75E0  # <CJK>
+0x4D5B 0x75E1  # <CJK>
+0x4D5C 0x75E4  # <CJK>
+0x4D5D 0x75E7  # <CJK>
+0x4D5E 0x75EC  # <CJK>
+0x4D5F 0x75EE  # <CJK>
+0x4D60 0x75EF  # <CJK>
+0x4D61 0x75F1  # <CJK>
+0x4D62 0x75F9  # <CJK>
+0x4D63 0x7600  # <CJK>
+0x4D64 0x7602  # <CJK>
+0x4D65 0x7603  # <CJK>
+0x4D66 0x7604  # <CJK>
+0x4D67 0x7607  # <CJK>
+0x4D68 0x7608  # <CJK>
+0x4D69 0x760A  # <CJK>
+0x4D6A 0x760C  # <CJK>
+0x4D6B 0x760F  # <CJK>
+0x4D6C 0x7612  # <CJK>
+0x4D6D 0x7613  # <CJK>
+0x4D6E 0x7615  # <CJK>
+0x4D6F 0x7616  # <CJK>
+0x4D70 0x7619  # <CJK>
+0x4D71 0x761B  # <CJK>
+0x4D72 0x761C  # <CJK>
+0x4D73 0x761D  # <CJK>
+0x4D74 0x761E  # <CJK>
+0x4D75 0x7623  # <CJK>
+0x4D76 0x7625  # <CJK>
+0x4D77 0x7626  # <CJK>
+0x4D78 0x7629  # <CJK>
+0x4D79 0x762D  # <CJK>
+0x4D7A 0x7632  # <CJK>
+0x4D7B 0x7633  # <CJK>
+0x4D7C 0x7635  # <CJK>
+0x4D7D 0x7638  # <CJK>
+0x4D7E 0x7639  # <CJK>
+0x4E21 0x763A  # <CJK>
+0x4E22 0x763C  # <CJK>
+0x4E23 0x764A  # <CJK>
+0x4E24 0x7640  # <CJK>
+0x4E25 0x7641  # <CJK>
+0x4E26 0x7643  # <CJK>
+0x4E27 0x7644  # <CJK>
+0x4E28 0x7645  # <CJK>
+0x4E29 0x7649  # <CJK>
+0x4E2A 0x764B  # <CJK>
+0x4E2B 0x7655  # <CJK>
+0x4E2C 0x7659  # <CJK>
+0x4E2D 0x765F  # <CJK>
+0x4E2E 0x7664  # <CJK>
+0x4E2F 0x7665  # <CJK>
+0x4E30 0x766D  # <CJK>
+0x4E31 0x766E  # <CJK>
+0x4E32 0x766F  # <CJK>
+0x4E33 0x7671  # <CJK>
+0x4E34 0x7674  # <CJK>
+0x4E35 0x7681  # <CJK>
+0x4E36 0x7685  # <CJK>
+0x4E37 0x768C  # <CJK>
+0x4E38 0x768D  # <CJK>
+0x4E39 0x7695  # <CJK>
+0x4E3A 0x769B  # <CJK>
+0x4E3B 0x769C  # <CJK>
+0x4E3C 0x769D  # <CJK>
+0x4E3D 0x769F  # <CJK>
+0x4E3E 0x76A0  # <CJK>
+0x4E3F 0x76A2  # <CJK>
+0x4E40 0x76A3  # <CJK>
+0x4E41 0x76A4  # <CJK>
+0x4E42 0x76A5  # <CJK>
+0x4E43 0x76A6  # <CJK>
+0x4E44 0x76A7  # <CJK>
+0x4E45 0x76A8  # <CJK>
+0x4E46 0x76AA  # <CJK>
+0x4E47 0x76AD  # <CJK>
+0x4E48 0x76BD  # <CJK>
+0x4E49 0x76C1  # <CJK>
+0x4E4A 0x76C5  # <CJK>
+0x4E4B 0x76C9  # <CJK>
+0x4E4C 0x76CB  # <CJK>
+0x4E4D 0x76CC  # <CJK>
+0x4E4E 0x76CE  # <CJK>
+0x4E4F 0x76D4  # <CJK>
+0x4E50 0x76D9  # <CJK>
+0x4E51 0x76E0  # <CJK>
+0x4E52 0x76E6  # <CJK>
+0x4E53 0x76E8  # <CJK>
+0x4E54 0x76EC  # <CJK>
+0x4E55 0x76F0  # <CJK>
+0x4E56 0x76F1  # <CJK>
+0x4E57 0x76F6  # <CJK>
+0x4E58 0x76F9  # <CJK>
+0x4E59 0x76FC  # <CJK>
+0x4E5A 0x7700  # <CJK>
+0x4E5B 0x7706  # <CJK>
+0x4E5C 0x770A  # <CJK>
+0x4E5D 0x770E  # <CJK>
+0x4E5E 0x7712  # <CJK>
+0x4E5F 0x7714  # <CJK>
+0x4E60 0x7715  # <CJK>
+0x4E61 0x7717  # <CJK>
+0x4E62 0x7719  # <CJK>
+0x4E63 0x771A  # <CJK>
+0x4E64 0x771C  # <CJK>
+0x4E65 0x7722  # <CJK>
+0x4E66 0x7728  # <CJK>
+0x4E67 0x772D  # <CJK>
+0x4E68 0x772E  # <CJK>
+0x4E69 0x772F  # <CJK>
+0x4E6A 0x7734  # <CJK>
+0x4E6B 0x7735  # <CJK>
+0x4E6C 0x7736  # <CJK>
+0x4E6D 0x7739  # <CJK>
+0x4E6E 0x773D  # <CJK>
+0x4E6F 0x773E  # <CJK>
+0x4E70 0x7742  # <CJK>
+0x4E71 0x7745  # <CJK>
+0x4E72 0x7746  # <CJK>
+0x4E73 0x774A  # <CJK>
+0x4E74 0x774D  # <CJK>
+0x4E75 0x774E  # <CJK>
+0x4E76 0x774F  # <CJK>
+0x4E77 0x7752  # <CJK>
+0x4E78 0x7756  # <CJK>
+0x4E79 0x7757  # <CJK>
+0x4E7A 0x775C  # <CJK>
+0x4E7B 0x775E  # <CJK>
+0x4E7C 0x775F  # <CJK>
+0x4E7D 0x7760  # <CJK>
+0x4E7E 0x7762  # <CJK>
+0x4F21 0x7764  # <CJK>
+0x4F22 0x7767  # <CJK>
+0x4F23 0x776A  # <CJK>
+0x4F24 0x776C  # <CJK>
+0x4F25 0x7770  # <CJK>
+0x4F26 0x7772  # <CJK>
+0x4F27 0x7773  # <CJK>
+0x4F28 0x7774  # <CJK>
+0x4F29 0x777A  # <CJK>
+0x4F2A 0x777D  # <CJK>
+0x4F2B 0x7780  # <CJK>
+0x4F2C 0x7784  # <CJK>
+0x4F2D 0x778C  # <CJK>
+0x4F2E 0x778D  # <CJK>
+0x4F2F 0x7794  # <CJK>
+0x4F30 0x7795  # <CJK>
+0x4F31 0x7796  # <CJK>
+0x4F32 0x779A  # <CJK>
+0x4F33 0x779F  # <CJK>
+0x4F34 0x77A2  # <CJK>
+0x4F35 0x77A7  # <CJK>
+0x4F36 0x77AA  # <CJK>
+0x4F37 0x77AE  # <CJK>
+0x4F38 0x77AF  # <CJK>
+0x4F39 0x77B1  # <CJK>
+0x4F3A 0x77B5  # <CJK>
+0x4F3B 0x77BE  # <CJK>
+0x4F3C 0x77C3  # <CJK>
+0x4F3D 0x77C9  # <CJK>
+0x4F3E 0x77D1  # <CJK>
+0x4F3F 0x77D2  # <CJK>
+0x4F40 0x77D5  # <CJK>
+0x4F41 0x77D9  # <CJK>
+0x4F42 0x77DE  # <CJK>
+0x4F43 0x77DF  # <CJK>
+0x4F44 0x77E0  # <CJK>
+0x4F45 0x77E4  # <CJK>
+0x4F46 0x77E6  # <CJK>
+0x4F47 0x77EA  # <CJK>
+0x4F48 0x77EC  # <CJK>
+0x4F49 0x77F0  # <CJK>
+0x4F4A 0x77F1  # <CJK>
+0x4F4B 0x77F4  # <CJK>
+0x4F4C 0x77F8  # <CJK>
+0x4F4D 0x77FB  # <CJK>
+0x4F4E 0x7805  # <CJK>
+0x4F4F 0x7806  # <CJK>
+0x4F50 0x7809  # <CJK>
+0x4F51 0x780D  # <CJK>
+0x4F52 0x780E  # <CJK>
+0x4F53 0x7811  # <CJK>
+0x4F54 0x781D  # <CJK>
+0x4F55 0x7821  # <CJK>
+0x4F56 0x7822  # <CJK>
+0x4F57 0x7823  # <CJK>
+0x4F58 0x782D  # <CJK>
+0x4F59 0x782E  # <CJK>
+0x4F5A 0x7830  # <CJK>
+0x4F5B 0x7835  # <CJK>
+0x4F5C 0x7837  # <CJK>
+0x4F5D 0x7843  # <CJK>
+0x4F5E 0x7844  # <CJK>
+0x4F5F 0x7847  # <CJK>
+0x4F60 0x7848  # <CJK>
+0x4F61 0x784C  # <CJK>
+0x4F62 0x784E  # <CJK>
+0x4F63 0x7852  # <CJK>
+0x4F64 0x785C  # <CJK>
+0x4F65 0x785E  # <CJK>
+0x4F66 0x7860  # <CJK>
+0x4F67 0x7861  # <CJK>
+0x4F68 0x7863  # <CJK>
+0x4F69 0x7864  # <CJK>
+0x4F6A 0x7868  # <CJK>
+0x4F6B 0x786A  # <CJK>
+0x4F6C 0x786E  # <CJK>
+0x4F6D 0x787A  # <CJK>
+0x4F6E 0x787E  # <CJK>
+0x4F6F 0x788A  # <CJK>
+0x4F70 0x788F  # <CJK>
+0x4F71 0x7894  # <CJK>
+0x4F72 0x7898  # <CJK>
+0x4F73 0x78A1  # <CJK>
+0x4F74 0x789D  # <CJK>
+0x4F75 0x789E  # <CJK>
+0x4F76 0x789F  # <CJK>
+0x4F77 0x78A4  # <CJK>
+0x4F78 0x78A8  # <CJK>
+0x4F79 0x78AC  # <CJK>
+0x4F7A 0x78AD  # <CJK>
+0x4F7B 0x78B0  # <CJK>
+0x4F7C 0x78B1  # <CJK>
+0x4F7D 0x78B2  # <CJK>
+0x4F7E 0x78B3  # <CJK>
+0x5021 0x78BB  # <CJK>
+0x5022 0x78BD  # <CJK>
+0x5023 0x78BF  # <CJK>
+0x5024 0x78C7  # <CJK>
+0x5025 0x78C8  # <CJK>
+0x5026 0x78C9  # <CJK>
+0x5027 0x78CC  # <CJK>
+0x5028 0x78CE  # <CJK>
+0x5029 0x78D2  # <CJK>
+0x502A 0x78D3  # <CJK>
+0x502B 0x78D5  # <CJK>
+0x502C 0x78D6  # <CJK>
+0x502D 0x78E4  # <CJK>
+0x502E 0x78DB  # <CJK>
+0x502F 0x78DF  # <CJK>
+0x5030 0x78E0  # <CJK>
+0x5031 0x78E1  # <CJK>
+0x5032 0x78E6  # <CJK>
+0x5033 0x78EA  # <CJK>
+0x5034 0x78F2  # <CJK>
+0x5035 0x78F3  # <CJK>
+0x5036 0x7900  # <CJK>
+0x5037 0x78F6  # <CJK>
+0x5038 0x78F7  # <CJK>
+0x5039 0x78FA  # <CJK>
+0x503A 0x78FB  # <CJK>
+0x503B 0x78FF  # <CJK>
+0x503C 0x7906  # <CJK>
+0x503D 0x790C  # <CJK>
+0x503E 0x7910  # <CJK>
+0x503F 0x791A  # <CJK>
+0x5040 0x791C  # <CJK>
+0x5041 0x791E  # <CJK>
+0x5042 0x791F  # <CJK>
+0x5043 0x7920  # <CJK>
+0x5044 0x7925  # <CJK>
+0x5045 0x7927  # <CJK>
+0x5046 0x7929  # <CJK>
+0x5047 0x792D  # <CJK>
+0x5048 0x7931  # <CJK>
+0x5049 0x7934  # <CJK>
+0x504A 0x7935  # <CJK>
+0x504B 0x793B  # <CJK>
+0x504C 0x793D  # <CJK>
+0x504D 0x793F  # <CJK>
+0x504E 0x7944  # <CJK>
+0x504F 0x7945  # <CJK>
+0x5050 0x7946  # <CJK>
+0x5051 0x794A  # <CJK>
+0x5052 0x794B  # <CJK>
+0x5053 0x794F  # <CJK>
+0x5054 0x7951  # <CJK>
+0x5055 0x7954  # <CJK>
+0x5056 0x7958  # <CJK>
+0x5057 0x795B  # <CJK>
+0x5058 0x795C  # <CJK>
+0x5059 0x7967  # <CJK>
+0x505A 0x7969  # <CJK>
+0x505B 0x796B  # <CJK>
+0x505C 0x7972  # <CJK>
+0x505D 0x7979  # <CJK>
+0x505E 0x797B  # <CJK>
+0x505F 0x797C  # <CJK>
+0x5060 0x797E  # <CJK>
+0x5061 0x798B  # <CJK>
+0x5062 0x798C  # <CJK>
+0x5063 0x7991  # <CJK>
+0x5064 0x7993  # <CJK>
+0x5065 0x7994  # <CJK>
+0x5066 0x7995  # <CJK>
+0x5067 0x7996  # <CJK>
+0x5068 0x7998  # <CJK>
+0x5069 0x799B  # <CJK>
+0x506A 0x799C  # <CJK>
+0x506B 0x79A1  # <CJK>
+0x506C 0x79A8  # <CJK>
+0x506D 0x79A9  # <CJK>
+0x506E 0x79AB  # <CJK>
+0x506F 0x79AF  # <CJK>
+0x5070 0x79B1  # <CJK>
+0x5071 0x79B4  # <CJK>
+0x5072 0x79B8  # <CJK>
+0x5073 0x79BB  # <CJK>
+0x5074 0x79C2  # <CJK>
+0x5075 0x79C4  # <CJK>
+0x5076 0x79C7  # <CJK>
+0x5077 0x79C8  # <CJK>
+0x5078 0x79CA  # <CJK>
+0x5079 0x79CF  # <CJK>
+0x507A 0x79D4  # <CJK>
+0x507B 0x79D6  # <CJK>
+0x507C 0x79DA  # <CJK>
+0x507D 0x79DD  # <CJK>
+0x507E 0x79DE  # <CJK>
+0x5121 0x79E0  # <CJK>
+0x5122 0x79E2  # <CJK>
+0x5123 0x79E5  # <CJK>
+0x5124 0x79EA  # <CJK>
+0x5125 0x79EB  # <CJK>
+0x5126 0x79ED  # <CJK>
+0x5127 0x79F1  # <CJK>
+0x5128 0x79F8  # <CJK>
+0x5129 0x79FC  # <CJK>
+0x512A 0x7A02  # <CJK>
+0x512B 0x7A03  # <CJK>
+0x512C 0x7A07  # <CJK>
+0x512D 0x7A09  # <CJK>
+0x512E 0x7A0A  # <CJK>
+0x512F 0x7A0C  # <CJK>
+0x5130 0x7A11  # <CJK>
+0x5131 0x7A15  # <CJK>
+0x5132 0x7A1B  # <CJK>
+0x5133 0x7A1E  # <CJK>
+0x5134 0x7A21  # <CJK>
+0x5135 0x7A27  # <CJK>
+0x5136 0x7A2B  # <CJK>
+0x5137 0x7A2D  # <CJK>
+0x5138 0x7A2F  # <CJK>
+0x5139 0x7A30  # <CJK>
+0x513A 0x7A34  # <CJK>
+0x513B 0x7A35  # <CJK>
+0x513C 0x7A38  # <CJK>
+0x513D 0x7A39  # <CJK>
+0x513E 0x7A3A  # <CJK>
+0x513F 0x7A44  # <CJK>
+0x5140 0x7A45  # <CJK>
+0x5141 0x7A47  # <CJK>
+0x5142 0x7A48  # <CJK>
+0x5143 0x7A4C  # <CJK>
+0x5144 0x7A55  # <CJK>
+0x5145 0x7A56  # <CJK>
+0x5146 0x7A59  # <CJK>
+0x5147 0x7A5C  # <CJK>
+0x5148 0x7A5D  # <CJK>
+0x5149 0x7A5F  # <CJK>
+0x514A 0x7A60  # <CJK>
+0x514B 0x7A65  # <CJK>
+0x514C 0x7A67  # <CJK>
+0x514D 0x7A6A  # <CJK>
+0x514E 0x7A6D  # <CJK>
+0x514F 0x7A75  # <CJK>
+0x5150 0x7A78  # <CJK>
+0x5151 0x7A7E  # <CJK>
+0x5152 0x7A80  # <CJK>
+0x5153 0x7A82  # <CJK>
+0x5154 0x7A85  # <CJK>
+0x5155 0x7A86  # <CJK>
+0x5156 0x7A8A  # <CJK>
+0x5157 0x7A8B  # <CJK>
+0x5158 0x7A90  # <CJK>
+0x5159 0x7A91  # <CJK>
+0x515A 0x7A94  # <CJK>
+0x515B 0x7A9E  # <CJK>
+0x515C 0x7AA0  # <CJK>
+0x515D 0x7AA3  # <CJK>
+0x515E 0x7AAC  # <CJK>
+0x515F 0x7AB3  # <CJK>
+0x5160 0x7AB5  # <CJK>
+0x5161 0x7AB9  # <CJK>
+0x5162 0x7ABB  # <CJK>
+0x5163 0x7ABC  # <CJK>
+0x5164 0x7AC6  # <CJK>
+0x5165 0x7AC9  # <CJK>
+0x5166 0x7ACC  # <CJK>
+0x5167 0x7ACE  # <CJK>
+0x5168 0x7AD1  # <CJK>
+0x5169 0x7ADB  # <CJK>
+0x516A 0x7AE8  # <CJK>
+0x516B 0x7AE9  # <CJK>
+0x516C 0x7AEB  # <CJK>
+0x516D 0x7AEC  # <CJK>
+0x516E 0x7AF1  # <CJK>
+0x516F 0x7AF4  # <CJK>
+0x5170 0x7AFB  # <CJK>
+0x5171 0x7AFD  # <CJK>
+0x5172 0x7AFE  # <CJK>
+0x5173 0x7B07  # <CJK>
+0x5174 0x7B14  # <CJK>
+0x5175 0x7B1F  # <CJK>
+0x5176 0x7B23  # <CJK>
+0x5177 0x7B27  # <CJK>
+0x5178 0x7B29  # <CJK>
+0x5179 0x7B2A  # <CJK>
+0x517A 0x7B2B  # <CJK>
+0x517B 0x7B2D  # <CJK>
+0x517C 0x7B2E  # <CJK>
+0x517D 0x7B2F  # <CJK>
+0x517E 0x7B30  # <CJK>
+0x5221 0x7B31  # <CJK>
+0x5222 0x7B34  # <CJK>
+0x5223 0x7B3D  # <CJK>
+0x5224 0x7B3F  # <CJK>
+0x5225 0x7B40  # <CJK>
+0x5226 0x7B41  # <CJK>
+0x5227 0x7B47  # <CJK>
+0x5228 0x7B4E  # <CJK>
+0x5229 0x7B55  # <CJK>
+0x522A 0x7B60  # <CJK>
+0x522B 0x7B64  # <CJK>
+0x522C 0x7B66  # <CJK>
+0x522D 0x7B69  # <CJK>
+0x522E 0x7B6A  # <CJK>
+0x522F 0x7B6D  # <CJK>
+0x5230 0x7B6F  # <CJK>
+0x5231 0x7B72  # <CJK>
+0x5232 0x7B73  # <CJK>
+0x5233 0x7B77  # <CJK>
+0x5234 0x7B84  # <CJK>
+0x5235 0x7B89  # <CJK>
+0x5236 0x7B8E  # <CJK>
+0x5237 0x7B90  # <CJK>
+0x5238 0x7B91  # <CJK>
+0x5239 0x7B96  # <CJK>
+0x523A 0x7B9B  # <CJK>
+0x523B 0x7B9E  # <CJK>
+0x523C 0x7BA0  # <CJK>
+0x523D 0x7BA5  # <CJK>
+0x523E 0x7BAC  # <CJK>
+0x523F 0x7BAF  # <CJK>
+0x5240 0x7BB0  # <CJK>
+0x5241 0x7BB2  # <CJK>
+0x5242 0x7BB5  # <CJK>
+0x5243 0x7BB6  # <CJK>
+0x5244 0x7BBA  # <CJK>
+0x5245 0x7BBB  # <CJK>
+0x5246 0x7BBC  # <CJK>
+0x5247 0x7BBD  # <CJK>
+0x5248 0x7BC2  # <CJK>
+0x5249 0x7BC5  # <CJK>
+0x524A 0x7BC8  # <CJK>
+0x524B 0x7BCA  # <CJK>
+0x524C 0x7BD4  # <CJK>
+0x524D 0x7BD6  # <CJK>
+0x524E 0x7BD7  # <CJK>
+0x524F 0x7BD9  # <CJK>
+0x5250 0x7BDA  # <CJK>
+0x5251 0x7BDB  # <CJK>
+0x5252 0x7BE8  # <CJK>
+0x5253 0x7BEA  # <CJK>
+0x5254 0x7BF2  # <CJK>
+0x5255 0x7BF4  # <CJK>
+0x5256 0x7BF5  # <CJK>
+0x5257 0x7BF8  # <CJK>
+0x5258 0x7BF9  # <CJK>
+0x5259 0x7BFA  # <CJK>
+0x525A 0x7BFC  # <CJK>
+0x525B 0x7BFE  # <CJK>
+0x525C 0x7C01  # <CJK>
+0x525D 0x7C02  # <CJK>
+0x525E 0x7C03  # <CJK>
+0x525F 0x7C04  # <CJK>
+0x5260 0x7C06  # <CJK>
+0x5261 0x7C09  # <CJK>
+0x5262 0x7C0B  # <CJK>
+0x5263 0x7C0C  # <CJK>
+0x5264 0x7C0E  # <CJK>
+0x5265 0x7C0F  # <CJK>
+0x5266 0x7C19  # <CJK>
+0x5267 0x7C1B  # <CJK>
+0x5268 0x7C20  # <CJK>
+0x5269 0x7C25  # <CJK>
+0x526A 0x7C26  # <CJK>
+0x526B 0x7C28  # <CJK>
+0x526C 0x7C2C  # <CJK>
+0x526D 0x7C31  # <CJK>
+0x526E 0x7C33  # <CJK>
+0x526F 0x7C34  # <CJK>
+0x5270 0x7C36  # <CJK>
+0x5271 0x7C39  # <CJK>
+0x5272 0x7C3A  # <CJK>
+0x5273 0x7C46  # <CJK>
+0x5274 0x7C4A  # <CJK>
+0x5275 0x7C55  # <CJK>
+0x5276 0x7C51  # <CJK>
+0x5277 0x7C52  # <CJK>
+0x5278 0x7C53  # <CJK>
+0x5279 0x7C59  # <CJK>
+0x527A 0x7C5A  # <CJK>
+0x527B 0x7C5B  # <CJK>
+0x527C 0x7C5C  # <CJK>
+0x527D 0x7C5D  # <CJK>
+0x527E 0x7C5E  # <CJK>
+0x5321 0x7C61  # <CJK>
+0x5322 0x7C63  # <CJK>
+0x5323 0x7C67  # <CJK>
+0x5324 0x7C69  # <CJK>
+0x5325 0x7C6D  # <CJK>
+0x5326 0x7C6E  # <CJK>
+0x5327 0x7C70  # <CJK>
+0x5328 0x7C72  # <CJK>
+0x5329 0x7C79  # <CJK>
+0x532A 0x7C7C  # <CJK>
+0x532B 0x7C7D  # <CJK>
+0x532C 0x7C86  # <CJK>
+0x532D 0x7C87  # <CJK>
+0x532E 0x7C8F  # <CJK>
+0x532F 0x7C94  # <CJK>
+0x5330 0x7C9E  # <CJK>
+0x5331 0x7CA0  # <CJK>
+0x5332 0x7CA6  # <CJK>
+0x5333 0x7CB0  # <CJK>
+0x5334 0x7CB6  # <CJK>
+0x5335 0x7CB7  # <CJK>
+0x5336 0x7CBA  # <CJK>
+0x5337 0x7CBB  # <CJK>
+0x5338 0x7CBC  # <CJK>
+0x5339 0x7CBF  # <CJK>
+0x533A 0x7CC4  # <CJK>
+0x533B 0x7CC7  # <CJK>
+0x533C 0x7CC8  # <CJK>
+0x533D 0x7CC9  # <CJK>
+0x533E 0x7CCD  # <CJK>
+0x533F 0x7CCF  # <CJK>
+0x5340 0x7CD3  # <CJK>
+0x5341 0x7CD4  # <CJK>
+0x5342 0x7CD5  # <CJK>
+0x5343 0x7CD7  # <CJK>
+0x5344 0x7CD9  # <CJK>
+0x5345 0x7CDA  # <CJK>
+0x5346 0x7CDD  # <CJK>
+0x5347 0x7CE6  # <CJK>
+0x5348 0x7CE9  # <CJK>
+0x5349 0x7CEB  # <CJK>
+0x534A 0x7CF5  # <CJK>
+0x534B 0x7D03  # <CJK>
+0x534C 0x7D07  # <CJK>
+0x534D 0x7D08  # <CJK>
+0x534E 0x7D09  # <CJK>
+0x534F 0x7D0F  # <CJK>
+0x5350 0x7D11  # <CJK>
+0x5351 0x7D12  # <CJK>
+0x5352 0x7D13  # <CJK>
+0x5353 0x7D16  # <CJK>
+0x5354 0x7D1D  # <CJK>
+0x5355 0x7D1E  # <CJK>
+0x5356 0x7D23  # <CJK>
+0x5357 0x7D26  # <CJK>
+0x5358 0x7D2A  # <CJK>
+0x5359 0x7D2D  # <CJK>
+0x535A 0x7D31  # <CJK>
+0x535B 0x7D3C  # <CJK>
+0x535C 0x7D3D  # <CJK>
+0x535D 0x7D3E  # <CJK>
+0x535E 0x7D40  # <CJK>
+0x535F 0x7D41  # <CJK>
+0x5360 0x7D47  # <CJK>
+0x5361 0x7D48  # <CJK>
+0x5362 0x7D4D  # <CJK>
+0x5363 0x7D51  # <CJK>
+0x5364 0x7D53  # <CJK>
+0x5365 0x7D57  # <CJK>
+0x5366 0x7D59  # <CJK>
+0x5367 0x7D5A  # <CJK>
+0x5368 0x7D5C  # <CJK>
+0x5369 0x7D5D  # <CJK>
+0x536A 0x7D65  # <CJK>
+0x536B 0x7D67  # <CJK>
+0x536C 0x7D6A  # <CJK>
+0x536D 0x7D70  # <CJK>
+0x536E 0x7D78  # <CJK>
+0x536F 0x7D7A  # <CJK>
+0x5370 0x7D7B  # <CJK>
+0x5371 0x7D7F  # <CJK>
+0x5372 0x7D81  # <CJK>
+0x5373 0x7D82  # <CJK>
+0x5374 0x7D83  # <CJK>
+0x5375 0x7D85  # <CJK>
+0x5376 0x7D86  # <CJK>
+0x5377 0x7D88  # <CJK>
+0x5378 0x7D8B  # <CJK>
+0x5379 0x7D8C  # <CJK>
+0x537A 0x7D8D  # <CJK>
+0x537B 0x7D91  # <CJK>
+0x537C 0x7D96  # <CJK>
+0x537D 0x7D97  # <CJK>
+0x537E 0x7D9D  # <CJK>
+0x5421 0x7D9E  # <CJK>
+0x5422 0x7DA6  # <CJK>
+0x5423 0x7DA7  # <CJK>
+0x5424 0x7DAA  # <CJK>
+0x5425 0x7DB3  # <CJK>
+0x5426 0x7DB6  # <CJK>
+0x5427 0x7DB7  # <CJK>
+0x5428 0x7DB9  # <CJK>
+0x5429 0x7DC2  # <CJK>
+0x542A 0x7DC3  # <CJK>
+0x542B 0x7DC4  # <CJK>
+0x542C 0x7DC5  # <CJK>
+0x542D 0x7DC6  # <CJK>
+0x542E 0x7DCC  # <CJK>
+0x542F 0x7DCD  # <CJK>
+0x5430 0x7DCE  # <CJK>
+0x5431 0x7DD7  # <CJK>
+0x5432 0x7DD9  # <CJK>
+0x5433 0x7E00  # <CJK>
+0x5434 0x7DE2  # <CJK>
+0x5435 0x7DE5  # <CJK>
+0x5436 0x7DE6  # <CJK>
+0x5437 0x7DEA  # <CJK>
+0x5438 0x7DEB  # <CJK>
+0x5439 0x7DED  # <CJK>
+0x543A 0x7DF1  # <CJK>
+0x543B 0x7DF5  # <CJK>
+0x543C 0x7DF6  # <CJK>
+0x543D 0x7DF9  # <CJK>
+0x543E 0x7DFA  # <CJK>
+0x543F 0x7E08  # <CJK>
+0x5440 0x7E10  # <CJK>
+0x5441 0x7E11  # <CJK>
+0x5442 0x7E15  # <CJK>
+0x5443 0x7E17  # <CJK>
+0x5444 0x7E1C  # <CJK>
+0x5445 0x7E1D  # <CJK>
+0x5446 0x7E20  # <CJK>
+0x5447 0x7E27  # <CJK>
+0x5448 0x7E28  # <CJK>
+0x5449 0x7E2C  # <CJK>
+0x544A 0x7E2D  # <CJK>
+0x544B 0x7E2F  # <CJK>
+0x544C 0x7E33  # <CJK>
+0x544D 0x7E36  # <CJK>
+0x544E 0x7E3F  # <CJK>
+0x544F 0x7E44  # <CJK>
+0x5450 0x7E45  # <CJK>
+0x5451 0x7E47  # <CJK>
+0x5452 0x7E4E  # <CJK>
+0x5453 0x7E50  # <CJK>
+0x5454 0x7E52  # <CJK>
+0x5455 0x7E58  # <CJK>
+0x5456 0x7E5F  # <CJK>
+0x5457 0x7E61  # <CJK>
+0x5458 0x7E62  # <CJK>
+0x5459 0x7E65  # <CJK>
+0x545A 0x7E6B  # <CJK>
+0x545B 0x7E6E  # <CJK>
+0x545C 0x7E6F  # <CJK>
+0x545D 0x7E73  # <CJK>
+0x545E 0x7E78  # <CJK>
+0x545F 0x7E7E  # <CJK>
+0x5460 0x7E81  # <CJK>
+0x5461 0x7E86  # <CJK>
+0x5462 0x7E87  # <CJK>
+0x5463 0x7E8A  # <CJK>
+0x5464 0x7E8D  # <CJK>
+0x5465 0x7E91  # <CJK>
+0x5466 0x7E95  # <CJK>
+0x5467 0x7E98  # <CJK>
+0x5468 0x7E9A  # <CJK>
+0x5469 0x7E9D  # <CJK>
+0x546A 0x7E9E  # <CJK>
+0x546B 0x7F3C  # <CJK>
+0x546C 0x7F3B  # <CJK>
+0x546D 0x7F3D  # <CJK>
+0x546E 0x7F3E  # <CJK>
+0x546F 0x7F3F  # <CJK>
+0x5470 0x7F43  # <CJK>
+0x5471 0x7F44  # <CJK>
+0x5472 0x7F47  # <CJK>
+0x5473 0x7F4F  # <CJK>
+0x5474 0x7F52  # <CJK>
+0x5475 0x7F53  # <CJK>
+0x5476 0x7F5B  # <CJK>
+0x5477 0x7F5C  # <CJK>
+0x5478 0x7F5D  # <CJK>
+0x5479 0x7F61  # <CJK>
+0x547A 0x7F63  # <CJK>
+0x547B 0x7F64  # <CJK>
+0x547C 0x7F65  # <CJK>
+0x547D 0x7F66  # <CJK>
+0x547E 0x7F6D  # <CJK>
+0x5521 0x7F71  # <CJK>
+0x5522 0x7F7D  # <CJK>
+0x5523 0x7F7E  # <CJK>
+0x5524 0x7F7F  # <CJK>
+0x5525 0x7F80  # <CJK>
+0x5526 0x7F8B  # <CJK>
+0x5527 0x7F8D  # <CJK>
+0x5528 0x7F8F  # <CJK>
+0x5529 0x7F90  # <CJK>
+0x552A 0x7F91  # <CJK>
+0x552B 0x7F96  # <CJK>
+0x552C 0x7F97  # <CJK>
+0x552D 0x7F9C  # <CJK>
+0x552E 0x7FA1  # <CJK>
+0x552F 0x7FA2  # <CJK>
+0x5530 0x7FA6  # <CJK>
+0x5531 0x7FAA  # <CJK>
+0x5532 0x7FAD  # <CJK>
+0x5533 0x7FB4  # <CJK>
+0x5534 0x7FBC  # <CJK>
+0x5535 0x7FBF  # <CJK>
+0x5536 0x7FC0  # <CJK>
+0x5537 0x7FC3  # <CJK>
+0x5538 0x7FC8  # <CJK>
+0x5539 0x7FCE  # <CJK>
+0x553A 0x7FCF  # <CJK>
+0x553B 0x7FDB  # <CJK>
+0x553C 0x7FDF  # <CJK>
+0x553D 0x7FE3  # <CJK>
+0x553E 0x7FE5  # <CJK>
+0x553F 0x7FE8  # <CJK>
+0x5540 0x7FEC  # <CJK>
+0x5541 0x7FEE  # <CJK>
+0x5542 0x7FEF  # <CJK>
+0x5543 0x7FF2  # <CJK>
+0x5544 0x7FFA  # <CJK>
+0x5545 0x7FFD  # <CJK>
+0x5546 0x7FFE  # <CJK>
+0x5547 0x7FFF  # <CJK>
+0x5548 0x8007  # <CJK>
+0x5549 0x8008  # <CJK>
+0x554A 0x800A  # <CJK>
+0x554B 0x800D  # <CJK>
+0x554C 0x800E  # <CJK>
+0x554D 0x800F  # <CJK>
+0x554E 0x8011  # <CJK>
+0x554F 0x8013  # <CJK>
+0x5550 0x8014  # <CJK>
+0x5551 0x8016  # <CJK>
+0x5552 0x801D  # <CJK>
+0x5553 0x801E  # <CJK>
+0x5554 0x801F  # <CJK>
+0x5555 0x8020  # <CJK>
+0x5556 0x8024  # <CJK>
+0x5557 0x8026  # <CJK>
+0x5558 0x802C  # <CJK>
+0x5559 0x802E  # <CJK>
+0x555A 0x8030  # <CJK>
+0x555B 0x8034  # <CJK>
+0x555C 0x8035  # <CJK>
+0x555D 0x8037  # <CJK>
+0x555E 0x8039  # <CJK>
+0x555F 0x803A  # <CJK>
+0x5560 0x803C  # <CJK>
+0x5561 0x803E  # <CJK>
+0x5562 0x8040  # <CJK>
+0x5563 0x8044  # <CJK>
+0x5564 0x8060  # <CJK>
+0x5565 0x8064  # <CJK>
+0x5566 0x8066  # <CJK>
+0x5567 0x806D  # <CJK>
+0x5568 0x8071  # <CJK>
+0x5569 0x8075  # <CJK>
+0x556A 0x8081  # <CJK>
+0x556B 0x8088  # <CJK>
+0x556C 0x808E  # <CJK>
+0x556D 0x809C  # <CJK>
+0x556E 0x809E  # <CJK>
+0x556F 0x80A6  # <CJK>
+0x5570 0x80A7  # <CJK>
+0x5571 0x80AB  # <CJK>
+0x5572 0x80B8  # <CJK>
+0x5573 0x80B9  # <CJK>
+0x5574 0x80C8  # <CJK>
+0x5575 0x80CD  # <CJK>
+0x5576 0x80CF  # <CJK>
+0x5577 0x80D2  # <CJK>
+0x5578 0x80D4  # <CJK>
+0x5579 0x80D5  # <CJK>
+0x557A 0x80D7  # <CJK>
+0x557B 0x80D8  # <CJK>
+0x557C 0x80E0  # <CJK>
+0x557D 0x80ED  # <CJK>
+0x557E 0x80EE  # <CJK>
+0x5621 0x80F0  # <CJK>
+0x5622 0x80F2  # <CJK>
+0x5623 0x80F3  # <CJK>
+0x5624 0x80F6  # <CJK>
+0x5625 0x80F9  # <CJK>
+0x5626 0x80FA  # <CJK>
+0x5627 0x80FE  # <CJK>
+0x5628 0x8103  # <CJK>
+0x5629 0x810B  # <CJK>
+0x562A 0x8116  # <CJK>
+0x562B 0x8117  # <CJK>
+0x562C 0x8118  # <CJK>
+0x562D 0x811C  # <CJK>
+0x562E 0x811E  # <CJK>
+0x562F 0x8120  # <CJK>
+0x5630 0x8124  # <CJK>
+0x5631 0x8127  # <CJK>
+0x5632 0x812C  # <CJK>
+0x5633 0x8130  # <CJK>
+0x5634 0x8135  # <CJK>
+0x5635 0x813A  # <CJK>
+0x5636 0x813C  # <CJK>
+0x5637 0x8145  # <CJK>
+0x5638 0x8147  # <CJK>
+0x5639 0x814A  # <CJK>
+0x563A 0x814C  # <CJK>
+0x563B 0x8152  # <CJK>
+0x563C 0x8157  # <CJK>
+0x563D 0x8160  # <CJK>
+0x563E 0x8161  # <CJK>
+0x563F 0x8167  # <CJK>
+0x5640 0x8168  # <CJK>
+0x5641 0x8169  # <CJK>
+0x5642 0x816D  # <CJK>
+0x5643 0x816F  # <CJK>
+0x5644 0x8177  # <CJK>
+0x5645 0x8181  # <CJK>
+0x5646 0x8190  # <CJK>
+0x5647 0x8184  # <CJK>
+0x5648 0x8185  # <CJK>
+0x5649 0x8186  # <CJK>
+0x564A 0x818B  # <CJK>
+0x564B 0x818E  # <CJK>
+0x564C 0x8196  # <CJK>
+0x564D 0x8198  # <CJK>
+0x564E 0x819B  # <CJK>
+0x564F 0x819E  # <CJK>
+0x5650 0x81A2  # <CJK>
+0x5651 0x81AE  # <CJK>
+0x5652 0x81B2  # <CJK>
+0x5653 0x81B4  # <CJK>
+0x5654 0x81BB  # <CJK>
+0x5655 0x81CB  # <CJK>
+0x5656 0x81C3  # <CJK>
+0x5657 0x81C5  # <CJK>
+0x5658 0x81CA  # <CJK>
+0x5659 0x81CE  # <CJK>
+0x565A 0x81CF  # <CJK>
+0x565B 0x81D5  # <CJK>
+0x565C 0x81D7  # <CJK>
+0x565D 0x81DB  # <CJK>
+0x565E 0x81DD  # <CJK>
+0x565F 0x81DE  # <CJK>
+0x5660 0x81E1  # <CJK>
+0x5661 0x81E4  # <CJK>
+0x5662 0x81EB  # <CJK>
+0x5663 0x81EC  # <CJK>
+0x5664 0x81F0  # <CJK>
+0x5665 0x81F1  # <CJK>
+0x5666 0x81F2  # <CJK>
+0x5667 0x81F5  # <CJK>
+0x5668 0x81F6  # <CJK>
+0x5669 0x81F8  # <CJK>
+0x566A 0x81F9  # <CJK>
+0x566B 0x81FD  # <CJK>
+0x566C 0x81FF  # <CJK>
+0x566D 0x8200  # <CJK>
+0x566E 0x8203  # <CJK>
+0x566F 0x820F  # <CJK>
+0x5670 0x8213  # <CJK>
+0x5671 0x8214  # <CJK>
+0x5672 0x8219  # <CJK>
+0x5673 0x821A  # <CJK>
+0x5674 0x821D  # <CJK>
+0x5675 0x8221  # <CJK>
+0x5676 0x8222  # <CJK>
+0x5677 0x8228  # <CJK>
+0x5678 0x8232  # <CJK>
+0x5679 0x8234  # <CJK>
+0x567A 0x823A  # <CJK>
+0x567B 0x8243  # <CJK>
+0x567C 0x8244  # <CJK>
+0x567D 0x8245  # <CJK>
+0x567E 0x8246  # <CJK>
+0x5721 0x824B  # <CJK>
+0x5722 0x824E  # <CJK>
+0x5723 0x824F  # <CJK>
+0x5724 0x8251  # <CJK>
+0x5725 0x8256  # <CJK>
+0x5726 0x825C  # <CJK>
+0x5727 0x8260  # <CJK>
+0x5728 0x8263  # <CJK>
+0x5729 0x8267  # <CJK>
+0x572A 0x826D  # <CJK>
+0x572B 0x8274  # <CJK>
+0x572C 0x827B  # <CJK>
+0x572D 0x827D  # <CJK>
+0x572E 0x827F  # <CJK>
+0x572F 0x8280  # <CJK>
+0x5730 0x8281  # <CJK>
+0x5731 0x8283  # <CJK>
+0x5732 0x8284  # <CJK>
+0x5733 0x8287  # <CJK>
+0x5734 0x8289  # <CJK>
+0x5735 0x828A  # <CJK>
+0x5736 0x828E  # <CJK>
+0x5737 0x8291  # <CJK>
+0x5738 0x8294  # <CJK>
+0x5739 0x8296  # <CJK>
+0x573A 0x8298  # <CJK>
+0x573B 0x829A  # <CJK>
+0x573C 0x829B  # <CJK>
+0x573D 0x82A0  # <CJK>
+0x573E 0x82A1  # <CJK>
+0x573F 0x82A3  # <CJK>
+0x5740 0x82A4  # <CJK>
+0x5741 0x82A7  # <CJK>
+0x5742 0x82A8  # <CJK>
+0x5743 0x82A9  # <CJK>
+0x5744 0x82AA  # <CJK>
+0x5745 0x82AE  # <CJK>
+0x5746 0x82B0  # <CJK>
+0x5747 0x82B2  # <CJK>
+0x5748 0x82B4  # <CJK>
+0x5749 0x82B7  # <CJK>
+0x574A 0x82BA  # <CJK>
+0x574B 0x82BC  # <CJK>
+0x574C 0x82BE  # <CJK>
+0x574D 0x82BF  # <CJK>
+0x574E 0x82C6  # <CJK>
+0x574F 0x82D0  # <CJK>
+0x5750 0x82D5  # <CJK>
+0x5751 0x82DA  # <CJK>
+0x5752 0x82E0  # <CJK>
+0x5753 0x82E2  # <CJK>
+0x5754 0x82E4  # <CJK>
+0x5755 0x82E8  # <CJK>
+0x5756 0x82EA  # <CJK>
+0x5757 0x82ED  # <CJK>
+0x5758 0x82EF  # <CJK>
+0x5759 0x82F6  # <CJK>
+0x575A 0x82F7  # <CJK>
+0x575B 0x82FD  # <CJK>
+0x575C 0x82FE  # <CJK>
+0x575D 0x8300  # <CJK>
+0x575E 0x8301  # <CJK>
+0x575F 0x8307  # <CJK>
+0x5760 0x8308  # <CJK>
+0x5761 0x830A  # <CJK>
+0x5762 0x830B  # <CJK>
+0x5763 0x8354  # <CJK>
+0x5764 0x831B  # <CJK>
+0x5765 0x831D  # <CJK>
+0x5766 0x831E  # <CJK>
+0x5767 0x831F  # <CJK>
+0x5768 0x8321  # <CJK>
+0x5769 0x8322  # <CJK>
+0x576A 0x832C  # <CJK>
+0x576B 0x832D  # <CJK>
+0x576C 0x832E  # <CJK>
+0x576D 0x8330  # <CJK>
+0x576E 0x8333  # <CJK>
+0x576F 0x8337  # <CJK>
+0x5770 0x833A  # <CJK>
+0x5771 0x833C  # <CJK>
+0x5772 0x833D  # <CJK>
+0x5773 0x8342  # <CJK>
+0x5774 0x8343  # <CJK>
+0x5775 0x8344  # <CJK>
+0x5776 0x8347  # <CJK>
+0x5777 0x834D  # <CJK>
+0x5778 0x834E  # <CJK>
+0x5779 0x8351  # <CJK>
+0x577A 0x8355  # <CJK>
+0x577B 0x8356  # <CJK>
+0x577C 0x8357  # <CJK>
+0x577D 0x8370  # <CJK>
+0x577E 0x8378  # <CJK>
+0x5821 0x837D  # <CJK>
+0x5822 0x837F  # <CJK>
+0x5823 0x8380  # <CJK>
+0x5824 0x8382  # <CJK>
+0x5825 0x8384  # <CJK>
+0x5826 0x8386  # <CJK>
+0x5827 0x838D  # <CJK>
+0x5828 0x8392  # <CJK>
+0x5829 0x8394  # <CJK>
+0x582A 0x8395  # <CJK>
+0x582B 0x8398  # <CJK>
+0x582C 0x8399  # <CJK>
+0x582D 0x839B  # <CJK>
+0x582E 0x839C  # <CJK>
+0x582F 0x839D  # <CJK>
+0x5830 0x83A6  # <CJK>
+0x5831 0x83A7  # <CJK>
+0x5832 0x83A9  # <CJK>
+0x5833 0x83AC  # <CJK>
+0x5834 0x83BE  # <CJK>
+0x5835 0x83BF  # <CJK>
+0x5836 0x83C0  # <CJK>
+0x5837 0x83C7  # <CJK>
+0x5838 0x83C9  # <CJK>
+0x5839 0x83CF  # <CJK>
+0x583A 0x83D0  # <CJK>
+0x583B 0x83D1  # <CJK>
+0x583C 0x83D4  # <CJK>
+0x583D 0x83DD  # <CJK>
+0x583E 0x8353  # <CJK>
+0x583F 0x83E8  # <CJK>
+0x5840 0x83EA  # <CJK>
+0x5841 0x83F6  # <CJK>
+0x5842 0x83F8  # <CJK>
+0x5843 0x83F9  # <CJK>
+0x5844 0x83FC  # <CJK>
+0x5845 0x8401  # <CJK>
+0x5846 0x8406  # <CJK>
+0x5847 0x840A  # <CJK>
+0x5848 0x840F  # <CJK>
+0x5849 0x8411  # <CJK>
+0x584A 0x8415  # <CJK>
+0x584B 0x8419  # <CJK>
+0x584C 0x83AD  # <CJK>
+0x584D 0x842F  # <CJK>
+0x584E 0x8439  # <CJK>
+0x584F 0x8445  # <CJK>
+0x5850 0x8447  # <CJK>
+0x5851 0x8448  # <CJK>
+0x5852 0x844A  # <CJK>
+0x5853 0x844D  # <CJK>
+0x5854 0x844F  # <CJK>
+0x5855 0x8451  # <CJK>
+0x5856 0x8452  # <CJK>
+0x5857 0x8456  # <CJK>
+0x5858 0x8458  # <CJK>
+0x5859 0x8459  # <CJK>
+0x585A 0x845A  # <CJK>
+0x585B 0x845C  # <CJK>
+0x585C 0x8460  # <CJK>
+0x585D 0x8464  # <CJK>
+0x585E 0x8465  # <CJK>
+0x585F 0x8467  # <CJK>
+0x5860 0x846A  # <CJK>
+0x5861 0x8470  # <CJK>
+0x5862 0x8473  # <CJK>
+0x5863 0x8474  # <CJK>
+0x5864 0x8476  # <CJK>
+0x5865 0x8478  # <CJK>
+0x5866 0x847C  # <CJK>
+0x5867 0x847D  # <CJK>
+0x5868 0x8481  # <CJK>
+0x5869 0x8485  # <CJK>
+0x586A 0x8492  # <CJK>
+0x586B 0x8493  # <CJK>
+0x586C 0x8495  # <CJK>
+0x586D 0x849E  # <CJK>
+0x586E 0x84A6  # <CJK>
+0x586F 0x84A8  # <CJK>
+0x5870 0x84A9  # <CJK>
+0x5871 0x84AA  # <CJK>
+0x5872 0x84AF  # <CJK>
+0x5873 0x84B1  # <CJK>
+0x5874 0x84B4  # <CJK>
+0x5875 0x84BA  # <CJK>
+0x5876 0x84BD  # <CJK>
+0x5877 0x84BE  # <CJK>
+0x5878 0x84C0  # <CJK>
+0x5879 0x84C2  # <CJK>
+0x587A 0x84C7  # <CJK>
+0x587B 0x84C8  # <CJK>
+0x587C 0x84CC  # <CJK>
+0x587D 0x84CF  # <CJK>
+0x587E 0x84D3  # <CJK>
+0x5921 0x84DC  # <CJK>
+0x5922 0x84E7  # <CJK>
+0x5923 0x84EA  # <CJK>
+0x5924 0x84EF  # <CJK>
+0x5925 0x84F0  # <CJK>
+0x5926 0x84F1  # <CJK>
+0x5927 0x84F2  # <CJK>
+0x5928 0x84F7  # <CJK>
+0x5929 0x8532  # <CJK>
+0x592A 0x84FA  # <CJK>
+0x592B 0x84FB  # <CJK>
+0x592C 0x84FD  # <CJK>
+0x592D 0x8502  # <CJK>
+0x592E 0x8503  # <CJK>
+0x592F 0x8507  # <CJK>
+0x5930 0x850C  # <CJK>
+0x5931 0x850E  # <CJK>
+0x5932 0x8510  # <CJK>
+0x5933 0x851C  # <CJK>
+0x5934 0x851E  # <CJK>
+0x5935 0x8522  # <CJK>
+0x5936 0x8523  # <CJK>
+0x5937 0x8524  # <CJK>
+0x5938 0x8525  # <CJK>
+0x5939 0x8527  # <CJK>
+0x593A 0x852A  # <CJK>
+0x593B 0x852B  # <CJK>
+0x593C 0x852F  # <CJK>
+0x593D 0x8533  # <CJK>
+0x593E 0x8534  # <CJK>
+0x593F 0x8536  # <CJK>
+0x5940 0x853F  # <CJK>
+0x5941 0x8546  # <CJK>
+0x5942 0x854F  # <CJK>
+0x5943 0x8550  # <CJK>
+0x5944 0x8551  # <CJK>
+0x5945 0x8552  # <CJK>
+0x5946 0x8553  # <CJK>
+0x5947 0x8556  # <CJK>
+0x5948 0x8559  # <CJK>
+0x5949 0x855C  # <CJK>
+0x594A 0x855D  # <CJK>
+0x594B 0x855E  # <CJK>
+0x594C 0x855F  # <CJK>
+0x594D 0x8560  # <CJK>
+0x594E 0x8561  # <CJK>
+0x594F 0x8562  # <CJK>
+0x5950 0x8564  # <CJK>
+0x5951 0x856B  # <CJK>
+0x5952 0x856F  # <CJK>
+0x5953 0x8579  # <CJK>
+0x5954 0x857A  # <CJK>
+0x5955 0x857B  # <CJK>
+0x5956 0x857D  # <CJK>
+0x5957 0x857F  # <CJK>
+0x5958 0x8581  # <CJK>
+0x5959 0x8585  # <CJK>
+0x595A 0x8586  # <CJK>
+0x595B 0x8589  # <CJK>
+0x595C 0x858B  # <CJK>
+0x595D 0x858C  # <CJK>
+0x595E 0x858F  # <CJK>
+0x595F 0x8593  # <CJK>
+0x5960 0x8598  # <CJK>
+0x5961 0x859D  # <CJK>
+0x5962 0x859F  # <CJK>
+0x5963 0x85A0  # <CJK>
+0x5964 0x85A2  # <CJK>
+0x5965 0x85A5  # <CJK>
+0x5966 0x85A7  # <CJK>
+0x5967 0x85B4  # <CJK>
+0x5968 0x85B6  # <CJK>
+0x5969 0x85B7  # <CJK>
+0x596A 0x85B8  # <CJK>
+0x596B 0x85BC  # <CJK>
+0x596C 0x85BD  # <CJK>
+0x596D 0x85BE  # <CJK>
+0x596E 0x85BF  # <CJK>
+0x596F 0x85C2  # <CJK>
+0x5970 0x85C7  # <CJK>
+0x5971 0x85CA  # <CJK>
+0x5972 0x85CB  # <CJK>
+0x5973 0x85CE  # <CJK>
+0x5974 0x85AD  # <CJK>
+0x5975 0x85D8  # <CJK>
+0x5976 0x85DA  # <CJK>
+0x5977 0x85DF  # <CJK>
+0x5978 0x85E0  # <CJK>
+0x5979 0x85E6  # <CJK>
+0x597A 0x85E8  # <CJK>
+0x597B 0x85ED  # <CJK>
+0x597C 0x85F3  # <CJK>
+0x597D 0x85F6  # <CJK>
+0x597E 0x85FC  # <CJK>
+0x5A21 0x85FF  # <CJK>
+0x5A22 0x8600  # <CJK>
+0x5A23 0x8604  # <CJK>
+0x5A24 0x8605  # <CJK>
+0x5A25 0x860D  # <CJK>
+0x5A26 0x860E  # <CJK>
+0x5A27 0x8610  # <CJK>
+0x5A28 0x8611  # <CJK>
+0x5A29 0x8612  # <CJK>
+0x5A2A 0x8618  # <CJK>
+0x5A2B 0x8619  # <CJK>
+0x5A2C 0x861B  # <CJK>
+0x5A2D 0x861E  # <CJK>
+0x5A2E 0x8621  # <CJK>
+0x5A2F 0x8627  # <CJK>
+0x5A30 0x8629  # <CJK>
+0x5A31 0x8636  # <CJK>
+0x5A32 0x8638  # <CJK>
+0x5A33 0x863A  # <CJK>
+0x5A34 0x863C  # <CJK>
+0x5A35 0x863D  # <CJK>
+0x5A36 0x8640  # <CJK>
+0x5A37 0x8642  # <CJK>
+0x5A38 0x8646  # <CJK>
+0x5A39 0x8652  # <CJK>
+0x5A3A 0x8653  # <CJK>
+0x5A3B 0x8656  # <CJK>
+0x5A3C 0x8657  # <CJK>
+0x5A3D 0x8658  # <CJK>
+0x5A3E 0x8659  # <CJK>
+0x5A3F 0x865D  # <CJK>
+0x5A40 0x8660  # <CJK>
+0x5A41 0x8661  # <CJK>
+0x5A42 0x8662  # <CJK>
+0x5A43 0x8663  # <CJK>
+0x5A44 0x8664  # <CJK>
+0x5A45 0x8669  # <CJK>
+0x5A46 0x866C  # <CJK>
+0x5A47 0x866F  # <CJK>
+0x5A48 0x8675  # <CJK>
+0x5A49 0x8676  # <CJK>
+0x5A4A 0x8677  # <CJK>
+0x5A4B 0x867A  # <CJK>
+0x5A4C 0x868D  # <CJK>
+0x5A4D 0x8691  # <CJK>
+0x5A4E 0x8696  # <CJK>
+0x5A4F 0x8698  # <CJK>
+0x5A50 0x869A  # <CJK>
+0x5A51 0x869C  # <CJK>
+0x5A52 0x86A1  # <CJK>
+0x5A53 0x86A6  # <CJK>
+0x5A54 0x86A7  # <CJK>
+0x5A55 0x86A8  # <CJK>
+0x5A56 0x86AD  # <CJK>
+0x5A57 0x86B1  # <CJK>
+0x5A58 0x86B3  # <CJK>
+0x5A59 0x86B4  # <CJK>
+0x5A5A 0x86B5  # <CJK>
+0x5A5B 0x86B7  # <CJK>
+0x5A5C 0x86B8  # <CJK>
+0x5A5D 0x86B9  # <CJK>
+0x5A5E 0x86BF  # <CJK>
+0x5A5F 0x86C0  # <CJK>
+0x5A60 0x86C1  # <CJK>
+0x5A61 0x86C3  # <CJK>
+0x5A62 0x86C5  # <CJK>
+0x5A63 0x86D1  # <CJK>
+0x5A64 0x86D2  # <CJK>
+0x5A65 0x86D5  # <CJK>
+0x5A66 0x86D7  # <CJK>
+0x5A67 0x86DA  # <CJK>
+0x5A68 0x86DC  # <CJK>
+0x5A69 0x86E0  # <CJK>
+0x5A6A 0x86E3  # <CJK>
+0x5A6B 0x86E5  # <CJK>
+0x5A6C 0x86E7  # <CJK>
+0x5A6D 0x8688  # <CJK>
+0x5A6E 0x86FA  # <CJK>
+0x5A6F 0x86FC  # <CJK>
+0x5A70 0x86FD  # <CJK>
+0x5A71 0x8704  # <CJK>
+0x5A72 0x8705  # <CJK>
+0x5A73 0x8707  # <CJK>
+0x5A74 0x870B  # <CJK>
+0x5A75 0x870E  # <CJK>
+0x5A76 0x870F  # <CJK>
+0x5A77 0x8710  # <CJK>
+0x5A78 0x8713  # <CJK>
+0x5A79 0x8714  # <CJK>
+0x5A7A 0x8719  # <CJK>
+0x5A7B 0x871E  # <CJK>
+0x5A7C 0x871F  # <CJK>
+0x5A7D 0x8721  # <CJK>
+0x5A7E 0x8723  # <CJK>
+0x5B21 0x8728  # <CJK>
+0x5B22 0x872E  # <CJK>
+0x5B23 0x872F  # <CJK>
+0x5B24 0x8731  # <CJK>
+0x5B25 0x8732  # <CJK>
+0x5B26 0x8739  # <CJK>
+0x5B27 0x873A  # <CJK>
+0x5B28 0x873C  # <CJK>
+0x5B29 0x873D  # <CJK>
+0x5B2A 0x873E  # <CJK>
+0x5B2B 0x8740  # <CJK>
+0x5B2C 0x8743  # <CJK>
+0x5B2D 0x8745  # <CJK>
+0x5B2E 0x874D  # <CJK>
+0x5B2F 0x8758  # <CJK>
+0x5B30 0x875D  # <CJK>
+0x5B31 0x8761  # <CJK>
+0x5B32 0x8764  # <CJK>
+0x5B33 0x8765  # <CJK>
+0x5B34 0x876F  # <CJK>
+0x5B35 0x8771  # <CJK>
+0x5B36 0x8772  # <CJK>
+0x5B37 0x877B  # <CJK>
+0x5B38 0x8783  # <CJK>
+0x5B39 0x8784  # <CJK>
+0x5B3A 0x8785  # <CJK>
+0x5B3B 0x8786  # <CJK>
+0x5B3C 0x8787  # <CJK>
+0x5B3D 0x8788  # <CJK>
+0x5B3E 0x8789  # <CJK>
+0x5B3F 0x878B  # <CJK>
+0x5B40 0x878C  # <CJK>
+0x5B41 0x8790  # <CJK>
+0x5B42 0x8793  # <CJK>
+0x5B43 0x8795  # <CJK>
+0x5B44 0x8797  # <CJK>
+0x5B45 0x8798  # <CJK>
+0x5B46 0x8799  # <CJK>
+0x5B47 0x879E  # <CJK>
+0x5B48 0x87A0  # <CJK>
+0x5B49 0x87A3  # <CJK>
+0x5B4A 0x87A7  # <CJK>
+0x5B4B 0x87AC  # <CJK>
+0x5B4C 0x87AD  # <CJK>
+0x5B4D 0x87AE  # <CJK>
+0x5B4E 0x87B1  # <CJK>
+0x5B4F 0x87B5  # <CJK>
+0x5B50 0x87BE  # <CJK>
+0x5B51 0x87BF  # <CJK>
+0x5B52 0x87C1  # <CJK>
+0x5B53 0x87C8  # <CJK>
+0x5B54 0x87C9  # <CJK>
+0x5B55 0x87CA  # <CJK>
+0x5B56 0x87CE  # <CJK>
+0x5B57 0x87D5  # <CJK>
+0x5B58 0x87D6  # <CJK>
+0x5B59 0x87D9  # <CJK>
+0x5B5A 0x87DA  # <CJK>
+0x5B5B 0x87DC  # <CJK>
+0x5B5C 0x87DF  # <CJK>
+0x5B5D 0x87E2  # <CJK>
+0x5B5E 0x87E3  # <CJK>
+0x5B5F 0x87E4  # <CJK>
+0x5B60 0x87EA  # <CJK>
+0x5B61 0x87EB  # <CJK>
+0x5B62 0x87ED  # <CJK>
+0x5B63 0x87F1  # <CJK>
+0x5B64 0x87F3  # <CJK>
+0x5B65 0x87F8  # <CJK>
+0x5B66 0x87FA  # <CJK>
+0x5B67 0x87FF  # <CJK>
+0x5B68 0x8801  # <CJK>
+0x5B69 0x8803  # <CJK>
+0x5B6A 0x8806  # <CJK>
+0x5B6B 0x8809  # <CJK>
+0x5B6C 0x880A  # <CJK>
+0x5B6D 0x880B  # <CJK>
+0x5B6E 0x8810  # <CJK>
+0x5B6F 0x8819  # <CJK>
+0x5B70 0x8812  # <CJK>
+0x5B71 0x8813  # <CJK>
+0x5B72 0x8814  # <CJK>
+0x5B73 0x8818  # <CJK>
+0x5B74 0x881A  # <CJK>
+0x5B75 0x881B  # <CJK>
+0x5B76 0x881C  # <CJK>
+0x5B77 0x881E  # <CJK>
+0x5B78 0x881F  # <CJK>
+0x5B79 0x8828  # <CJK>
+0x5B7A 0x882D  # <CJK>
+0x5B7B 0x882E  # <CJK>
+0x5B7C 0x8830  # <CJK>
+0x5B7D 0x8832  # <CJK>
+0x5B7E 0x8835  # <CJK>
+0x5C21 0x883A  # <CJK>
+0x5C22 0x883C  # <CJK>
+0x5C23 0x8841  # <CJK>
+0x5C24 0x8843  # <CJK>
+0x5C25 0x8845  # <CJK>
+0x5C26 0x8848  # <CJK>
+0x5C27 0x8849  # <CJK>
+0x5C28 0x884A  # <CJK>
+0x5C29 0x884B  # <CJK>
+0x5C2A 0x884E  # <CJK>
+0x5C2B 0x8851  # <CJK>
+0x5C2C 0x8855  # <CJK>
+0x5C2D 0x8856  # <CJK>
+0x5C2E 0x8858  # <CJK>
+0x5C2F 0x885A  # <CJK>
+0x5C30 0x885C  # <CJK>
+0x5C31 0x885F  # <CJK>
+0x5C32 0x8860  # <CJK>
+0x5C33 0x8864  # <CJK>
+0x5C34 0x8869  # <CJK>
+0x5C35 0x8871  # <CJK>
+0x5C36 0x8879  # <CJK>
+0x5C37 0x887B  # <CJK>
+0x5C38 0x8880  # <CJK>
+0x5C39 0x8898  # <CJK>
+0x5C3A 0x889A  # <CJK>
+0x5C3B 0x889B  # <CJK>
+0x5C3C 0x889C  # <CJK>
+0x5C3D 0x889F  # <CJK>
+0x5C3E 0x88A0  # <CJK>
+0x5C3F 0x88A8  # <CJK>
+0x5C40 0x88AA  # <CJK>
+0x5C41 0x88BA  # <CJK>
+0x5C42 0x88BD  # <CJK>
+0x5C43 0x88BE  # <CJK>
+0x5C44 0x88C0  # <CJK>
+0x5C45 0x88CA  # <CJK>
+0x5C46 0x88CB  # <CJK>
+0x5C47 0x88CC  # <CJK>
+0x5C48 0x88CD  # <CJK>
+0x5C49 0x88CE  # <CJK>
+0x5C4A 0x88D1  # <CJK>
+0x5C4B 0x88D2  # <CJK>
+0x5C4C 0x88D3  # <CJK>
+0x5C4D 0x88DB  # <CJK>
+0x5C4E 0x88DE  # <CJK>
+0x5C4F 0x88E7  # <CJK>
+0x5C50 0x88EF  # <CJK>
+0x5C51 0x88F0  # <CJK>
+0x5C52 0x88F1  # <CJK>
+0x5C53 0x88F5  # <CJK>
+0x5C54 0x88F7  # <CJK>
+0x5C55 0x8901  # <CJK>
+0x5C56 0x8906  # <CJK>
+0x5C57 0x890D  # <CJK>
+0x5C58 0x890E  # <CJK>
+0x5C59 0x890F  # <CJK>
+0x5C5A 0x8915  # <CJK>
+0x5C5B 0x8916  # <CJK>
+0x5C5C 0x8918  # <CJK>
+0x5C5D 0x8919  # <CJK>
+0x5C5E 0x891A  # <CJK>
+0x5C5F 0x891C  # <CJK>
+0x5C60 0x8920  # <CJK>
+0x5C61 0x8926  # <CJK>
+0x5C62 0x8927  # <CJK>
+0x5C63 0x8928  # <CJK>
+0x5C64 0x8930  # <CJK>
+0x5C65 0x8931  # <CJK>
+0x5C66 0x8932  # <CJK>
+0x5C67 0x8935  # <CJK>
+0x5C68 0x8939  # <CJK>
+0x5C69 0x893A  # <CJK>
+0x5C6A 0x893E  # <CJK>
+0x5C6B 0x8940  # <CJK>
+0x5C6C 0x8942  # <CJK>
+0x5C6D 0x8945  # <CJK>
+0x5C6E 0x8946  # <CJK>
+0x5C6F 0x8949  # <CJK>
+0x5C70 0x894F  # <CJK>
+0x5C71 0x8952  # <CJK>
+0x5C72 0x8957  # <CJK>
+0x5C73 0x895A  # <CJK>
+0x5C74 0x895B  # <CJK>
+0x5C75 0x895C  # <CJK>
+0x5C76 0x8961  # <CJK>
+0x5C77 0x8962  # <CJK>
+0x5C78 0x8963  # <CJK>
+0x5C79 0x896B  # <CJK>
+0x5C7A 0x896E  # <CJK>
+0x5C7B 0x8970  # <CJK>
+0x5C7C 0x8973  # <CJK>
+0x5C7D 0x8975  # <CJK>
+0x5C7E 0x897A  # <CJK>
+0x5D21 0x897B  # <CJK>
+0x5D22 0x897C  # <CJK>
+0x5D23 0x897D  # <CJK>
+0x5D24 0x8989  # <CJK>
+0x5D25 0x898D  # <CJK>
+0x5D26 0x8990  # <CJK>
+0x5D27 0x8994  # <CJK>
+0x5D28 0x8995  # <CJK>
+0x5D29 0x899B  # <CJK>
+0x5D2A 0x899C  # <CJK>
+0x5D2B 0x899F  # <CJK>
+0x5D2C 0x89A0  # <CJK>
+0x5D2D 0x89A5  # <CJK>
+0x5D2E 0x89B0  # <CJK>
+0x5D2F 0x89B4  # <CJK>
+0x5D30 0x89B5  # <CJK>
+0x5D31 0x89B6  # <CJK>
+0x5D32 0x89B7  # <CJK>
+0x5D33 0x89BC  # <CJK>
+0x5D34 0x89D4  # <CJK>
+0x5D35 0x89D5  # <CJK>
+0x5D36 0x89D6  # <CJK>
+0x5D37 0x89D7  # <CJK>
+0x5D38 0x89D8  # <CJK>
+0x5D39 0x89E5  # <CJK>
+0x5D3A 0x89E9  # <CJK>
+0x5D3B 0x89EB  # <CJK>
+0x5D3C 0x89ED  # <CJK>
+0x5D3D 0x89F1  # <CJK>
+0x5D3E 0x89F3  # <CJK>
+0x5D3F 0x89F6  # <CJK>
+0x5D40 0x89F9  # <CJK>
+0x5D41 0x89FD  # <CJK>
+0x5D42 0x89FF  # <CJK>
+0x5D43 0x8A04  # <CJK>
+0x5D44 0x8A05  # <CJK>
+0x5D45 0x8A07  # <CJK>
+0x5D46 0x8A0F  # <CJK>
+0x5D47 0x8A11  # <CJK>
+0x5D48 0x8A12  # <CJK>
+0x5D49 0x8A14  # <CJK>
+0x5D4A 0x8A15  # <CJK>
+0x5D4B 0x8A1E  # <CJK>
+0x5D4C 0x8A20  # <CJK>
+0x5D4D 0x8A22  # <CJK>
+0x5D4E 0x8A24  # <CJK>
+0x5D4F 0x8A26  # <CJK>
+0x5D50 0x8A2B  # <CJK>
+0x5D51 0x8A2C  # <CJK>
+0x5D52 0x8A2F  # <CJK>
+0x5D53 0x8A35  # <CJK>
+0x5D54 0x8A37  # <CJK>
+0x5D55 0x8A3D  # <CJK>
+0x5D56 0x8A3E  # <CJK>
+0x5D57 0x8A40  # <CJK>
+0x5D58 0x8A43  # <CJK>
+0x5D59 0x8A45  # <CJK>
+0x5D5A 0x8A47  # <CJK>
+0x5D5B 0x8A49  # <CJK>
+0x5D5C 0x8A4D  # <CJK>
+0x5D5D 0x8A4E  # <CJK>
+0x5D5E 0x8A53  # <CJK>
+0x5D5F 0x8A56  # <CJK>
+0x5D60 0x8A57  # <CJK>
+0x5D61 0x8A58  # <CJK>
+0x5D62 0x8A5C  # <CJK>
+0x5D63 0x8A5D  # <CJK>
+0x5D64 0x8A61  # <CJK>
+0x5D65 0x8A65  # <CJK>
+0x5D66 0x8A67  # <CJK>
+0x5D67 0x8A75  # <CJK>
+0x5D68 0x8A76  # <CJK>
+0x5D69 0x8A77  # <CJK>
+0x5D6A 0x8A79  # <CJK>
+0x5D6B 0x8A7A  # <CJK>
+0x5D6C 0x8A7B  # <CJK>
+0x5D6D 0x8A7E  # <CJK>
+0x5D6E 0x8A7F  # <CJK>
+0x5D6F 0x8A80  # <CJK>
+0x5D70 0x8A83  # <CJK>
+0x5D71 0x8A86  # <CJK>
+0x5D72 0x8A8B  # <CJK>
+0x5D73 0x8A8F  # <CJK>
+0x5D74 0x8A90  # <CJK>
+0x5D75 0x8A92  # <CJK>
+0x5D76 0x8A96  # <CJK>
+0x5D77 0x8A97  # <CJK>
+0x5D78 0x8A99  # <CJK>
+0x5D79 0x8A9F  # <CJK>
+0x5D7A 0x8AA7  # <CJK>
+0x5D7B 0x8AA9  # <CJK>
+0x5D7C 0x8AAE  # <CJK>
+0x5D7D 0x8AAF  # <CJK>
+0x5D7E 0x8AB3  # <CJK>
+0x5E21 0x8AB6  # <CJK>
+0x5E22 0x8AB7  # <CJK>
+0x5E23 0x8ABB  # <CJK>
+0x5E24 0x8ABE  # <CJK>
+0x5E25 0x8AC3  # <CJK>
+0x5E26 0x8AC6  # <CJK>
+0x5E27 0x8AC8  # <CJK>
+0x5E28 0x8AC9  # <CJK>
+0x5E29 0x8ACA  # <CJK>
+0x5E2A 0x8AD1  # <CJK>
+0x5E2B 0x8AD3  # <CJK>
+0x5E2C 0x8AD4  # <CJK>
+0x5E2D 0x8AD5  # <CJK>
+0x5E2E 0x8AD7  # <CJK>
+0x5E2F 0x8ADD  # <CJK>
+0x5E30 0x8ADF  # <CJK>
+0x5E31 0x8AEC  # <CJK>
+0x5E32 0x8AF0  # <CJK>
+0x5E33 0x8AF4  # <CJK>
+0x5E34 0x8AF5  # <CJK>
+0x5E35 0x8AF6  # <CJK>
+0x5E36 0x8AFC  # <CJK>
+0x5E37 0x8AFF  # <CJK>
+0x5E38 0x8B05  # <CJK>
+0x5E39 0x8B06  # <CJK>
+0x5E3A 0x8B0B  # <CJK>
+0x5E3B 0x8B11  # <CJK>
+0x5E3C 0x8B1C  # <CJK>
+0x5E3D 0x8B1E  # <CJK>
+0x5E3E 0x8B1F  # <CJK>
+0x5E3F 0x8B0A  # <CJK>
+0x5E40 0x8B2D  # <CJK>
+0x5E41 0x8B30  # <CJK>
+0x5E42 0x8B37  # <CJK>
+0x5E43 0x8B3C  # <CJK>
+0x5E44 0x8B42  # <CJK>
+0x5E45 0x8B43  # <CJK>
+0x5E46 0x8B44  # <CJK>
+0x5E47 0x8B45  # <CJK>
+0x5E48 0x8B46  # <CJK>
+0x5E49 0x8B48  # <CJK>
+0x5E4A 0x8B52  # <CJK>
+0x5E4B 0x8B53  # <CJK>
+0x5E4C 0x8B54  # <CJK>
+0x5E4D 0x8B59  # <CJK>
+0x5E4E 0x8B4D  # <CJK>
+0x5E4F 0x8B5E  # <CJK>
+0x5E50 0x8B63  # <CJK>
+0x5E51 0x8B6D  # <CJK>
+0x5E52 0x8B76  # <CJK>
+0x5E53 0x8B78  # <CJK>
+0x5E54 0x8B79  # <CJK>
+0x5E55 0x8B7C  # <CJK>
+0x5E56 0x8B7E  # <CJK>
+0x5E57 0x8B81  # <CJK>
+0x5E58 0x8B84  # <CJK>
+0x5E59 0x8B85  # <CJK>
+0x5E5A 0x8B8B  # <CJK>
+0x5E5B 0x8B8D  # <CJK>
+0x5E5C 0x8B8F  # <CJK>
+0x5E5D 0x8B94  # <CJK>
+0x5E5E 0x8B95  # <CJK>
+0x5E5F 0x8B9C  # <CJK>
+0x5E60 0x8B9E  # <CJK>
+0x5E61 0x8B9F  # <CJK>
+0x5E62 0x8C38  # <CJK>
+0x5E63 0x8C39  # <CJK>
+0x5E64 0x8C3D  # <CJK>
+0x5E65 0x8C3E  # <CJK>
+0x5E66 0x8C45  # <CJK>
+0x5E67 0x8C47  # <CJK>
+0x5E68 0x8C49  # <CJK>
+0x5E69 0x8C4B  # <CJK>
+0x5E6A 0x8C4F  # <CJK>
+0x5E6B 0x8C51  # <CJK>
+0x5E6C 0x8C53  # <CJK>
+0x5E6D 0x8C54  # <CJK>
+0x5E6E 0x8C57  # <CJK>
+0x5E6F 0x8C58  # <CJK>
+0x5E70 0x8C5B  # <CJK>
+0x5E71 0x8C5D  # <CJK>
+0x5E72 0x8C59  # <CJK>
+0x5E73 0x8C63  # <CJK>
+0x5E74 0x8C64  # <CJK>
+0x5E75 0x8C66  # <CJK>
+0x5E76 0x8C68  # <CJK>
+0x5E77 0x8C69  # <CJK>
+0x5E78 0x8C6D  # <CJK>
+0x5E79 0x8C73  # <CJK>
+0x5E7A 0x8C75  # <CJK>
+0x5E7B 0x8C76  # <CJK>
+0x5E7C 0x8C7B  # <CJK>
+0x5E7D 0x8C7E  # <CJK>
+0x5E7E 0x8C86  # <CJK>
+0x5F21 0x8C87  # <CJK>
+0x5F22 0x8C8B  # <CJK>
+0x5F23 0x8C90  # <CJK>
+0x5F24 0x8C92  # <CJK>
+0x5F25 0x8C93  # <CJK>
+0x5F26 0x8C99  # <CJK>
+0x5F27 0x8C9B  # <CJK>
+0x5F28 0x8C9C  # <CJK>
+0x5F29 0x8CA4  # <CJK>
+0x5F2A 0x8CB9  # <CJK>
+0x5F2B 0x8CBA  # <CJK>
+0x5F2C 0x8CC5  # <CJK>
+0x5F2D 0x8CC6  # <CJK>
+0x5F2E 0x8CC9  # <CJK>
+0x5F2F 0x8CCB  # <CJK>
+0x5F30 0x8CCF  # <CJK>
+0x5F31 0x8CD6  # <CJK>
+0x5F32 0x8CD5  # <CJK>
+0x5F33 0x8CD9  # <CJK>
+0x5F34 0x8CDD  # <CJK>
+0x5F35 0x8CE1  # <CJK>
+0x5F36 0x8CE8  # <CJK>
+0x5F37 0x8CEC  # <CJK>
+0x5F38 0x8CEF  # <CJK>
+0x5F39 0x8CF0  # <CJK>
+0x5F3A 0x8CF2  # <CJK>
+0x5F3B 0x8CF5  # <CJK>
+0x5F3C 0x8CF7  # <CJK>
+0x5F3D 0x8CF8  # <CJK>
+0x5F3E 0x8CFE  # <CJK>
+0x5F3F 0x8CFF  # <CJK>
+0x5F40 0x8D01  # <CJK>
+0x5F41 0x8D03  # <CJK>
+0x5F42 0x8D09  # <CJK>
+0x5F43 0x8D12  # <CJK>
+0x5F44 0x8D17  # <CJK>
+0x5F45 0x8D1B  # <CJK>
+0x5F46 0x8D65  # <CJK>
+0x5F47 0x8D69  # <CJK>
+0x5F48 0x8D6C  # <CJK>
+0x5F49 0x8D6E  # <CJK>
+0x5F4A 0x8D7F  # <CJK>
+0x5F4B 0x8D82  # <CJK>
+0x5F4C 0x8D84  # <CJK>
+0x5F4D 0x8D88  # <CJK>
+0x5F4E 0x8D8D  # <CJK>
+0x5F4F 0x8D90  # <CJK>
+0x5F50 0x8D91  # <CJK>
+0x5F51 0x8D95  # <CJK>
+0x5F52 0x8D9E  # <CJK>
+0x5F53 0x8D9F  # <CJK>
+0x5F54 0x8DA0  # <CJK>
+0x5F55 0x8DA6  # <CJK>
+0x5F56 0x8DAB  # <CJK>
+0x5F57 0x8DAC  # <CJK>
+0x5F58 0x8DAF  # <CJK>
+0x5F59 0x8DB2  # <CJK>
+0x5F5A 0x8DB5  # <CJK>
+0x5F5B 0x8DB7  # <CJK>
+0x5F5C 0x8DB9  # <CJK>
+0x5F5D 0x8DBB  # <CJK>
+0x5F5E 0x8DC0  # <CJK>
+0x5F5F 0x8DC5  # <CJK>
+0x5F60 0x8DC6  # <CJK>
+0x5F61 0x8DC7  # <CJK>
+0x5F62 0x8DC8  # <CJK>
+0x5F63 0x8DCA  # <CJK>
+0x5F64 0x8DCE  # <CJK>
+0x5F65 0x8DD1  # <CJK>
+0x5F66 0x8DD4  # <CJK>
+0x5F67 0x8DD5  # <CJK>
+0x5F68 0x8DD7  # <CJK>
+0x5F69 0x8DD9  # <CJK>
+0x5F6A 0x8DE4  # <CJK>
+0x5F6B 0x8DE5  # <CJK>
+0x5F6C 0x8DE7  # <CJK>
+0x5F6D 0x8DEC  # <CJK>
+0x5F6E 0x8DF0  # <CJK>
+0x5F6F 0x8DBC  # <CJK>
+0x5F70 0x8DF1  # <CJK>
+0x5F71 0x8DF2  # <CJK>
+0x5F72 0x8DF4  # <CJK>
+0x5F73 0x8DFD  # <CJK>
+0x5F74 0x8E01  # <CJK>
+0x5F75 0x8E04  # <CJK>
+0x5F76 0x8E05  # <CJK>
+0x5F77 0x8E06  # <CJK>
+0x5F78 0x8E0B  # <CJK>
+0x5F79 0x8E11  # <CJK>
+0x5F7A 0x8E14  # <CJK>
+0x5F7B 0x8E16  # <CJK>
+0x5F7C 0x8E20  # <CJK>
+0x5F7D 0x8E21  # <CJK>
+0x5F7E 0x8E22  # <CJK>
+0x6021 0x8E23  # <CJK>
+0x6022 0x8E26  # <CJK>
+0x6023 0x8E27  # <CJK>
+0x6024 0x8E31  # <CJK>
+0x6025 0x8E33  # <CJK>
+0x6026 0x8E36  # <CJK>
+0x6027 0x8E37  # <CJK>
+0x6028 0x8E38  # <CJK>
+0x6029 0x8E39  # <CJK>
+0x602A 0x8E3D  # <CJK>
+0x602B 0x8E40  # <CJK>
+0x602C 0x8E41  # <CJK>
+0x602D 0x8E4B  # <CJK>
+0x602E 0x8E4D  # <CJK>
+0x602F 0x8E4E  # <CJK>
+0x6030 0x8E4F  # <CJK>
+0x6031 0x8E54  # <CJK>
+0x6032 0x8E5B  # <CJK>
+0x6033 0x8E5C  # <CJK>
+0x6034 0x8E5D  # <CJK>
+0x6035 0x8E5E  # <CJK>
+0x6036 0x8E61  # <CJK>
+0x6037 0x8E62  # <CJK>
+0x6038 0x8E69  # <CJK>
+0x6039 0x8E6C  # <CJK>
+0x603A 0x8E6D  # <CJK>
+0x603B 0x8E6F  # <CJK>
+0x603C 0x8E70  # <CJK>
+0x603D 0x8E71  # <CJK>
+0x603E 0x8E79  # <CJK>
+0x603F 0x8E7A  # <CJK>
+0x6040 0x8E7B  # <CJK>
+0x6041 0x8E82  # <CJK>
+0x6042 0x8E83  # <CJK>
+0x6043 0x8E89  # <CJK>
+0x6044 0x8E90  # <CJK>
+0x6045 0x8E92  # <CJK>
+0x6046 0x8E95  # <CJK>
+0x6047 0x8E9A  # <CJK>
+0x6048 0x8E9B  # <CJK>
+0x6049 0x8E9D  # <CJK>
+0x604A 0x8E9E  # <CJK>
+0x604B 0x8EA2  # <CJK>
+0x604C 0x8EA7  # <CJK>
+0x604D 0x8EA9  # <CJK>
+0x604E 0x8EAD  # <CJK>
+0x604F 0x8EAE  # <CJK>
+0x6050 0x8EB3  # <CJK>
+0x6051 0x8EB5  # <CJK>
+0x6052 0x8EBA  # <CJK>
+0x6053 0x8EBB  # <CJK>
+0x6054 0x8EC0  # <CJK>
+0x6055 0x8EC1  # <CJK>
+0x6056 0x8EC3  # <CJK>
+0x6057 0x8EC4  # <CJK>
+0x6058 0x8EC7  # <CJK>
+0x6059 0x8ECF  # <CJK>
+0x605A 0x8ED1  # <CJK>
+0x605B 0x8ED4  # <CJK>
+0x605C 0x8EDC  # <CJK>
+0x605D 0x8EE8  # <CJK>
+0x605E 0x8EEE  # <CJK>
+0x605F 0x8EF0  # <CJK>
+0x6060 0x8EF1  # <CJK>
+0x6061 0x8EF7  # <CJK>
+0x6062 0x8EF9  # <CJK>
+0x6063 0x8EFA  # <CJK>
+0x6064 0x8EED  # <CJK>
+0x6065 0x8F00  # <CJK>
+0x6066 0x8F02  # <CJK>
+0x6067 0x8F07  # <CJK>
+0x6068 0x8F08  # <CJK>
+0x6069 0x8F0F  # <CJK>
+0x606A 0x8F10  # <CJK>
+0x606B 0x8F16  # <CJK>
+0x606C 0x8F17  # <CJK>
+0x606D 0x8F18  # <CJK>
+0x606E 0x8F1E  # <CJK>
+0x606F 0x8F20  # <CJK>
+0x6070 0x8F21  # <CJK>
+0x6071 0x8F23  # <CJK>
+0x6072 0x8F25  # <CJK>
+0x6073 0x8F27  # <CJK>
+0x6074 0x8F28  # <CJK>
+0x6075 0x8F2C  # <CJK>
+0x6076 0x8F2D  # <CJK>
+0x6077 0x8F2E  # <CJK>
+0x6078 0x8F34  # <CJK>
+0x6079 0x8F35  # <CJK>
+0x607A 0x8F36  # <CJK>
+0x607B 0x8F37  # <CJK>
+0x607C 0x8F3A  # <CJK>
+0x607D 0x8F40  # <CJK>
+0x607E 0x8F41  # <CJK>
+0x6121 0x8F43  # <CJK>
+0x6122 0x8F47  # <CJK>
+0x6123 0x8F4F  # <CJK>
+0x6124 0x8F51  # <CJK>
+0x6125 0x8F52  # <CJK>
+0x6126 0x8F53  # <CJK>
+0x6127 0x8F54  # <CJK>
+0x6128 0x8F55  # <CJK>
+0x6129 0x8F58  # <CJK>
+0x612A 0x8F5D  # <CJK>
+0x612B 0x8F5E  # <CJK>
+0x612C 0x8F65  # <CJK>
+0x612D 0x8F9D  # <CJK>
+0x612E 0x8FA0  # <CJK>
+0x612F 0x8FA1  # <CJK>
+0x6130 0x8FA4  # <CJK>
+0x6131 0x8FA5  # <CJK>
+0x6132 0x8FA6  # <CJK>
+0x6133 0x8FB5  # <CJK>
+0x6134 0x8FB6  # <CJK>
+0x6135 0x8FB8  # <CJK>
+0x6136 0x8FBE  # <CJK>
+0x6137 0x8FC0  # <CJK>
+0x6138 0x8FC1  # <CJK>
+0x6139 0x8FC6  # <CJK>
+0x613A 0x8FCA  # <CJK>
+0x613B 0x8FCB  # <CJK>
+0x613C 0x8FCD  # <CJK>
+0x613D 0x8FD0  # <CJK>
+0x613E 0x8FD2  # <CJK>
+0x613F 0x8FD3  # <CJK>
+0x6140 0x8FD5  # <CJK>
+0x6141 0x8FE0  # <CJK>
+0x6142 0x8FE3  # <CJK>
+0x6143 0x8FE4  # <CJK>
+0x6144 0x8FE8  # <CJK>
+0x6145 0x8FEE  # <CJK>
+0x6146 0x8FF1  # <CJK>
+0x6147 0x8FF5  # <CJK>
+0x6148 0x8FF6  # <CJK>
+0x6149 0x8FFB  # <CJK>
+0x614A 0x8FFE  # <CJK>
+0x614B 0x9002  # <CJK>
+0x614C 0x9004  # <CJK>
+0x614D 0x9008  # <CJK>
+0x614E 0x900C  # <CJK>
+0x614F 0x9018  # <CJK>
+0x6150 0x901B  # <CJK>
+0x6151 0x9028  # <CJK>
+0x6152 0x9029  # <CJK>
+0x6153 0x902F  # <CJK>
+0x6154 0x902A  # <CJK>
+0x6155 0x902C  # <CJK>
+0x6156 0x902D  # <CJK>
+0x6157 0x9033  # <CJK>
+0x6158 0x9034  # <CJK>
+0x6159 0x9037  # <CJK>
+0x615A 0x903F  # <CJK>
+0x615B 0x9043  # <CJK>
+0x615C 0x9044  # <CJK>
+0x615D 0x904C  # <CJK>
+0x615E 0x905B  # <CJK>
+0x615F 0x905D  # <CJK>
+0x6160 0x9062  # <CJK>
+0x6161 0x9066  # <CJK>
+0x6162 0x9067  # <CJK>
+0x6163 0x906C  # <CJK>
+0x6164 0x9070  # <CJK>
+0x6165 0x9074  # <CJK>
+0x6166 0x9079  # <CJK>
+0x6167 0x9085  # <CJK>
+0x6168 0x9088  # <CJK>
+0x6169 0x908B  # <CJK>
+0x616A 0x908C  # <CJK>
+0x616B 0x908E  # <CJK>
+0x616C 0x9090  # <CJK>
+0x616D 0x9095  # <CJK>
+0x616E 0x9097  # <CJK>
+0x616F 0x9098  # <CJK>
+0x6170 0x9099  # <CJK>
+0x6171 0x909B  # <CJK>
+0x6172 0x90A0  # <CJK>
+0x6173 0x90A1  # <CJK>
+0x6174 0x90A2  # <CJK>
+0x6175 0x90A5  # <CJK>
+0x6176 0x90B0  # <CJK>
+0x6177 0x90B2  # <CJK>
+0x6178 0x90B3  # <CJK>
+0x6179 0x90B4  # <CJK>
+0x617A 0x90B6  # <CJK>
+0x617B 0x90BD  # <CJK>
+0x617C 0x90CC  # <CJK>
+0x617D 0x90BE  # <CJK>
+0x617E 0x90C3  # <CJK>
+0x6221 0x90C4  # <CJK>
+0x6222 0x90C5  # <CJK>
+0x6223 0x90C7  # <CJK>
+0x6224 0x90C8  # <CJK>
+0x6225 0x90D5  # <CJK>
+0x6226 0x90D7  # <CJK>
+0x6227 0x90D8  # <CJK>
+0x6228 0x90D9  # <CJK>
+0x6229 0x90DC  # <CJK>
+0x622A 0x90DD  # <CJK>
+0x622B 0x90DF  # <CJK>
+0x622C 0x90E5  # <CJK>
+0x622D 0x90D2  # <CJK>
+0x622E 0x90F6  # <CJK>
+0x622F 0x90EB  # <CJK>
+0x6230 0x90EF  # <CJK>
+0x6231 0x90F0  # <CJK>
+0x6232 0x90F4  # <CJK>
+0x6233 0x90FE  # <CJK>
+0x6234 0x90FF  # <CJK>
+0x6235 0x9100  # <CJK>
+0x6236 0x9104  # <CJK>
+0x6237 0x9105  # <CJK>
+0x6238 0x9106  # <CJK>
+0x6239 0x9108  # <CJK>
+0x623A 0x910D  # <CJK>
+0x623B 0x9110  # <CJK>
+0x623C 0x9114  # <CJK>
+0x623D 0x9116  # <CJK>
+0x623E 0x9117  # <CJK>
+0x623F 0x9118  # <CJK>
+0x6240 0x911A  # <CJK>
+0x6241 0x911C  # <CJK>
+0x6242 0x911E  # <CJK>
+0x6243 0x9120  # <CJK>
+0x6244 0x9125  # <CJK>
+0x6245 0x9122  # <CJK>
+0x6246 0x9123  # <CJK>
+0x6247 0x9127  # <CJK>
+0x6248 0x9129  # <CJK>
+0x6249 0x912E  # <CJK>
+0x624A 0x912F  # <CJK>
+0x624B 0x9131  # <CJK>
+0x624C 0x9134  # <CJK>
+0x624D 0x9136  # <CJK>
+0x624E 0x9137  # <CJK>
+0x624F 0x9139  # <CJK>
+0x6250 0x913A  # <CJK>
+0x6251 0x913C  # <CJK>
+0x6252 0x913D  # <CJK>
+0x6253 0x9143  # <CJK>
+0x6254 0x9147  # <CJK>
+0x6255 0x9148  # <CJK>
+0x6256 0x914F  # <CJK>
+0x6257 0x9153  # <CJK>
+0x6258 0x9157  # <CJK>
+0x6259 0x9159  # <CJK>
+0x625A 0x915A  # <CJK>
+0x625B 0x915B  # <CJK>
+0x625C 0x9161  # <CJK>
+0x625D 0x9164  # <CJK>
+0x625E 0x9167  # <CJK>
+0x625F 0x916D  # <CJK>
+0x6260 0x9174  # <CJK>
+0x6261 0x9179  # <CJK>
+0x6262 0x917A  # <CJK>
+0x6263 0x917B  # <CJK>
+0x6264 0x9181  # <CJK>
+0x6265 0x9183  # <CJK>
+0x6266 0x9185  # <CJK>
+0x6267 0x9186  # <CJK>
+0x6268 0x918A  # <CJK>
+0x6269 0x918E  # <CJK>
+0x626A 0x9191  # <CJK>
+0x626B 0x9193  # <CJK>
+0x626C 0x9194  # <CJK>
+0x626D 0x9195  # <CJK>
+0x626E 0x9198  # <CJK>
+0x626F 0x919E  # <CJK>
+0x6270 0x91A1  # <CJK>
+0x6271 0x91A6  # <CJK>
+0x6272 0x91A8  # <CJK>
+0x6273 0x91AC  # <CJK>
+0x6274 0x91AD  # <CJK>
+0x6275 0x91AE  # <CJK>
+0x6276 0x91B0  # <CJK>
+0x6277 0x91B1  # <CJK>
+0x6278 0x91B2  # <CJK>
+0x6279 0x91B3  # <CJK>
+0x627A 0x91B6  # <CJK>
+0x627B 0x91BB  # <CJK>
+0x627C 0x91BC  # <CJK>
+0x627D 0x91BD  # <CJK>
+0x627E 0x91BF  # <CJK>
+0x6321 0x91C2  # <CJK>
+0x6322 0x91C3  # <CJK>
+0x6323 0x91C5  # <CJK>
+0x6324 0x91D3  # <CJK>
+0x6325 0x91D4  # <CJK>
+0x6326 0x91D7  # <CJK>
+0x6327 0x91D9  # <CJK>
+0x6328 0x91DA  # <CJK>
+0x6329 0x91DE  # <CJK>
+0x632A 0x91E4  # <CJK>
+0x632B 0x91E5  # <CJK>
+0x632C 0x91E9  # <CJK>
+0x632D 0x91EA  # <CJK>
+0x632E 0x91EC  # <CJK>
+0x632F 0x91ED  # <CJK>
+0x6330 0x91EE  # <CJK>
+0x6331 0x91EF  # <CJK>
+0x6332 0x91F0  # <CJK>
+0x6333 0x91F1  # <CJK>
+0x6334 0x91F7  # <CJK>
+0x6335 0x91F9  # <CJK>
+0x6336 0x91FB  # <CJK>
+0x6337 0x91FD  # <CJK>
+0x6338 0x9200  # <CJK>
+0x6339 0x9201  # <CJK>
+0x633A 0x9204  # <CJK>
+0x633B 0x9205  # <CJK>
+0x633C 0x9206  # <CJK>
+0x633D 0x9207  # <CJK>
+0x633E 0x9209  # <CJK>
+0x633F 0x920A  # <CJK>
+0x6340 0x920C  # <CJK>
+0x6341 0x9210  # <CJK>
+0x6342 0x9212  # <CJK>
+0x6343 0x9213  # <CJK>
+0x6344 0x9216  # <CJK>
+0x6345 0x9218  # <CJK>
+0x6346 0x921C  # <CJK>
+0x6347 0x921D  # <CJK>
+0x6348 0x9223  # <CJK>
+0x6349 0x9224  # <CJK>
+0x634A 0x9225  # <CJK>
+0x634B 0x9226  # <CJK>
+0x634C 0x9228  # <CJK>
+0x634D 0x922E  # <CJK>
+0x634E 0x922F  # <CJK>
+0x634F 0x9230  # <CJK>
+0x6350 0x9233  # <CJK>
+0x6351 0x9235  # <CJK>
+0x6352 0x9236  # <CJK>
+0x6353 0x9238  # <CJK>
+0x6354 0x9239  # <CJK>
+0x6355 0x923A  # <CJK>
+0x6356 0x923C  # <CJK>
+0x6357 0x923E  # <CJK>
+0x6358 0x9240  # <CJK>
+0x6359 0x9242  # <CJK>
+0x635A 0x9243  # <CJK>
+0x635B 0x9246  # <CJK>
+0x635C 0x9247  # <CJK>
+0x635D 0x924A  # <CJK>
+0x635E 0x924D  # <CJK>
+0x635F 0x924E  # <CJK>
+0x6360 0x924F  # <CJK>
+0x6361 0x9251  # <CJK>
+0x6362 0x9258  # <CJK>
+0x6363 0x9259  # <CJK>
+0x6364 0x925C  # <CJK>
+0x6365 0x925D  # <CJK>
+0x6366 0x9260  # <CJK>
+0x6367 0x9261  # <CJK>
+0x6368 0x9265  # <CJK>
+0x6369 0x9267  # <CJK>
+0x636A 0x9268  # <CJK>
+0x636B 0x9269  # <CJK>
+0x636C 0x926E  # <CJK>
+0x636D 0x926F  # <CJK>
+0x636E 0x9270  # <CJK>
+0x636F 0x9275  # <CJK>
+0x6370 0x9276  # <CJK>
+0x6371 0x9277  # <CJK>
+0x6372 0x9278  # <CJK>
+0x6373 0x9279  # <CJK>
+0x6374 0x927B  # <CJK>
+0x6375 0x927C  # <CJK>
+0x6376 0x927D  # <CJK>
+0x6377 0x927F  # <CJK>
+0x6378 0x9288  # <CJK>
+0x6379 0x9289  # <CJK>
+0x637A 0x928A  # <CJK>
+0x637B 0x928D  # <CJK>
+0x637C 0x928E  # <CJK>
+0x637D 0x9292  # <CJK>
+0x637E 0x9297  # <CJK>
+0x6421 0x9299  # <CJK>
+0x6422 0x929F  # <CJK>
+0x6423 0x92A0  # <CJK>
+0x6424 0x92A4  # <CJK>
+0x6425 0x92A5  # <CJK>
+0x6426 0x92A7  # <CJK>
+0x6427 0x92A8  # <CJK>
+0x6428 0x92AB  # <CJK>
+0x6429 0x92AF  # <CJK>
+0x642A 0x92B2  # <CJK>
+0x642B 0x92B6  # <CJK>
+0x642C 0x92B8  # <CJK>
+0x642D 0x92BA  # <CJK>
+0x642E 0x92BB  # <CJK>
+0x642F 0x92BC  # <CJK>
+0x6430 0x92BD  # <CJK>
+0x6431 0x92BF  # <CJK>
+0x6432 0x92C0  # <CJK>
+0x6433 0x92C1  # <CJK>
+0x6434 0x92C2  # <CJK>
+0x6435 0x92C3  # <CJK>
+0x6436 0x92C5  # <CJK>
+0x6437 0x92C6  # <CJK>
+0x6438 0x92C7  # <CJK>
+0x6439 0x92C8  # <CJK>
+0x643A 0x92CB  # <CJK>
+0x643B 0x92CC  # <CJK>
+0x643C 0x92CD  # <CJK>
+0x643D 0x92CE  # <CJK>
+0x643E 0x92D0  # <CJK>
+0x643F 0x92D3  # <CJK>
+0x6440 0x92D5  # <CJK>
+0x6441 0x92D7  # <CJK>
+0x6442 0x92D8  # <CJK>
+0x6443 0x92D9  # <CJK>
+0x6444 0x92DC  # <CJK>
+0x6445 0x92DD  # <CJK>
+0x6446 0x92DF  # <CJK>
+0x6447 0x92E0  # <CJK>
+0x6448 0x92E1  # <CJK>
+0x6449 0x92E3  # <CJK>
+0x644A 0x92E5  # <CJK>
+0x644B 0x92E7  # <CJK>
+0x644C 0x92E8  # <CJK>
+0x644D 0x92EC  # <CJK>
+0x644E 0x92EE  # <CJK>
+0x644F 0x92F0  # <CJK>
+0x6450 0x92F9  # <CJK>
+0x6451 0x92FB  # <CJK>
+0x6452 0x92FF  # <CJK>
+0x6453 0x9300  # <CJK>
+0x6454 0x9302  # <CJK>
+0x6455 0x9308  # <CJK>
+0x6456 0x930D  # <CJK>
+0x6457 0x9311  # <CJK>
+0x6458 0x9314  # <CJK>
+0x6459 0x9315  # <CJK>
+0x645A 0x931C  # <CJK>
+0x645B 0x931D  # <CJK>
+0x645C 0x931E  # <CJK>
+0x645D 0x931F  # <CJK>
+0x645E 0x9321  # <CJK>
+0x645F 0x9324  # <CJK>
+0x6460 0x9325  # <CJK>
+0x6461 0x9327  # <CJK>
+0x6462 0x9329  # <CJK>
+0x6463 0x932A  # <CJK>
+0x6464 0x9333  # <CJK>
+0x6465 0x9334  # <CJK>
+0x6466 0x9336  # <CJK>
+0x6467 0x9337  # <CJK>
+0x6468 0x9347  # <CJK>
+0x6469 0x9348  # <CJK>
+0x646A 0x9349  # <CJK>
+0x646B 0x9350  # <CJK>
+0x646C 0x9351  # <CJK>
+0x646D 0x9352  # <CJK>
+0x646E 0x9355  # <CJK>
+0x646F 0x9357  # <CJK>
+0x6470 0x9358  # <CJK>
+0x6471 0x935A  # <CJK>
+0x6472 0x935E  # <CJK>
+0x6473 0x9364  # <CJK>
+0x6474 0x9365  # <CJK>
+0x6475 0x9367  # <CJK>
+0x6476 0x9369  # <CJK>
+0x6477 0x936A  # <CJK>
+0x6478 0x936D  # <CJK>
+0x6479 0x936F  # <CJK>
+0x647A 0x9370  # <CJK>
+0x647B 0x9371  # <CJK>
+0x647C 0x9373  # <CJK>
+0x647D 0x9374  # <CJK>
+0x647E 0x9376  # <CJK>
+0x6521 0x937A  # <CJK>
+0x6522 0x937D  # <CJK>
+0x6523 0x937F  # <CJK>
+0x6524 0x9380  # <CJK>
+0x6525 0x9381  # <CJK>
+0x6526 0x9382  # <CJK>
+0x6527 0x9388  # <CJK>
+0x6528 0x938A  # <CJK>
+0x6529 0x938B  # <CJK>
+0x652A 0x938D  # <CJK>
+0x652B 0x938F  # <CJK>
+0x652C 0x9392  # <CJK>
+0x652D 0x9395  # <CJK>
+0x652E 0x9398  # <CJK>
+0x652F 0x939B  # <CJK>
+0x6530 0x939E  # <CJK>
+0x6531 0x93A1  # <CJK>
+0x6532 0x93A3  # <CJK>
+0x6533 0x93A4  # <CJK>
+0x6534 0x93A6  # <CJK>
+0x6535 0x93A8  # <CJK>
+0x6536 0x93AB  # <CJK>
+0x6537 0x93B4  # <CJK>
+0x6538 0x93B5  # <CJK>
+0x6539 0x93B6  # <CJK>
+0x653A 0x93BA  # <CJK>
+0x653B 0x93A9  # <CJK>
+0x653C 0x93C1  # <CJK>
+0x653D 0x93C4  # <CJK>
+0x653E 0x93C5  # <CJK>
+0x653F 0x93C6  # <CJK>
+0x6540 0x93C7  # <CJK>
+0x6541 0x93C9  # <CJK>
+0x6542 0x93CA  # <CJK>
+0x6543 0x93CB  # <CJK>
+0x6544 0x93CC  # <CJK>
+0x6545 0x93CD  # <CJK>
+0x6546 0x93D3  # <CJK>
+0x6547 0x93D9  # <CJK>
+0x6548 0x93DC  # <CJK>
+0x6549 0x93DE  # <CJK>
+0x654A 0x93DF  # <CJK>
+0x654B 0x93E2  # <CJK>
+0x654C 0x93E6  # <CJK>
+0x654D 0x93E7  # <CJK>
+0x654E 0x93F9  # <CJK>
+0x654F 0x93F7  # <CJK>
+0x6550 0x93F8  # <CJK>
+0x6551 0x93FA  # <CJK>
+0x6552 0x93FB  # <CJK>
+0x6553 0x93FD  # <CJK>
+0x6554 0x9401  # <CJK>
+0x6555 0x9402  # <CJK>
+0x6556 0x9404  # <CJK>
+0x6557 0x9408  # <CJK>
+0x6558 0x9409  # <CJK>
+0x6559 0x940D  # <CJK>
+0x655A 0x940E  # <CJK>
+0x655B 0x940F  # <CJK>
+0x655C 0x9415  # <CJK>
+0x655D 0x9416  # <CJK>
+0x655E 0x9417  # <CJK>
+0x655F 0x941F  # <CJK>
+0x6560 0x942E  # <CJK>
+0x6561 0x942F  # <CJK>
+0x6562 0x9431  # <CJK>
+0x6563 0x9432  # <CJK>
+0x6564 0x9433  # <CJK>
+0x6565 0x9434  # <CJK>
+0x6566 0x943B  # <CJK>
+0x6567 0x943F  # <CJK>
+0x6568 0x943D  # <CJK>
+0x6569 0x9443  # <CJK>
+0x656A 0x9445  # <CJK>
+0x656B 0x9448  # <CJK>
+0x656C 0x944A  # <CJK>
+0x656D 0x944C  # <CJK>
+0x656E 0x9455  # <CJK>
+0x656F 0x9459  # <CJK>
+0x6570 0x945C  # <CJK>
+0x6571 0x945F  # <CJK>
+0x6572 0x9461  # <CJK>
+0x6573 0x9463  # <CJK>
+0x6574 0x9468  # <CJK>
+0x6575 0x946B  # <CJK>
+0x6576 0x946D  # <CJK>
+0x6577 0x946E  # <CJK>
+0x6578 0x946F  # <CJK>
+0x6579 0x9471  # <CJK>
+0x657A 0x9472  # <CJK>
+0x657B 0x9484  # <CJK>
+0x657C 0x9483  # <CJK>
+0x657D 0x9578  # <CJK>
+0x657E 0x9579  # <CJK>
+0x6621 0x957E  # <CJK>
+0x6622 0x9584  # <CJK>
+0x6623 0x9588  # <CJK>
+0x6624 0x958C  # <CJK>
+0x6625 0x958D  # <CJK>
+0x6626 0x958E  # <CJK>
+0x6627 0x959D  # <CJK>
+0x6628 0x959E  # <CJK>
+0x6629 0x959F  # <CJK>
+0x662A 0x95A1  # <CJK>
+0x662B 0x95A6  # <CJK>
+0x662C 0x95A9  # <CJK>
+0x662D 0x95AB  # <CJK>
+0x662E 0x95AC  # <CJK>
+0x662F 0x95B4  # <CJK>
+0x6630 0x95B6  # <CJK>
+0x6631 0x95BA  # <CJK>
+0x6632 0x95BD  # <CJK>
+0x6633 0x95BF  # <CJK>
+0x6634 0x95C6  # <CJK>
+0x6635 0x95C8  # <CJK>
+0x6636 0x95C9  # <CJK>
+0x6637 0x95CB  # <CJK>
+0x6638 0x95D0  # <CJK>
+0x6639 0x95D1  # <CJK>
+0x663A 0x95D2  # <CJK>
+0x663B 0x95D3  # <CJK>
+0x663C 0x95D9  # <CJK>
+0x663D 0x95DA  # <CJK>
+0x663E 0x95DD  # <CJK>
+0x663F 0x95DE  # <CJK>
+0x6640 0x95DF  # <CJK>
+0x6641 0x95E0  # <CJK>
+0x6642 0x95E4  # <CJK>
+0x6643 0x95E6  # <CJK>
+0x6644 0x961D  # <CJK>
+0x6645 0x961E  # <CJK>
+0x6646 0x9622  # <CJK>
+0x6647 0x9624  # <CJK>
+0x6648 0x9625  # <CJK>
+0x6649 0x9626  # <CJK>
+0x664A 0x962C  # <CJK>
+0x664B 0x9631  # <CJK>
+0x664C 0x9633  # <CJK>
+0x664D 0x9637  # <CJK>
+0x664E 0x9638  # <CJK>
+0x664F 0x9639  # <CJK>
+0x6650 0x963A  # <CJK>
+0x6651 0x963C  # <CJK>
+0x6652 0x963D  # <CJK>
+0x6653 0x9641  # <CJK>
+0x6654 0x9652  # <CJK>
+0x6655 0x9654  # <CJK>
+0x6656 0x9656  # <CJK>
+0x6657 0x9657  # <CJK>
+0x6658 0x9658  # <CJK>
+0x6659 0x9661  # <CJK>
+0x665A 0x966E  # <CJK>
+0x665B 0x9674  # <CJK>
+0x665C 0x967B  # <CJK>
+0x665D 0x967C  # <CJK>
+0x665E 0x967E  # <CJK>
+0x665F 0x967F  # <CJK>
+0x6660 0x9681  # <CJK>
+0x6661 0x9682  # <CJK>
+0x6662 0x9683  # <CJK>
+0x6663 0x9684  # <CJK>
+0x6664 0x9689  # <CJK>
+0x6665 0x9691  # <CJK>
+0x6666 0x9696  # <CJK>
+0x6667 0x969A  # <CJK>
+0x6668 0x969D  # <CJK>
+0x6669 0x969F  # <CJK>
+0x666A 0x96A4  # <CJK>
+0x666B 0x96A5  # <CJK>
+0x666C 0x96A6  # <CJK>
+0x666D 0x96A9  # <CJK>
+0x666E 0x96AE  # <CJK>
+0x666F 0x96AF  # <CJK>
+0x6670 0x96B3  # <CJK>
+0x6671 0x96BA  # <CJK>
+0x6672 0x96CA  # <CJK>
+0x6673 0x96D2  # <CJK>
+0x6674 0x5DB2  # <CJK>
+0x6675 0x96D8  # <CJK>
+0x6676 0x96DA  # <CJK>
+0x6677 0x96DD  # <CJK>
+0x6678 0x96DE  # <CJK>
+0x6679 0x96DF  # <CJK>
+0x667A 0x96E9  # <CJK>
+0x667B 0x96EF  # <CJK>
+0x667C 0x96F1  # <CJK>
+0x667D 0x96FA  # <CJK>
+0x667E 0x9702  # <CJK>
+0x6721 0x9703  # <CJK>
+0x6722 0x9705  # <CJK>
+0x6723 0x9709  # <CJK>
+0x6724 0x971A  # <CJK>
+0x6725 0x971B  # <CJK>
+0x6726 0x971D  # <CJK>
+0x6727 0x9721  # <CJK>
+0x6728 0x9722  # <CJK>
+0x6729 0x9723  # <CJK>
+0x672A 0x9728  # <CJK>
+0x672B 0x9731  # <CJK>
+0x672C 0x9733  # <CJK>
+0x672D 0x9741  # <CJK>
+0x672E 0x9743  # <CJK>
+0x672F 0x974A  # <CJK>
+0x6730 0x974E  # <CJK>
+0x6731 0x974F  # <CJK>
+0x6732 0x9755  # <CJK>
+0x6733 0x9757  # <CJK>
+0x6734 0x9758  # <CJK>
+0x6735 0x975A  # <CJK>
+0x6736 0x975B  # <CJK>
+0x6737 0x9763  # <CJK>
+0x6738 0x9767  # <CJK>
+0x6739 0x976A  # <CJK>
+0x673A 0x976E  # <CJK>
+0x673B 0x9773  # <CJK>
+0x673C 0x9776  # <CJK>
+0x673D 0x9777  # <CJK>
+0x673E 0x9778  # <CJK>
+0x673F 0x977B  # <CJK>
+0x6740 0x977D  # <CJK>
+0x6741 0x977F  # <CJK>
+0x6742 0x9780  # <CJK>
+0x6743 0x9789  # <CJK>
+0x6744 0x9795  # <CJK>
+0x6745 0x9796  # <CJK>
+0x6746 0x9797  # <CJK>
+0x6747 0x9799  # <CJK>
+0x6748 0x979A  # <CJK>
+0x6749 0x979E  # <CJK>
+0x674A 0x979F  # <CJK>
+0x674B 0x97A2  # <CJK>
+0x674C 0x97AC  # <CJK>
+0x674D 0x97AE  # <CJK>
+0x674E 0x97B1  # <CJK>
+0x674F 0x97B2  # <CJK>
+0x6750 0x97B5  # <CJK>
+0x6751 0x97B6  # <CJK>
+0x6752 0x97B8  # <CJK>
+0x6753 0x97B9  # <CJK>
+0x6754 0x97BA  # <CJK>
+0x6755 0x97BC  # <CJK>
+0x6756 0x97BE  # <CJK>
+0x6757 0x97BF  # <CJK>
+0x6758 0x97C1  # <CJK>
+0x6759 0x97C4  # <CJK>
+0x675A 0x97C5  # <CJK>
+0x675B 0x97C7  # <CJK>
+0x675C 0x97C9  # <CJK>
+0x675D 0x97CA  # <CJK>
+0x675E 0x97CC  # <CJK>
+0x675F 0x97CD  # <CJK>
+0x6760 0x97CE  # <CJK>
+0x6761 0x97D0  # <CJK>
+0x6762 0x97D1  # <CJK>
+0x6763 0x97D4  # <CJK>
+0x6764 0x97D7  # <CJK>
+0x6765 0x97D8  # <CJK>
+0x6766 0x97D9  # <CJK>
+0x6767 0x97DD  # <CJK>
+0x6768 0x97DE  # <CJK>
+0x6769 0x97E0  # <CJK>
+0x676A 0x97DB  # <CJK>
+0x676B 0x97E1  # <CJK>
+0x676C 0x97E4  # <CJK>
+0x676D 0x97EF  # <CJK>
+0x676E 0x97F1  # <CJK>
+0x676F 0x97F4  # <CJK>
+0x6770 0x97F7  # <CJK>
+0x6771 0x97F8  # <CJK>
+0x6772 0x97FA  # <CJK>
+0x6773 0x9807  # <CJK>
+0x6774 0x980A  # <CJK>
+0x6775 0x9819  # <CJK>
+0x6776 0x980D  # <CJK>
+0x6777 0x980E  # <CJK>
+0x6778 0x9814  # <CJK>
+0x6779 0x9816  # <CJK>
+0x677A 0x981C  # <CJK>
+0x677B 0x981E  # <CJK>
+0x677C 0x9820  # <CJK>
+0x677D 0x9823  # <CJK>
+0x677E 0x9826  # <CJK>
+0x6821 0x982B  # <CJK>
+0x6822 0x982E  # <CJK>
+0x6823 0x982F  # <CJK>
+0x6824 0x9830  # <CJK>
+0x6825 0x9832  # <CJK>
+0x6826 0x9833  # <CJK>
+0x6827 0x9835  # <CJK>
+0x6828 0x9825  # <CJK>
+0x6829 0x983E  # <CJK>
+0x682A 0x9844  # <CJK>
+0x682B 0x9847  # <CJK>
+0x682C 0x984A  # <CJK>
+0x682D 0x9851  # <CJK>
+0x682E 0x9852  # <CJK>
+0x682F 0x9853  # <CJK>
+0x6830 0x9856  # <CJK>
+0x6831 0x9857  # <CJK>
+0x6832 0x9859  # <CJK>
+0x6833 0x985A  # <CJK>
+0x6834 0x9862  # <CJK>
+0x6835 0x9863  # <CJK>
+0x6836 0x9865  # <CJK>
+0x6837 0x9866  # <CJK>
+0x6838 0x986A  # <CJK>
+0x6839 0x986C  # <CJK>
+0x683A 0x98AB  # <CJK>
+0x683B 0x98AD  # <CJK>
+0x683C 0x98AE  # <CJK>
+0x683D 0x98B0  # <CJK>
+0x683E 0x98B4  # <CJK>
+0x683F 0x98B7  # <CJK>
+0x6840 0x98B8  # <CJK>
+0x6841 0x98BA  # <CJK>
+0x6842 0x98BB  # <CJK>
+0x6843 0x98BF  # <CJK>
+0x6844 0x98C2  # <CJK>
+0x6845 0x98C5  # <CJK>
+0x6846 0x98C8  # <CJK>
+0x6847 0x98CC  # <CJK>
+0x6848 0x98E1  # <CJK>
+0x6849 0x98E3  # <CJK>
+0x684A 0x98E5  # <CJK>
+0x684B 0x98E6  # <CJK>
+0x684C 0x98E7  # <CJK>
+0x684D 0x98EA  # <CJK>
+0x684E 0x98F3  # <CJK>
+0x684F 0x98F6  # <CJK>
+0x6850 0x9902  # <CJK>
+0x6851 0x9907  # <CJK>
+0x6852 0x9908  # <CJK>
+0x6853 0x9911  # <CJK>
+0x6854 0x9915  # <CJK>
+0x6855 0x9916  # <CJK>
+0x6856 0x9917  # <CJK>
+0x6857 0x991A  # <CJK>
+0x6858 0x991B  # <CJK>
+0x6859 0x991C  # <CJK>
+0x685A 0x991F  # <CJK>
+0x685B 0x9922  # <CJK>
+0x685C 0x9926  # <CJK>
+0x685D 0x9927  # <CJK>
+0x685E 0x992B  # <CJK>
+0x685F 0x9931  # <CJK>
+0x6860 0x9932  # <CJK>
+0x6861 0x9933  # <CJK>
+0x6862 0x9934  # <CJK>
+0x6863 0x9935  # <CJK>
+0x6864 0x9939  # <CJK>
+0x6865 0x993A  # <CJK>
+0x6866 0x993B  # <CJK>
+0x6867 0x993C  # <CJK>
+0x6868 0x9940  # <CJK>
+0x6869 0x9941  # <CJK>
+0x686A 0x9946  # <CJK>
+0x686B 0x9947  # <CJK>
+0x686C 0x9948  # <CJK>
+0x686D 0x994D  # <CJK>
+0x686E 0x994E  # <CJK>
+0x686F 0x9954  # <CJK>
+0x6870 0x9958  # <CJK>
+0x6871 0x9959  # <CJK>
+0x6872 0x995B  # <CJK>
+0x6873 0x995C  # <CJK>
+0x6874 0x995E  # <CJK>
+0x6875 0x995F  # <CJK>
+0x6876 0x9960  # <CJK>
+0x6877 0x999B  # <CJK>
+0x6878 0x999D  # <CJK>
+0x6879 0x999F  # <CJK>
+0x687A 0x99A6  # <CJK>
+0x687B 0x99B0  # <CJK>
+0x687C 0x99B1  # <CJK>
+0x687D 0x99B2  # <CJK>
+0x687E 0x99B5  # <CJK>
+0x6921 0x99B9  # <CJK>
+0x6922 0x99BA  # <CJK>
+0x6923 0x99BD  # <CJK>
+0x6924 0x99BF  # <CJK>
+0x6925 0x99C3  # <CJK>
+0x6926 0x99C9  # <CJK>
+0x6927 0x99D3  # <CJK>
+0x6928 0x99D4  # <CJK>
+0x6929 0x99D9  # <CJK>
+0x692A 0x99DA  # <CJK>
+0x692B 0x99DC  # <CJK>
+0x692C 0x99DE  # <CJK>
+0x692D 0x99E7  # <CJK>
+0x692E 0x99EA  # <CJK>
+0x692F 0x99EB  # <CJK>
+0x6930 0x99EC  # <CJK>
+0x6931 0x99F0  # <CJK>
+0x6932 0x99F4  # <CJK>
+0x6933 0x99F5  # <CJK>
+0x6934 0x99F9  # <CJK>
+0x6935 0x99FD  # <CJK>
+0x6936 0x99FE  # <CJK>
+0x6937 0x9A02  # <CJK>
+0x6938 0x9A03  # <CJK>
+0x6939 0x9A04  # <CJK>
+0x693A 0x9A0B  # <CJK>
+0x693B 0x9A0C  # <CJK>
+0x693C 0x9A10  # <CJK>
+0x693D 0x9A11  # <CJK>
+0x693E 0x9A16  # <CJK>
+0x693F 0x9A1E  # <CJK>
+0x6940 0x9A20  # <CJK>
+0x6941 0x9A22  # <CJK>
+0x6942 0x9A23  # <CJK>
+0x6943 0x9A24  # <CJK>
+0x6944 0x9A27  # <CJK>
+0x6945 0x9A2D  # <CJK>
+0x6946 0x9A2E  # <CJK>
+0x6947 0x9A33  # <CJK>
+0x6948 0x9A35  # <CJK>
+0x6949 0x9A36  # <CJK>
+0x694A 0x9A38  # <CJK>
+0x694B 0x9A47  # <CJK>
+0x694C 0x9A41  # <CJK>
+0x694D 0x9A44  # <CJK>
+0x694E 0x9A4A  # <CJK>
+0x694F 0x9A4B  # <CJK>
+0x6950 0x9A4C  # <CJK>
+0x6951 0x9A4E  # <CJK>
+0x6952 0x9A51  # <CJK>
+0x6953 0x9A54  # <CJK>
+0x6954 0x9A56  # <CJK>
+0x6955 0x9A5D  # <CJK>
+0x6956 0x9AAA  # <CJK>
+0x6957 0x9AAC  # <CJK>
+0x6958 0x9AAE  # <CJK>
+0x6959 0x9AAF  # <CJK>
+0x695A 0x9AB2  # <CJK>
+0x695B 0x9AB4  # <CJK>
+0x695C 0x9AB5  # <CJK>
+0x695D 0x9AB6  # <CJK>
+0x695E 0x9AB9  # <CJK>
+0x695F 0x9ABB  # <CJK>
+0x6960 0x9ABE  # <CJK>
+0x6961 0x9ABF  # <CJK>
+0x6962 0x9AC1  # <CJK>
+0x6963 0x9AC3  # <CJK>
+0x6964 0x9AC6  # <CJK>
+0x6965 0x9AC8  # <CJK>
+0x6966 0x9ACE  # <CJK>
+0x6967 0x9AD0  # <CJK>
+0x6968 0x9AD2  # <CJK>
+0x6969 0x9AD5  # <CJK>
+0x696A 0x9AD6  # <CJK>
+0x696B 0x9AD7  # <CJK>
+0x696C 0x9ADB  # <CJK>
+0x696D 0x9ADC  # <CJK>
+0x696E 0x9AE0  # <CJK>
+0x696F 0x9AE4  # <CJK>
+0x6970 0x9AE5  # <CJK>
+0x6971 0x9AE7  # <CJK>
+0x6972 0x9AE9  # <CJK>
+0x6973 0x9AEC  # <CJK>
+0x6974 0x9AF2  # <CJK>
+0x6975 0x9AF3  # <CJK>
+0x6976 0x9AF5  # <CJK>
+0x6977 0x9AF9  # <CJK>
+0x6978 0x9AFA  # <CJK>
+0x6979 0x9AFD  # <CJK>
+0x697A 0x9AFF  # <CJK>
+0x697B 0x9B00  # <CJK>
+0x697C 0x9B01  # <CJK>
+0x697D 0x9B02  # <CJK>
+0x697E 0x9B03  # <CJK>
+0x6A21 0x9B04  # <CJK>
+0x6A22 0x9B05  # <CJK>
+0x6A23 0x9B08  # <CJK>
+0x6A24 0x9B09  # <CJK>
+0x6A25 0x9B0B  # <CJK>
+0x6A26 0x9B0C  # <CJK>
+0x6A27 0x9B0D  # <CJK>
+0x6A28 0x9B0E  # <CJK>
+0x6A29 0x9B10  # <CJK>
+0x6A2A 0x9B12  # <CJK>
+0x6A2B 0x9B16  # <CJK>
+0x6A2C 0x9B19  # <CJK>
+0x6A2D 0x9B1B  # <CJK>
+0x6A2E 0x9B1C  # <CJK>
+0x6A2F 0x9B20  # <CJK>
+0x6A30 0x9B26  # <CJK>
+0x6A31 0x9B2B  # <CJK>
+0x6A32 0x9B2D  # <CJK>
+0x6A33 0x9B33  # <CJK>
+0x6A34 0x9B34  # <CJK>
+0x6A35 0x9B35  # <CJK>
+0x6A36 0x9B37  # <CJK>
+0x6A37 0x9B39  # <CJK>
+0x6A38 0x9B3A  # <CJK>
+0x6A39 0x9B3D  # <CJK>
+0x6A3A 0x9B48  # <CJK>
+0x6A3B 0x9B4B  # <CJK>
+0x6A3C 0x9B4C  # <CJK>
+0x6A3D 0x9B55  # <CJK>
+0x6A3E 0x9B56  # <CJK>
+0x6A3F 0x9B57  # <CJK>
+0x6A40 0x9B5B  # <CJK>
+0x6A41 0x9B5E  # <CJK>
+0x6A42 0x9B61  # <CJK>
+0x6A43 0x9B63  # <CJK>
+0x6A44 0x9B65  # <CJK>
+0x6A45 0x9B66  # <CJK>
+0x6A46 0x9B68  # <CJK>
+0x6A47 0x9B6A  # <CJK>
+0x6A48 0x9B6B  # <CJK>
+0x6A49 0x9B6C  # <CJK>
+0x6A4A 0x9B6D  # <CJK>
+0x6A4B 0x9B6E  # <CJK>
+0x6A4C 0x9B73  # <CJK>
+0x6A4D 0x9B75  # <CJK>
+0x6A4E 0x9B77  # <CJK>
+0x6A4F 0x9B78  # <CJK>
+0x6A50 0x9B79  # <CJK>
+0x6A51 0x9B7F  # <CJK>
+0x6A52 0x9B80  # <CJK>
+0x6A53 0x9B84  # <CJK>
+0x6A54 0x9B85  # <CJK>
+0x6A55 0x9B86  # <CJK>
+0x6A56 0x9B87  # <CJK>
+0x6A57 0x9B89  # <CJK>
+0x6A58 0x9B8A  # <CJK>
+0x6A59 0x9B8B  # <CJK>
+0x6A5A 0x9B8D  # <CJK>
+0x6A5B 0x9B8F  # <CJK>
+0x6A5C 0x9B90  # <CJK>
+0x6A5D 0x9B94  # <CJK>
+0x6A5E 0x9B9A  # <CJK>
+0x6A5F 0x9B9D  # <CJK>
+0x6A60 0x9B9E  # <CJK>
+0x6A61 0x9BA6  # <CJK>
+0x6A62 0x9BA7  # <CJK>
+0x6A63 0x9BA9  # <CJK>
+0x6A64 0x9BAC  # <CJK>
+0x6A65 0x9BB0  # <CJK>
+0x6A66 0x9BB1  # <CJK>
+0x6A67 0x9BB2  # <CJK>
+0x6A68 0x9BB7  # <CJK>
+0x6A69 0x9BB8  # <CJK>
+0x6A6A 0x9BBB  # <CJK>
+0x6A6B 0x9BBC  # <CJK>
+0x6A6C 0x9BBE  # <CJK>
+0x6A6D 0x9BBF  # <CJK>
+0x6A6E 0x9BC1  # <CJK>
+0x6A6F 0x9BC7  # <CJK>
+0x6A70 0x9BC8  # <CJK>
+0x6A71 0x9BCE  # <CJK>
+0x6A72 0x9BD0  # <CJK>
+0x6A73 0x9BD7  # <CJK>
+0x6A74 0x9BD8  # <CJK>
+0x6A75 0x9BDD  # <CJK>
+0x6A76 0x9BDF  # <CJK>
+0x6A77 0x9BE5  # <CJK>
+0x6A78 0x9BE7  # <CJK>
+0x6A79 0x9BEA  # <CJK>
+0x6A7A 0x9BEB  # <CJK>
+0x6A7B 0x9BEF  # <CJK>
+0x6A7C 0x9BF3  # <CJK>
+0x6A7D 0x9BF7  # <CJK>
+0x6A7E 0x9BF8  # <CJK>
+0x6B21 0x9BF9  # <CJK>
+0x6B22 0x9BFA  # <CJK>
+0x6B23 0x9BFD  # <CJK>
+0x6B24 0x9BFF  # <CJK>
+0x6B25 0x9C00  # <CJK>
+0x6B26 0x9C02  # <CJK>
+0x6B27 0x9C0B  # <CJK>
+0x6B28 0x9C0F  # <CJK>
+0x6B29 0x9C11  # <CJK>
+0x6B2A 0x9C16  # <CJK>
+0x6B2B 0x9C18  # <CJK>
+0x6B2C 0x9C19  # <CJK>
+0x6B2D 0x9C1A  # <CJK>
+0x6B2E 0x9C1C  # <CJK>
+0x6B2F 0x9C1E  # <CJK>
+0x6B30 0x9C22  # <CJK>
+0x6B31 0x9C23  # <CJK>
+0x6B32 0x9C26  # <CJK>
+0x6B33 0x9C27  # <CJK>
+0x6B34 0x9C28  # <CJK>
+0x6B35 0x9C29  # <CJK>
+0x6B36 0x9C2A  # <CJK>
+0x6B37 0x9C31  # <CJK>
+0x6B38 0x9C35  # <CJK>
+0x6B39 0x9C36  # <CJK>
+0x6B3A 0x9C37  # <CJK>
+0x6B3B 0x9C3D  # <CJK>
+0x6B3C 0x9C41  # <CJK>
+0x6B3D 0x9C43  # <CJK>
+0x6B3E 0x9C44  # <CJK>
+0x6B3F 0x9C45  # <CJK>
+0x6B40 0x9C49  # <CJK>
+0x6B41 0x9C4A  # <CJK>
+0x6B42 0x9C4E  # <CJK>
+0x6B43 0x9C4F  # <CJK>
+0x6B44 0x9C50  # <CJK>
+0x6B45 0x9C53  # <CJK>
+0x6B46 0x9C54  # <CJK>
+0x6B47 0x9C56  # <CJK>
+0x6B48 0x9C58  # <CJK>
+0x6B49 0x9C5B  # <CJK>
+0x6B4A 0x9C5D  # <CJK>
+0x6B4B 0x9C5E  # <CJK>
+0x6B4C 0x9C5F  # <CJK>
+0x6B4D 0x9C63  # <CJK>
+0x6B4E 0x9C69  # <CJK>
+0x6B4F 0x9C6A  # <CJK>
+0x6B50 0x9C5C  # <CJK>
+0x6B51 0x9C6B  # <CJK>
+0x6B52 0x9C68  # <CJK>
+0x6B53 0x9C6E  # <CJK>
+0x6B54 0x9C70  # <CJK>
+0x6B55 0x9C72  # <CJK>
+0x6B56 0x9C75  # <CJK>
+0x6B57 0x9C77  # <CJK>
+0x6B58 0x9C7B  # <CJK>
+0x6B59 0x9CE6  # <CJK>
+0x6B5A 0x9CF2  # <CJK>
+0x6B5B 0x9CF7  # <CJK>
+0x6B5C 0x9CF9  # <CJK>
+0x6B5D 0x9D0B  # <CJK>
+0x6B5E 0x9D02  # <CJK>
+0x6B5F 0x9D11  # <CJK>
+0x6B60 0x9D17  # <CJK>
+0x6B61 0x9D18  # <CJK>
+0x6B62 0x9D1C  # <CJK>
+0x6B63 0x9D1D  # <CJK>
+0x6B64 0x9D1E  # <CJK>
+0x6B65 0x9D2F  # <CJK>
+0x6B66 0x9D30  # <CJK>
+0x6B67 0x9D32  # <CJK>
+0x6B68 0x9D33  # <CJK>
+0x6B69 0x9D34  # <CJK>
+0x6B6A 0x9D3A  # <CJK>
+0x6B6B 0x9D3C  # <CJK>
+0x6B6C 0x9D45  # <CJK>
+0x6B6D 0x9D3D  # <CJK>
+0x6B6E 0x9D42  # <CJK>
+0x6B6F 0x9D43  # <CJK>
+0x6B70 0x9D47  # <CJK>
+0x6B71 0x9D4A  # <CJK>
+0x6B72 0x9D53  # <CJK>
+0x6B73 0x9D54  # <CJK>
+0x6B74 0x9D5F  # <CJK>
+0x6B75 0x9D63  # <CJK>
+0x6B76 0x9D62  # <CJK>
+0x6B77 0x9D65  # <CJK>
+0x6B78 0x9D69  # <CJK>
+0x6B79 0x9D6A  # <CJK>
+0x6B7A 0x9D6B  # <CJK>
+0x6B7B 0x9D70  # <CJK>
+0x6B7C 0x9D76  # <CJK>
+0x6B7D 0x9D77  # <CJK>
+0x6B7E 0x9D7B  # <CJK>
+0x6C21 0x9D7C  # <CJK>
+0x6C22 0x9D7E  # <CJK>
+0x6C23 0x9D83  # <CJK>
+0x6C24 0x9D84  # <CJK>
+0x6C25 0x9D86  # <CJK>
+0x6C26 0x9D8A  # <CJK>
+0x6C27 0x9D8D  # <CJK>
+0x6C28 0x9D8E  # <CJK>
+0x6C29 0x9D92  # <CJK>
+0x6C2A 0x9D93  # <CJK>
+0x6C2B 0x9D95  # <CJK>
+0x6C2C 0x9D96  # <CJK>
+0x6C2D 0x9D97  # <CJK>
+0x6C2E 0x9D98  # <CJK>
+0x6C2F 0x9DA1  # <CJK>
+0x6C30 0x9DAA  # <CJK>
+0x6C31 0x9DAC  # <CJK>
+0x6C32 0x9DAE  # <CJK>
+0x6C33 0x9DB1  # <CJK>
+0x6C34 0x9DB5  # <CJK>
+0x6C35 0x9DB9  # <CJK>
+0x6C36 0x9DBC  # <CJK>
+0x6C37 0x9DBF  # <CJK>
+0x6C38 0x9DC3  # <CJK>
+0x6C39 0x9DC7  # <CJK>
+0x6C3A 0x9DC9  # <CJK>
+0x6C3B 0x9DCA  # <CJK>
+0x6C3C 0x9DD4  # <CJK>
+0x6C3D 0x9DD5  # <CJK>
+0x6C3E 0x9DD6  # <CJK>
+0x6C3F 0x9DD7  # <CJK>
+0x6C40 0x9DDA  # <CJK>
+0x6C41 0x9DDE  # <CJK>
+0x6C42 0x9DDF  # <CJK>
+0x6C43 0x9DE0  # <CJK>
+0x6C44 0x9DE5  # <CJK>
+0x6C45 0x9DE7  # <CJK>
+0x6C46 0x9DE9  # <CJK>
+0x6C47 0x9DEB  # <CJK>
+0x6C48 0x9DEE  # <CJK>
+0x6C49 0x9DF0  # <CJK>
+0x6C4A 0x9DF3  # <CJK>
+0x6C4B 0x9DF4  # <CJK>
+0x6C4C 0x9DFE  # <CJK>
+0x6C4D 0x9E0A  # <CJK>
+0x6C4E 0x9E02  # <CJK>
+0x6C4F 0x9E07  # <CJK>
+0x6C50 0x9E0E  # <CJK>
+0x6C51 0x9E10  # <CJK>
+0x6C52 0x9E11  # <CJK>
+0x6C53 0x9E12  # <CJK>
+0x6C54 0x9E15  # <CJK>
+0x6C55 0x9E16  # <CJK>
+0x6C56 0x9E19  # <CJK>
+0x6C57 0x9E1C  # <CJK>
+0x6C58 0x9E1D  # <CJK>
+0x6C59 0x9E7A  # <CJK>
+0x6C5A 0x9E7B  # <CJK>
+0x6C5B 0x9E7C  # <CJK>
+0x6C5C 0x9E80  # <CJK>
+0x6C5D 0x9E82  # <CJK>
+0x6C5E 0x9E83  # <CJK>
+0x6C5F 0x9E84  # <CJK>
+0x6C60 0x9E85  # <CJK>
+0x6C61 0x9E87  # <CJK>
+0x6C62 0x9E8E  # <CJK>
+0x6C63 0x9E8F  # <CJK>
+0x6C64 0x9E96  # <CJK>
+0x6C65 0x9E98  # <CJK>
+0x6C66 0x9E9B  # <CJK>
+0x6C67 0x9E9E  # <CJK>
+0x6C68 0x9EA4  # <CJK>
+0x6C69 0x9EA8  # <CJK>
+0x6C6A 0x9EAC  # <CJK>
+0x6C6B 0x9EAE  # <CJK>
+0x6C6C 0x9EAF  # <CJK>
+0x6C6D 0x9EB0  # <CJK>
+0x6C6E 0x9EB3  # <CJK>
+0x6C6F 0x9EB4  # <CJK>
+0x6C70 0x9EB5  # <CJK>
+0x6C71 0x9EC6  # <CJK>
+0x6C72 0x9EC8  # <CJK>
+0x6C73 0x9ECB  # <CJK>
+0x6C74 0x9ED5  # <CJK>
+0x6C75 0x9EDF  # <CJK>
+0x6C76 0x9EE4  # <CJK>
+0x6C77 0x9EE7  # <CJK>
+0x6C78 0x9EEC  # <CJK>
+0x6C79 0x9EED  # <CJK>
+0x6C7A 0x9EEE  # <CJK>
+0x6C7B 0x9EF0  # <CJK>
+0x6C7C 0x9EF1  # <CJK>
+0x6C7D 0x9EF2  # <CJK>
+0x6C7E 0x9EF5  # <CJK>
+0x6D21 0x9EF8  # <CJK>
+0x6D22 0x9EFF  # <CJK>
+0x6D23 0x9F02  # <CJK>
+0x6D24 0x9F03  # <CJK>
+0x6D25 0x9F09  # <CJK>
+0x6D26 0x9F0F  # <CJK>
+0x6D27 0x9F10  # <CJK>
+0x6D28 0x9F11  # <CJK>
+0x6D29 0x9F12  # <CJK>
+0x6D2A 0x9F14  # <CJK>
+0x6D2B 0x9F16  # <CJK>
+0x6D2C 0x9F17  # <CJK>
+0x6D2D 0x9F19  # <CJK>
+0x6D2E 0x9F1A  # <CJK>
+0x6D2F 0x9F1B  # <CJK>
+0x6D30 0x9F1F  # <CJK>
+0x6D31 0x9F22  # <CJK>
+0x6D32 0x9F26  # <CJK>
+0x6D33 0x9F2A  # <CJK>
+0x6D34 0x9F2B  # <CJK>
+0x6D35 0x9F2F  # <CJK>
+0x6D36 0x9F31  # <CJK>
+0x6D37 0x9F32  # <CJK>
+0x6D38 0x9F34  # <CJK>
+0x6D39 0x9F37  # <CJK>
+0x6D3A 0x9F39  # <CJK>
+0x6D3B 0x9F3A  # <CJK>
+0x6D3C 0x9F3C  # <CJK>
+0x6D3D 0x9F3D  # <CJK>
+0x6D3E 0x9F3F  # <CJK>
+0x6D3F 0x9F41  # <CJK>
+0x6D40 0x9F43  # <CJK>
+0x6D41 0x9F44  # <CJK>
+0x6D42 0x9F45  # <CJK>
+0x6D43 0x9F46  # <CJK>
+0x6D44 0x9F47  # <CJK>
+0x6D45 0x9F53  # <CJK>
+0x6D46 0x9F55  # <CJK>
+0x6D47 0x9F56  # <CJK>
+0x6D48 0x9F57  # <CJK>
+0x6D49 0x9F58  # <CJK>
+0x6D4A 0x9F5A  # <CJK>
+0x6D4B 0x9F5D  # <CJK>
+0x6D4C 0x9F5E  # <CJK>
+0x6D4D 0x9F68  # <CJK>
+0x6D4E 0x9F69  # <CJK>
+0x6D4F 0x9F6D  # <CJK>
+0x6D50 0x9F6E  # <CJK>
+0x6D51 0x9F6F  # <CJK>
+0x6D52 0x9F70  # <CJK>
+0x6D53 0x9F71  # <CJK>
+0x6D54 0x9F73  # <CJK>
+0x6D55 0x9F75  # <CJK>
+0x6D56 0x9F7A  # <CJK>
+0x6D57 0x9F7D  # <CJK>
+0x6D58 0x9F8F  # <CJK>
+0x6D59 0x9F90  # <CJK>
+0x6D5A 0x9F91  # <CJK>
+0x6D5B 0x9F92  # <CJK>
+0x6D5C 0x9F94  # <CJK>
+0x6D5D 0x9F96  # <CJK>
+0x6D5E 0x9F97  # <CJK>
+0x6D5F 0x9F9E  # <CJK>
+0x6D60 0x9FA1  # <CJK>
+0x6D61 0x9FA2  # <CJK>
+0x6D62 0x9FA3  # <CJK>
+0x6D63 0x9FA5  # <CJK>
diff --git a/basis/io/encodings/iso2022/authors.txt b/basis/io/encodings/iso2022/authors.txt
new file mode 100644 (file)
index 0000000..f990dd0
--- /dev/null
@@ -0,0 +1 @@
+Daniel Ehrenberg
diff --git a/basis/io/encodings/iso2022/iso2022-docs.factor b/basis/io/encodings/iso2022/iso2022-docs.factor
new file mode 100644 (file)
index 0000000..7e21dd6
--- /dev/null
@@ -0,0 +1,13 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.syntax help.markup ;
+IN: io.encodings.iso2022
+
+HELP: iso2022
+{ $class-description "This encoding class implements ISO 2022-JP-1, a Japanese text encoding commonly used for email." }
+{ $see-also "encodings-introduction" } ;
+
+ARTICLE: "io.encodings.iso2022" "ISO 2022-JP-1 encoding"
+{ $subsection iso2022 } ;
+
+ABOUT: "io.encodings.iso2022"
diff --git a/basis/io/encodings/iso2022/iso2022-tests.factor b/basis/io/encodings/iso2022/iso2022-tests.factor
new file mode 100644 (file)
index 0000000..9111eee
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.encodings.string io.encodings.iso2022 tools.test
+io.encodings.iso2022.private literals strings byte-arrays ;
+IN: io.encodings.iso2022
+
+[ "hello" ] [ "hello" >byte-array iso2022 decode ] unit-test
+[ "hello" ] [ "hello" iso2022 encode >string ] unit-test
+
+[ "hi" ] [ B{ CHAR: h ESC CHAR: ( CHAR: B CHAR: i } iso2022 decode ] unit-test
+[ "hi" ] [ B{ CHAR: h CHAR: i ESC CHAR: ( CHAR: B } iso2022 decode ] unit-test
+[ "hi\u00fffd" ] [ B{ CHAR: h CHAR: i ESC CHAR: ( } iso2022 decode ] unit-test
+[ "hi\u00fffd" ] [ B{ CHAR: h CHAR: i ESC } iso2022 decode ] unit-test
+
+[ B{ CHAR: h ESC CHAR: ( CHAR: J HEX: D8 } ] [ "h\u00ff98" iso2022 encode ] unit-test
+[ "h\u00ff98" ] [ B{ CHAR: h ESC CHAR: ( CHAR: J HEX: D8 } iso2022 decode ] unit-test
+[ "hi" ] [ B{ CHAR: h ESC CHAR: ( CHAR: J CHAR: i } iso2022 decode ] unit-test
+[ "h" ] [ B{ CHAR: h ESC CHAR: ( CHAR: J } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: ( CHAR: J HEX: 80 } iso2022 decode ] unit-test
+
+[ B{ CHAR: h ESC CHAR: $ CHAR: B HEX: 3E HEX: 47 } ] [ "h\u007126" iso2022 encode ] unit-test
+[ "h\u007126" ] [ B{ CHAR: h ESC CHAR: $ CHAR: B HEX: 3E HEX: 47 } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: $ CHAR: B HEX: 3E } iso2022 decode ] unit-test
+[ "h" ] [ B{ CHAR: h ESC CHAR: $ CHAR: B } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: $ } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: $ CHAR: B HEX: 80 HEX: 80 } iso2022 decode ] unit-test
+
+[ B{ CHAR: h ESC CHAR: $ CHAR: ( CHAR: D HEX: 38 HEX: 54 } ] [ "h\u0058ce" iso2022 encode ] unit-test
+[ "h\u0058ce" ] [ B{ CHAR: h ESC CHAR: $ CHAR: ( CHAR: D HEX: 38 HEX: 54 } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: $ CHAR: ( CHAR: D HEX: 38 } iso2022 decode ] unit-test
+[ "h" ] [ B{ CHAR: h ESC CHAR: $ CHAR: ( CHAR: D } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: $ CHAR: ( } iso2022 decode ] unit-test
+[ "h\u00fffd" ] [ B{ CHAR: h ESC CHAR: $ CHAR: ( CHAR: D HEX: 70 HEX: 70 } iso2022 decode ] unit-test
+
+[ "\u{syriac-music}" iso2022 encode ] must-fail
diff --git a/basis/io/encodings/iso2022/iso2022.factor b/basis/io/encodings/iso2022/iso2022.factor
new file mode 100644 (file)
index 0000000..a057df2
--- /dev/null
@@ -0,0 +1,107 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.encodings kernel sequences io simple-flat-file sets math
+combinators.short-circuit io.binary values arrays assocs
+locals accessors combinators biassocs byte-arrays parser ;
+IN: io.encodings.iso2022
+
+SINGLETON: iso2022
+
+<PRIVATE
+
+VALUE: jis201
+VALUE: jis208
+VALUE: jis212
+
+"vocab:io/encodings/iso2022/201.txt" flat-file>biassoc to: jis201
+"vocab:io/encodings/iso2022/208.txt" flat-file>biassoc to: jis208
+"vocab:io/encodings/iso2022/212.txt" flat-file>biassoc to: jis212
+
+VALUE: ascii
+128 unique >biassoc to: ascii
+
+TUPLE: iso2022-state type ;
+
+: make-iso-coder ( encoding -- state )
+    drop ascii iso2022-state boa ;
+
+M: iso2022 <encoder>
+    make-iso-coder <encoder> ;
+
+M: iso2022 <decoder>
+    make-iso-coder <decoder> ;
+
+<< SYNTAX: ESC HEX: 16 parsed ; >>
+
+CONSTANT: switch-ascii B{ ESC CHAR: ( CHAR: B }
+CONSTANT: switch-jis201 B{ ESC CHAR: ( CHAR: J }
+CONSTANT: switch-jis208 B{ ESC CHAR: $ CHAR: B }
+CONSTANT: switch-jis212 B{ ESC CHAR: $ CHAR: ( CHAR: D }
+
+: find-type ( char -- code type )
+    {
+        { [ dup ascii value? ] [ drop switch-ascii ascii ] }
+        { [ dup jis201 value? ] [ drop switch-jis201 jis201 ] }
+        { [ dup jis208 value? ] [ drop switch-jis208 jis208 ] }
+        { [ dup jis212 value? ] [ drop switch-jis212 jis212 ] }
+        [ encode-error ]
+    } cond ;
+
+: stream-write-num ( num stream -- )
+    over 256 >=
+    [ [ h>b/b swap 2byte-array ] dip stream-write ]
+    [ stream-write1 ] if ;
+
+M:: iso2022-state encode-char ( char stream encoding -- )
+    char encoding type>> value? [
+        char find-type
+        [ stream stream-write ]
+        [ encoding (>>type) ] bi*
+    ] unless
+    char encoding type>> value-at stream stream-write-num ;
+
+: read-escape ( stream -- type/f )
+    dup stream-read1 {
+        { CHAR: ( [
+            stream-read1 {
+                { CHAR: B [ ascii ] }
+                { CHAR: J [ jis201 ] }
+                [ drop f ]
+            } case
+        ] }
+        { CHAR: $ [
+            dup stream-read1 {
+                { CHAR: @ [ drop jis208 ] } ! want: JIS X 0208-1978 
+                { CHAR: B [ drop jis208 ] }
+                { CHAR: ( [
+                    stream-read1 CHAR: D = jis212 f ?
+                ] }
+                [ 2drop f ]
+            } case
+        ] }
+        [ 2drop f ]
+    } case ;
+
+: double-width? ( type -- ? )
+    { [ jis208 eq? ] [ jis212 eq? ] } 1|| ;
+
+: finish-decode ( num encoding -- char )
+    type>> at replacement-char or ;
+
+M:: iso2022-state decode-char ( stream encoding -- char )
+    stream stream-read1 {
+        { ESC [
+            stream read-escape [
+                encoding (>>type)
+                stream encoding decode-char
+            ] [ replacement-char ] if*
+        ] }
+        { f [ f ] }
+        [
+            encoding type>> double-width? [
+                stream stream-read1
+                [ 2byte-array be> encoding finish-decode ]
+                [ drop replacement-char ] if*
+            ] [ encoding finish-decode ] if
+        ]
+    } case ;
diff --git a/basis/io/encodings/iso2022/summary.txt b/basis/io/encodings/iso2022/summary.txt
new file mode 100644 (file)
index 0000000..a025a21
--- /dev/null
@@ -0,0 +1 @@
+ISO-2022-JP-1 text encoding
index b7edec2de7bb80517d5ad2d01e423e0bac6d328f..d93c5dd24edde37ed41bd970add584bda579603b 100644 (file)
@@ -3,6 +3,6 @@
 USING: help.syntax help.markup ;
 IN: io.encodings.strict
 
-HELP: strict ( encoding -- strict-encoding )
-{ $values { "encoding" "an encoding descriptor" } { "strict-encoding" "a strict encoding descriptor" } }
+HELP: strict ( code -- strict )
+{ $values { "code" "an encoding descriptor" } { "strict" "a strict encoding descriptor" } }
 { $description "Makes an encoding strict, that is, in the presence of a malformed code point, an error is thrown. Note that the existence of a replacement character in a file (U+FFFD) also throws an error." } ;
index 5e7d1af8f57622a5c35538a43c059f9978c535b4..9f3f35ff2a7136f01ab3256eee86f100e025d970 100644 (file)
@@ -2,7 +2,7 @@ USING: accessors alien.c-types kernel
 io.encodings.utf16 io.streams.byte-array tools.test ;
 IN: io.encodings.utf16n
 
-: correct-endian
+: correct-endian ( obj -- ? )
     code>> little-endian? [ utf16le = ] [ utf16be = ] if ;
 
 [ t ] [ B{ } utf16n <byte-reader> correct-endian ] unit-test
index b8a4431a73ba11724afbdd7171bb58964f863ef4..6a7be478130bcc7887d06ff4e80c8fdbe60bc8c2 100644 (file)
@@ -23,7 +23,7 @@ HELP: unique-retries
 
 { unique-length unique-retries } related-words
 
-HELP: make-unique-file ( prefix suffix -- path )
+HELP: make-unique-file
 { $values { "prefix" "a string" } { "suffix" "a string" }
 { "path" "a pathname string" } }
 { $description "Creates a file that is guaranteed not to exist in the directory stored in " { $link current-temporary-directory } ". The file name is composed of a prefix, a number of random digits and letters, and the suffix. Returns the full pathname." }
@@ -31,18 +31,18 @@ HELP: make-unique-file ( prefix suffix -- path )
 
 { unique-file make-unique-file cleanup-unique-file } related-words
 
-HELP: cleanup-unique-file ( prefix suffix quot: ( path -- ) -- )
+HELP: cleanup-unique-file
 { $values { "prefix" "a string" } { "suffix" "a string" }
 { "quot" "a quotation" } }
 { $description "Creates a file with " { $link make-unique-file } " and calls the quotation with the path name on the stack." }
 { $notes "The unique file will be deleted after calling this word." } ;
 
-HELP: unique-directory ( -- path )
+HELP: unique-directory
 { $values { "path" "a pathname string" } }
 { $description "Creates a directory in the value in " { $link current-temporary-directory } " that is guaranteed not to exist in and returns the full pathname." }
 { $errors "Throws an error if the directory cannot be created after a number of tries. The most likely error is incorrect directory permissions on the temporary directory." } ;
 
-HELP: cleanup-unique-directory ( quot -- )
+HELP: cleanup-unique-directory
 { $values { "quot" "a quotation" } }
 { $description "Creates a directory with " { $link unique-directory } " and calls the quotation with the pathname on the stack using the " { $link with-temporary-directory } " combinator. The quotation can access the " { $link current-temporary-directory } " symbol for the name of the temporary directory. Subsequent unique files will be created in this unique directory until the combinator returns." }
 { $notes "The directory will be deleted after calling this word, even if an error is thrown in the quotation. This combinator is like " { $link with-unique-directory } " but does not delete the directory." } ;
@@ -62,8 +62,8 @@ HELP: current-temporary-directory
 
 HELP: unique-file
 { $values
+     { "prefix" string }
      { "path" "a pathname string" }
-     { "path'" "a pathname string" }
 }
 { $description "Creates a temporary file in the directory stored in " { $link current-temporary-directory } " and outputs the path name." } ;
 
index 7bd96aa63b4a10a1b7cf2f850ef6c34a5586d9a0..0e4338e3e0415d37a530e5a3d74da5c2de9e477d 100644 (file)
@@ -64,7 +64,7 @@ PRIVATE>
     [ unique-directory ] dip
     '[ _ with-temporary-directory ] [ delete-tree ] bi ; inline
 
-: unique-file ( path -- path' )
+: unique-file ( prefix -- path )
     "" make-unique-file ;
 
 {
index 9cadb3f6cc2b6df7eb3917e5f27b348b363b0617..c15663b0319c714e5ebaa09552b37d1f1a3a2f8c 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.encodings io.backend io.ports io.streams.duplex
 io splitting grouping sequences namespaces kernel
-destructors math concurrency.combinators accessors
+destructors math concurrency.combinators accessors fry
 arrays continuations quotations system vocabs.loader combinators ;
 IN: io.pipes
 
@@ -29,11 +29,12 @@ HOOK: (pipe) io-backend ( -- pipe )
 : ?writer ( handle/f -- stream )
     [ <output-port> &dispose ] [ output-stream get ] if* ;
 
-GENERIC: run-pipeline-element ( input-fd output-fd obj -- quot )
+GENERIC: run-pipeline-element ( input-fd output-fd obj -- result )
 
 M: callable run-pipeline-element
     [
-        [ [ ?reader ] [ ?writer ] bi* ] dip with-streams*
+        [ [ ?reader ] [ ?writer ] bi* ] dip
+        '[ _ call( -- result ) ] with-streams*
     ] with-destructors ;
 
 : <pipes> ( n -- pipes )
index 1a58d4200be8fdcd02ca50ef70b66fc341d0ed59..569366d4b8cad9c378880ddf3eb2d2032495326d 100644 (file)
@@ -27,6 +27,8 @@ TUPLE: buffered-port < port { buffer buffer } ;
 
 TUPLE: input-port < buffered-port ;
 
+M: input-port stream-element-type drop +byte+ ;
+
 : <input-port> ( handle -- input-port )
     input-port <buffered-port> ;
 
@@ -102,6 +104,8 @@ TUPLE: output-port < buffered-port ;
     [ nip ] [ buffer>> buffer-capacity <= ] 2bi
     [ drop ] [ stream-flush ] if ; inline
 
+M: output-port stream-element-type stream>> stream-element-type ;
+
 M: output-port stream-write1
     dup check-disposed
     1 over wait-to-write
index 589a50d2ebf58063d4e25f1813150fdf766ea77f..8eafe1b5bf24a6f0e63330f556f771ce2be4f64f 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2003, 2008 Slava Pestov.
+! Copyright (C) 2003, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations destructors kernel math math.parser
 namespaces parser sequences strings prettyprint
@@ -69,7 +69,7 @@ GENERIC: handle-client* ( threaded-server -- )
     [ [ remote-address set ] [ local-address set ] bi* ]
     2bi ;
 
-M: threaded-server handle-client* handler>> call ;
+M: threaded-server handle-client* handler>> call( -- ) ;
 
 : handle-client ( client remote local -- )
     '[
index 10df82ae7bf28ee8b4ad186219fae9a56eb61d98..9481a7c1a8924d87d13c9c4ae5749578dc131537 100644 (file)
@@ -1,11 +1,14 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors io.sockets.secure kernel ;
 IN: io.sockets.secure.unix.debug
 
-: with-test-context ( quot -- )
+: <test-secure-config> ( -- config )
     <secure-config>
         "vocab:openssl/test/server.pem" >>key-file
         "vocab:openssl/test/dh1024.pem" >>dh-file
-        "password" >>password
+        "password" >>password ;
+
+: with-test-context ( quot -- )
+    <test-secure-config>
     swap with-secure-context ; inline
index 77a912674044479af6fe2f0018e1c5e8b94c137e..44290bfb47266c8c4ac3f7961f30ad5c31670e56 100644 (file)
@@ -1,5 +1,5 @@
 USING: tools.test io.streams.byte-array io.encodings.binary
-io.encodings.utf8 io kernel arrays strings ;
+io.encodings.utf8 io kernel arrays strings namespaces ;
 
 [ B{ 1 2 3 } ] [ binary [ { 1 2 3 } write ] with-byte-writer ] unit-test
 [ B{ 1 2 3 } ] [ { 1 2 3 } binary [ 3 read ] with-byte-reader ] unit-test
@@ -7,3 +7,23 @@ io.encodings.utf8 io kernel arrays strings ;
 [ B{ BIN: 11110101 BIN: 10111111 BIN: 10000000 BIN: 10111111 BIN: 11101111 BIN: 10000000 BIN: 10111111 BIN: 11011111 BIN: 10000000 CHAR: x } ]
 [ { BIN: 101111111000000111111 BIN: 1111000000111111 BIN: 11111000000 CHAR: x } utf8 [ write ] with-byte-writer ] unit-test
 [ { BIN: 101111111000000111111 } t ] [ { BIN: 11110101 BIN: 10111111 BIN: 10000000 BIN: 10111111 } utf8 <byte-reader> contents dup >array swap string? ] unit-test
+
+[ B{ 121 120 } 0 ] [
+    B{ 0 121 120 0 0 0 0 0 0 } binary
+    [ 1 read drop "\0" read-until ] with-byte-reader
+] unit-test
+
+[ 1 1 4 11 f ] [
+    B{ 1 2 3 4 5 6 7 8 9 10 11 12 } binary
+    [
+        read1
+        0 seek-absolute input-stream get stream-seek
+        read1
+        2 seek-relative input-stream get stream-seek
+        read1
+        -2 seek-end input-stream get stream-seek
+        read1
+        0 seek-end input-stream get stream-seek
+        read1
+    ] with-byte-reader
+] unit-test
\ No newline at end of file
index 16160cd42d7584b853a01691959e4b8a14c3423c..2ffb9b9a63cf10677f849bdc7b28585c4680b56d 100644 (file)
@@ -5,6 +5,8 @@ sequences io namespaces io.encodings.private accessors sequences.private
 io.streams.sequence destructors math combinators ;
 IN: io.streams.byte-array
 
+M: byte-vector stream-element-type drop +byte+ ;
+
 : <byte-writer> ( encoding -- stream )
     512 <byte-vector> swap <encoder> ;
 
@@ -14,6 +16,8 @@ IN: io.streams.byte-array
 
 TUPLE: byte-reader { underlying byte-array read-only } { i array-capacity } ;
 
+M: byte-reader stream-element-type drop +byte+ ;
+
 M: byte-reader stream-read-partial stream-read ;
 M: byte-reader stream-read sequence-read ;
 M: byte-reader stream-read1 sequence-read1 ;
@@ -24,7 +28,7 @@ M: byte-reader stream-seek ( n seek-type stream -- )
     swap {
         { seek-absolute [ (>>i) ] }
         { seek-relative [ [ + ] change-i drop ] }
-        { seek-end [ dup underlying>> length >>i [ + ] change-i drop ] }
+        { seek-end [ [ underlying>> length + ] keep (>>i) ] }
         [ bad-seek-type ]
     } case ;
 
index 860702c5635b50853db0b34f7d30a7f40a4aef8a..4903db2b1b79615c695cab06035ea0ef70250f13 100644 (file)
@@ -5,13 +5,13 @@ IN: io.streams.duplex.tests
 ! Test duplex stream close behavior
 TUPLE: closing-stream < disposable ;
 
-: <closing-stream> closing-stream new ;
+: <closing-stream> ( -- stream ) closing-stream new ;
 
 M: closing-stream dispose* drop ;
 
 TUPLE: unclosable-stream ;
 
-: <unclosable-stream> unclosable-stream new ;
+: <unclosable-stream> ( -- stream ) unclosable-stream new ;
 
 M: unclosable-stream dispose
     "Can't close me!" throw ;
index 2eb5cc602a7e87e7513d34fe3b3ec1f555d9b411..4903195abcc0e454307e3e417996178695a8b989 100644 (file)
@@ -15,6 +15,11 @@ CONSULT: formatted-output-stream-protocol duplex-stream out>> ;
 
 : >duplex-stream< ( stream -- in out ) [ in>> ] [ out>> ] bi ; inline
 
+M: duplex-stream stream-element-type
+    [ in>> ] [ out>> ] bi
+    [ stream-element-type ] bi@
+    2dup eq? [ drop ] [ "Cannot determine element type" throw ] if ;
+
 M: duplex-stream set-timeout
     >duplex-stream< [ set-timeout ] bi-curry@ bi ;
 
index fac1232cc0280c1a8bd4d740eecf7a708b0a1526..130c7ba3a942148db9014970eeefe0b931b582f9 100755 (executable)
@@ -5,14 +5,14 @@ IN: io.streams.limited
 
 HELP: <limited-stream>
 { $values
-     { "stream" "an input stream" } { "limit" integer } { "mode" "a " { $link limited-stream } " mode singleton" }
+     { "stream" "an input stream" } { "limit" integer } { "mode" { $link stream-throws } " or " { $link stream-eofs } }
      { "stream'" "an input stream" }
 }
 { $description "Constructs a new " { $link limited-stream } " from an existing stream. User code should use " { $link limit } " or " { $link limit-input } "." } ;
 
 HELP: limit
 { $values
-     { "stream" "an input stream" } { "limit" integer } { "mode" "a " { $link limited-stream } " mode singleton" }
+     { "stream" "an input stream" } { "limit" integer } { "mode" { $link stream-throws } " or " { $link stream-eofs } }
      { "stream'" "a stream" }
 }
 { $description "Changes a decoder's stream to be a limited stream, or wraps " { $snippet "stream" } " in a " { $link limited-stream } "." }
@@ -36,7 +36,7 @@ HELP: limit
     }
 } ;
 
-HELP: unlimit
+HELP: unlimited
 { $values
      { "stream" "an input stream" }
      { "stream'" "a stream" }
@@ -51,22 +51,22 @@ HELP: limited-stream
 
 HELP: limit-input
 { $values
-     { "limit" integer } { "mode" "a " { $link limited-stream } " mode singleton" }
+     { "limit" integer } { "mode" { $link stream-throws } " or " { $link stream-eofs } }
 }
 { $description "Wraps the current " { $link input-stream } " in a " { $link limited-stream } "." } ;
 
-HELP: unlimit-input
+HELP: unlimited-input
 { $description "Returns the underlying stream of the limited-stream stored in " { $link input-stream } "." } ;
 
 HELP: stream-eofs
 { $values
-    { "value" "a " { $link limited-stream } " mode singleton" }
+    { "value" { $link stream-throws } " or " { $link stream-eofs } }
 }
 { $description "If the " { $slot "mode" } " of a limited stream is set to this singleton, the stream will return " { $link f } " upon exhaustion." } ;
 
 HELP: stream-throws
 { $values
-    { "value" "a " { $link limited-stream } " mode singleton" }
+    { "value" { $link stream-throws } " or " { $link stream-eofs } }
 }
 { $description "If the " { $slot "mode" } " of a limited stream is set to this singleton, the stream will throw " { $link limit-exceeded } " upon exhaustion." } ;
 
@@ -79,9 +79,9 @@ ARTICLE: "io.streams.limited" "Limited input streams"
 "Wrap the current " { $link input-stream } " in a limited stream:"
 { $subsection limit-input }
 "Unlimits a limited stream:"
-{ $subsection unlimit }
+{ $subsection unlimited }
 "Unlimits the current " { $link input-stream } ":"
-{ $subsection unlimit-input }
+{ $subsection unlimited-input }
 "Make a limited stream throw an exception on exhaustion:"
 { $subsection stream-throws }
 "Make a limited stream return " { $link f } " on exhaustion:"
index feddc130e933d228a96581e1974a773a0d0dd051..86d652d17c52e5d438e8ce7bfb929455ace4498d 100644 (file)
@@ -57,13 +57,13 @@ IN: io.streams.limited.tests
 
 [ t ]
 [
-    "abc" <string-reader> 3 stream-eofs limit unlimit
+    "abc" <string-reader> 3 stream-eofs limit unlimited
     "abc" <string-reader> =
 ] unit-test
 
 [ t ]
 [
-    "abc" <string-reader> 3 stream-eofs limit unlimit
+    "abc" <string-reader> 3 stream-eofs limit unlimited
     "abc" <string-reader> =
 ] unit-test
 
@@ -71,8 +71,14 @@ IN: io.streams.limited.tests
 [
     [
         "resource:license.txt" utf8 <file-reader> &dispose
-        3 stream-eofs limit unlimit
+        3 stream-eofs limit unlimited
         "resource:license.txt" utf8 <file-reader> &dispose
         [ decoder? ] both?
     ] with-destructors
 ] unit-test
+
+[ "HELL" ] [
+    "HELLO"
+    [ f stream-throws limit-input 4 read ]
+    with-string-reader
+] unit-test
\ No newline at end of file
index 1237b3aba293d128295ca0afc5865b7ba1afc1c0..b1b07a08c07c2c288d658f906c7547b07664d532 100755 (executable)
@@ -22,22 +22,24 @@ M: decoder limit ( stream limit mode -- stream' )
     [ clone ] 2dip '[ _ _ limit ] change-stream ;
 
 M: object limit ( stream limit mode -- stream' )
-    <limited-stream> ;
+    over [ <limited-stream> ] [ 2drop ] if ;
 
-GENERIC: unlimit ( stream -- stream' )
+GENERIC: unlimited ( stream -- stream' )
 
-M: decoder unlimit ( stream -- stream' )
+M: decoder unlimited ( stream -- stream' )
     [ stream>> ] change-stream ;
 
-M: object unlimit ( stream -- stream' )
+M: object unlimited ( stream -- stream' )
     stream>> stream>> ;
 
-: limit-input ( limit mode -- ) input-stream [ -rot limit ] change ;
+: limit-input ( limit mode -- )
+    [ input-stream ] 2dip '[ _ _ limit ] change ;
 
-: unlimit-input ( -- ) input-stream [ unlimit ] change ;
+: unlimited-input ( -- )
+    input-stream [ unlimited ] change ;
 
 : with-unlimited-stream ( stream quot -- )
-    [ clone unlimit ] dip call ; inline
+    [ clone unlimited ] dip call ; inline
 
 : with-limited-stream ( stream limit mode quot -- )
     [ limit ] dip call ; inline
index 20d9f4eb0c45e58c9edf7ef3687dc9a15941b592..52169de6f8651ef186239721d5fa73cda0946997 100644 (file)
@@ -8,6 +8,8 @@ TUPLE: memory-stream alien index ;
 : <memory-stream> ( alien -- stream )
     0 memory-stream boa ;
 
+M: memory-stream stream-element-type drop +byte+ ;
+
 M: memory-stream stream-read1
     [ [ alien>> ] [ index>> ] bi alien-unsigned-1 ]
     [ [ 1+ ] change-index drop ] bi ;
index 73bf5f5efe4204152709866b135622fbef11c29e..a0087a70ee26b16a2a02a3a7284be0467285294b 100644 (file)
@@ -5,41 +5,33 @@ strings generic splitting continuations destructors sequences.private
 io.streams.plain io.encodings math.order growable io.streams.sequence ;
 IN: io.streams.string
 
-<PRIVATE
-
-SINGLETON: null-encoding
-
-M: null-encoding decode-char drop stream-read1 ;
-
-PRIVATE>
-
-M: growable dispose drop ;
-
-M: growable stream-write1 push ;
-M: growable stream-write push-all ;
-M: growable stream-flush drop ;
-
-: <string-writer> ( -- stream )
-    512 <sbuf> ;
-
-: with-string-writer ( quot -- str )
-    <string-writer> swap [ output-stream get ] compose with-output-stream*
-    >string ; inline
-
-! New implementation
-
+! Readers
 TUPLE: string-reader { underlying string read-only } { i array-capacity } ;
 
+M: string-reader stream-element-type drop +character+ ;
 M: string-reader stream-read-partial stream-read ;
 M: string-reader stream-read sequence-read ;
 M: string-reader stream-read1 sequence-read1 ;
 M: string-reader stream-read-until sequence-read-until ;
 M: string-reader dispose drop ;
 
+<PRIVATE
+SINGLETON: null-encoding
+M: null-encoding decode-char drop stream-read1 ;
+PRIVATE>
+
 : <string-reader> ( str -- stream )
     0 string-reader boa null-encoding <decoder> ;
 
 : with-string-reader ( str quot -- )
     [ <string-reader> ] dip with-input-stream ; inline
 
-INSTANCE: growable plain-writer
+! Writers
+M: sbuf stream-element-type drop +character+ ;
+
+: <string-writer> ( -- stream )
+    512 <sbuf> ;
+
+: with-string-writer ( quot -- str )
+    <string-writer> swap [ output-stream get ] compose with-output-stream*
+    >string ; inline
\ No newline at end of file
index 55dc6ca9a4dbeb70503aa6297ba9e3664928271e..89fe90b5685b938437d3b7995021632618415356 100644 (file)
@@ -48,6 +48,8 @@ CONSULT: output-stream-protocol filter-writer stream>> ;
 
 CONSULT: formatted-output-stream-protocol filter-writer stream>> ;
 
+M: filter-writer stream-element-type stream>> stream-element-type ;
+
 M: filter-writer dispose stream>> dispose ;
 
 TUPLE: ignore-close-stream < filter-writer ;
index 61aa3239245824e73b0735f4defc59a8981ffe03..0616794939ee6a405eaa3fd1c5db3638dff6dbc8 100644 (file)
@@ -3,7 +3,7 @@ tools.test parser math namespaces continuations vocabs kernel
 compiler.units eval vocabs.parser ;
 IN: listener.tests
 
-: hello "Hi" print ; parsing
+SYNTAX: hello "Hi" print ;
 
 : parse-interactive ( string -- quot )
     <string-reader> stream-read-quot ;
@@ -50,7 +50,7 @@ IN: listener.tests
 
 [
     [ ] [
-        "IN: listener.tests : hello\n\"world\" ;" parse-interactive
+        "IN: listener.tests : hello ( -- )\n\"world\" ;" parse-interactive
         drop
     ] unit-test
 ] with-file-vocabs
index 78a9c03d205d2f401511bc986220dffbc044f215..4f7ccf227e54e12567e6e4d7f47916fa123278d5 100644 (file)
@@ -4,7 +4,7 @@ USING: arrays hashtables io kernel math math.parser memory
 namespaces parser lexer sequences strings io.styles
 vectors words generic system combinators continuations debugger
 definitions compiler.units accessors colors prettyprint fry
-sets vocabs.parser call ;
+sets vocabs.parser ;
 IN: listener
 
 GENERIC: stream-read-quot ( stream -- quot/f )
index 08fe3bbcba543fa711a487739daa45b7c5cd9380..c46d3251a94f34ee201cc594a0ed1bd8c80e3070 100644 (file)
@@ -108,7 +108,7 @@ HELP: lappend
 { $description "Perform a similar functionality to that of the " { $link append } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link <lazy-append> } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required. Successive calls to " { $link cdr } " will iterate through list1, followed by list2." } ;
 
 HELP: lfrom-by
-{ $values { "n" "an integer" } { "quot" { $quotation "( -- int )" } } { "list" "a lazy list of integers" } }
+{ $values { "n" "an integer" } { "quot" { $quotation "( -- int )" } } { "lazy-from-by" "a lazy list of integers" } }
 { $description "Return an infinite lazy list of values starting from n, with each successive value being the result of applying quot to n." } ;
 
 HELP: lfrom
index d3b08a11fb9e16440b3462c20bfe8823df4e907f..64a3f099a0ed5056ecfe327aa3482fa38dc4e905 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2004, 2008 Chris Double, Matthew Willis, James Cash.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences math vectors arrays namespaces make
-quotations promises combinators io lists accessors call ;
+quotations promises combinators io lists accessors ;
 IN: lists.lazy
 
 M: promise car ( promise -- car )
@@ -203,7 +203,7 @@ M: lazy-append nil? ( lazy-append -- bool )
 
 TUPLE: lazy-from-by n quot ;
 
-C: lfrom-by lazy-from-by ( n quot -- list )
+C: lfrom-by lazy-from-by
 
 : lfrom ( n -- list )
     [ 1+ ] lfrom-by ;
index 8494d7c3522cd8e290aeaf084a6f06f90f98d4f1..8782c3d9b4082d4026140a1a2128ce005eb2d115 100644 (file)
@@ -21,7 +21,7 @@ ARTICLE: { "lists" "protocol" } "The list protocol"
 { $subsection cdr }
 { $subsection nil? } ;
 
-ARTICLE: { "lists" "strict" } "Strict lists"
+ARTICLE: { "lists" "strict" } "Constructing strict lists"
 "Strict lists are simply cons cells where the car and cdr have already been evaluated. These are the lists of Lisp. To construct a strict list, the following words are provided:"
 { $subsection cons }
 { $subsection swons }
@@ -83,10 +83,6 @@ HELP: nil?
 
 { nil nil? } related-words
 
-HELP: list? ( object -- ? )
-{ $values { "object" "an object" } { "?" "a boolean" } }
-{ $description "Returns true if the object conforms to the list protocol." } ;
-
 { 1list 2list 3list } related-words
 
 HELP: 1list
index 18dabed4b039518e3b559e65273560a28b2b124c..b1f0b6ca1732b3d59b6092d32b665c1d04d08ea2 100644 (file)
@@ -112,7 +112,15 @@ HELP: MEMO::
 { $description "Defines a memoized word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." } ;
 
 { POSTPONE: MEMO: POSTPONE: MEMO:: } related-words
+                                          
+HELP: M::
+{ $syntax "M:: class generic ( bindings... -- outputs... ) body... ;" }
+{ $description "Defines a method with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." }
+{ $notes "The output names do not affect the word's behavior, however the compiler attempts to check the stack effect as with other definitions." } ;
+
+{ POSTPONE: M: POSTPONE: M:: } related-words
 
+                                                 
 ARTICLE: "locals-literals" "Locals in literals"
 "Certain data type literals are permitted to contain free variables. Any such literals are written into code which constructs an instance of the type with the free variable values spliced in. Conceptually, this is similar to the transformation applied to quotations containing free variables."
 $nl
@@ -237,13 +245,14 @@ $nl
 }
 "The reason is that locals are rewritten into stack code at parse time, whereas macro expansion is performed later during compile time. To circumvent this problem, the " { $vocab-link "macros.expander" } " vocabulary is used to rewrite simple macro usages prior to local transformation, however "{ $vocab-link "macros.expander" } " does not deal with more complicated cases where the literal inputs to the macro do not immediately precede the macro call in the source." ;
 
-ARTICLE: "locals" "Local variables and lexical closures"
+ARTICLE: "locals" "Lexical variables and closures"
 "The " { $vocab-link "locals" } " vocabulary implements lexical scope with full closures, both downward and upward. Mutable bindings are supported, including assignment to bindings in outer scope."
 $nl
 "Compile-time transformation is used to compile local variables to efficient code; prettyprinter extensions are defined so that " { $link see } " can display original word definitions with local variables and not the closure-converted concatenative code which results."
 $nl
 "Applicative word definitions where the inputs are named local variables:"
 { $subsection POSTPONE: :: }
+{ $subsection POSTPONE: M:: }
 { $subsection POSTPONE: MEMO:: }
 { $subsection POSTPONE: MACRO:: }
 "Lexical binding forms:"
index 558fa78494bd1eb34143bc614092d78b54792955..5e61c1ddfd45f0b881417557dcf7e9326d9547b4 100644 (file)
@@ -2,7 +2,7 @@ USING: locals math sequences tools.test hashtables words kernel
 namespaces arrays strings prettyprint io.streams.string parser
 accessors generic eval combinators combinators.short-circuit
 combinators.short-circuit.smart math.order math.functions
-definitions compiler.units fry lexer words.symbol see ;
+definitions compiler.units fry lexer words.symbol see multiline ;
 IN: locals.tests
 
 :: foo ( a b -- a a ) a a ;
@@ -192,14 +192,14 @@ M:: string lambda-generic ( a b -- c ) a b lambda-generic-2 ;
 DEFER: xyzzy
 
 [ ] [
-    "IN: locals.tests USE: math GENERIC: xyzzy M: integer xyzzy ;"
+    "IN: locals.tests USE: math GENERIC: xyzzy ( a -- b ) M: integer xyzzy ;"
     <string-reader> "lambda-generic-test" parse-stream drop
 ] unit-test
 
 [ 10 ] [ 10 xyzzy ] unit-test
 
 [ ] [
-    "IN: locals.tests USE: math USE: locals GENERIC: xyzzy M:: integer xyzzy ( n -- ) 5 ;"
+    "IN: locals.tests USE: math USE: locals GENERIC: xyzzy ( a -- b ) M:: integer xyzzy ( n -- x ) 5 ;"
     <string-reader> "lambda-generic-test" parse-stream drop
 ] unit-test
 
@@ -245,7 +245,7 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ;
 
 [ 5 ] [ 1 next-method-test ] unit-test
 
-: no-with-locals-test { 1 2 3 } [| x | x 3 + ] map ;
+: no-with-locals-test ( -- seq ) { 1 2 3 } [| x | x 3 + ] map ;
 
 [ { 4 5 6 } ] [ no-with-locals-test ] unit-test
 
@@ -259,7 +259,7 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ;
 
 :: a-word-with-locals ( a b -- ) ;
 
-: new-definition "USING: math ;\nIN: locals.tests\n: a-word-with-locals ( -- x ) 2 3 + ;\n" ;
+CONSTANT: new-definition "USING: math ;\nIN: locals.tests\n: a-word-with-locals ( -- x ) 2 3 + ;\n"
 
 [ ] [ new-definition eval ] unit-test
 
@@ -268,7 +268,7 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ;
     new-definition =
 ] unit-test
 
-: method-definition "USING: locals locals.tests sequences ;\nM:: sequence method-with-locals ( a -- y ) a reverse ;\n" ;
+CONSTANT: method-definition "USING: locals locals.tests sequences ;\nM:: sequence method-with-locals ( a -- y ) a reverse ;\n"
 
 GENERIC: method-with-locals ( x -- y )
 
@@ -392,11 +392,70 @@ ERROR: punned-class x ;
 
 [ 9 ] [ 3 big-case-test ] unit-test
 
+! Dan found this problem
+: littledan-case-problem-1 ( a -- b )
+    {
+        { t [ 3 ] }
+        { f [ 4 ] }
+        [| x | x 12 + { "howdy" } nth ]
+    } case ;
+
+\ littledan-case-problem-1 must-infer
+
+[ "howdy" ] [ -12 \ littledan-case-problem-1 def>> call ] unit-test
+[ "howdy" ] [ -12 littledan-case-problem-1 ] unit-test
+
+:: littledan-case-problem-2 ( a -- b )
+    a {
+        { t [ a not ] }
+        { f [ 4 ] }
+        [| x | x a - { "howdy" } nth ]
+    } case ;
+
+\ littledan-case-problem-2 must-infer
+
+[ "howdy" ] [ -12 \ littledan-case-problem-2 def>> call ] unit-test
+[ "howdy" ] [ -12 littledan-case-problem-2 ] unit-test
+
+:: littledan-cond-problem-1 ( a -- b )
+    a {
+        { [ dup 0 < ] [ drop a not ] }
+        { [| y | y y 0 > ] [ drop 4 ] }
+        [| x | x a - { "howdy" } nth ]
+    } cond ;
+
+\ littledan-cond-problem-1 must-infer
+
+[ f ] [ -12 \ littledan-cond-problem-1 def>> call ] unit-test
+[ 4 ] [ 12 \ littledan-cond-problem-1 def>> call ] unit-test
+[ "howdy" ] [ 0 \ littledan-cond-problem-1 def>> call ] unit-test
+[ f ] [ -12 littledan-cond-problem-1 ] unit-test
+[ 4 ] [ 12 littledan-cond-problem-1 ] unit-test
+[ "howdy" ] [ 0 littledan-cond-problem-1 ] unit-test
+
+/*
+:: littledan-case-problem-3 ( a quot -- b )
+    a {
+        { t [ a not ] }
+        { f [ 4 ] }
+        quot
+    } case ; inline
+
+[ f ] [ t [ ] littledan-case-problem-3 ] unit-test
+[ 144 ] [ 12 [ sq ] littledan-case-problem-3 ] unit-test
+[| | [| a | a ] littledan-case-problem-3 ] must-infer
+
+: littledan-case-problem-4 ( a -- b )
+    [ 1 + ] littledan-case-problem-3 ;
+
+\ littledan-case-problem-4 must-infer
+*/
+
 GENERIC: lambda-method-forget-test ( a -- b )
 
 M:: integer lambda-method-forget-test ( a -- b ) ;
 
-[ ] [ [ { integer lambda-method-forget-test } forget ] with-compilation-unit ] unit-test
+[ ] [ [ M\ integer lambda-method-forget-test forget ] with-compilation-unit ] unit-test
 
 [ 10 ] [ 10 [| A | { [ A ] } ] call first call ] unit-test
 
index 190be61e23c2b59eb6aafef775de7e7534035cf9..9e26a8caaa413c143e06563021286e57412b58de 100644 (file)
@@ -1,31 +1,29 @@
-! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
+! Copyright (C) 2007, 2009 Slava Pestov, Eduardo Cavazos.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: lexer macros memoize parser sequences vocabs
 vocabs.loader words kernel namespaces locals.parser locals.types
 locals.errors ;
 IN: locals
 
-: :>
+SYNTAX: :>
     scan locals get [ :>-outside-lambda-error ] unless*
-    [ make-local ] bind <def> parsed ; parsing
+    [ make-local ] bind <def> parsed ;
 
-: [| parse-lambda over push-all ; parsing
+SYNTAX: [| parse-lambda over push-all ;
 
-: [let parse-let over push-all ; parsing
+SYNTAX: [let parse-let over push-all ;
 
-: [let* parse-let* over push-all ; parsing
+SYNTAX: [let* parse-let* over push-all ;
 
-: [wlet parse-wlet over push-all ; parsing
+SYNTAX: [wlet parse-wlet over push-all ;
 
-: :: (::) define ; parsing
+SYNTAX: :: (::) define-declared ;
 
-: M:: (M::) define ; parsing
+SYNTAX: M:: (M::) define ;
 
-: MACRO:: (::) define-macro ; parsing
+SYNTAX: MACRO:: (::) define-macro ;
 
-: MEMO:: (::) define-memoized ; parsing
-
-USE: syntax
+SYNTAX: MEMO:: (::) define-memoized ;
 
 {
     "locals.macros"
index 7bde67a7922f6c96b579fc232d5846e63819a8d9..2b52c53eb5a792eebdbc4d4a4b225c41729b0052 100644 (file)
@@ -1,6 +1,6 @@
-! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
+! Copyright (C) 2007, 2009 Slava Pestov, Eduardo Cavazos.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs kernel locals.types macros.expander ;
+USING: accessors assocs kernel locals.types macros.expander fry ;
 IN: locals.macros
 
 M: lambda expand-macros clone [ expand-macros ] change-body ;
@@ -14,3 +14,6 @@ M: binding-form expand-macros
 
 M: binding-form expand-macros* expand-macros literal ;
 
+M: lambda condomize? drop t ;
+
+M: lambda condomize '[ @ ] ;
\ No newline at end of file
index d987e2c91d42831447ecab0a0d7b39571768246d..5e9bdfbed6620286d98de669903471bc4d5d2b99 100644 (file)
@@ -103,18 +103,19 @@ M: lambda-parser parse-quotation ( -- quotation )
     "|" expect "|" parse-wbindings
     (parse-lambda) <wlet> ?rewrite-closures ;
 
-: parse-locals ( -- vars assoc )
-    "(" expect ")" parse-effect
-    word [ over "declared-effect" set-word-prop ] when*
+: parse-locals ( -- effect vars assoc )
+    complete-effect
+    dup
     in>> [ dup pair? [ first ] when ] map make-locals ;
 
-: parse-locals-definition ( word reader -- word quot )
+: parse-locals-definition ( word reader -- word quot effect )
     [ parse-locals ] dip
     ((parse-lambda)) <lambda>
-    [ "lambda" set-word-prop ]
-    [ rewrite-closures dup length 1 = [ first ] [ bad-rewrite ] if ] 2bi ; inline
+    [ nip "lambda" set-word-prop ]
+    [ nip rewrite-closures dup length 1 = [ first ] [ bad-rewrite ] if ]
+    [ drop nip ] 3tri ; inline
 
-: (::) ( -- word def )
+: (::) ( -- word def effect )
     CREATE-WORD
     [ parse-definition ]
     parse-locals-definition ;
@@ -123,5 +124,5 @@ M: lambda-parser parse-quotation ( -- quotation )
     CREATE-METHOD
     [
         [ parse-definition ] 
-        parse-locals-definition
+        parse-locals-definition drop
     ] with-method-definition ;
\ No newline at end of file
index 24810a6c3e0a574b73ce0886e80b64d2acd24c56..0ba98996b3b0099bfdec6541d8f60b9e95947ff6 100644 (file)
@@ -41,7 +41,7 @@ SYMBOL: message-histogram
         [ >alist sort-values <reversed> ] dip [\r
             [ swapd with-cell pprint-cell ] with-row\r
         ] curry assoc-each\r
-    ] tabular-output ;\r
+    ] tabular-output ; inline\r
 \r
 : log-entry. ( entry -- )\r
     "====== " write\r
index e295960baa81f219866017f2e44022624f72dc6a..c8179108ef12d359c2958bd413c5b68c164b09ff 100644 (file)
@@ -80,7 +80,7 @@ ERROR: bad-log-message-parameters msg word level ;
 PRIVATE>\r
 \r
 : (define-logging) ( word level quot -- )\r
-    [ dup ] 2dip 2curry annotate ;\r
+    [ dup ] 2dip 2curry annotate ; inline\r
 \r
 : call-logging-quot ( quot word level -- quot' )\r
     [ "called" ] 2dip [ log-message ] 3curry prepose ;\r
@@ -135,11 +135,11 @@ PRIVATE>
     [ [ input-logging-quot ] 2keep drop error-logging-quot ]\r
     (define-logging) ;\r
 \r
-: LOG:\r
+SYNTAX: LOG:\r
     #! Syntax: name level\r
     CREATE-WORD dup scan-word\r
     '[ 1array stack>message _ _ log-message ]\r
-    (( message -- )) define-declared ; parsing\r
+    (( message -- )) define-declared ;\r
 \r
 USE: vocabs.loader\r
 \r
index cdd2b49d9cd656f738835b3dd66466959f498d89..25f754e92af46ca874d2ed42f67f13d978cac1cf 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences sequences.private namespaces make
 quotations accessors words continuations vectors effects math
-generalizations fry ;
+generalizations fry arrays ;
 IN: macros.expander
 
 GENERIC: expand-macros ( quot -- quot' )
@@ -17,7 +17,23 @@ SYMBOL: stack
     [ delete-all ]
     bi ;
 
-: literal ( obj -- ) stack get push ;
+GENERIC: condomize? ( obj -- ? )
+
+M: array condomize? [ condomize? ] any? ;
+
+M: callable condomize? [ condomize? ] any? ;
+
+M: object condomize? drop f ;
+
+GENERIC: condomize ( obj -- obj' )
+
+M: array condomize [ condomize ] map ;
+
+M: callable condomize [ condomize ] map ;
+
+M: object condomize ;
+
+: literal ( obj -- ) dup condomize? [ condomize ] when stack get push ;
 
 GENERIC: expand-macros* ( obj -- )
 
index 7d93ce8a9ea4b83eb98ca66d1ca43819f77bc64d..91aa6880e6b6cfa845a81021906cb0808d84a1cd 100644 (file)
@@ -2,16 +2,22 @@ IN: macros.tests
 USING: tools.test macros math kernel arrays
 vectors io.streams.string prettyprint parser eval see ;
 
-MACRO: see-test ( a b -- c ) + ;
+MACRO: see-test ( a b -- quot ) + ;
 
-[ "USING: macros math ;\nIN: macros.tests\nMACRO: see-test ( a b -- c ) + ;\n" ]
+[ t ] [ \ see-test macro? ] unit-test
+
+[ "USING: macros math ;\nIN: macros.tests\nMACRO: see-test ( a b -- quot ) + ;\n" ]
 [ [ \ see-test see ] with-string-writer ]
 unit-test
 
+[ t ] [ \ see-test macro? ] unit-test
+
 [ t ] [
     "USING: math ;\nIN: macros.tests\n: see-test ( a b -- c ) - ;\n" dup eval
     [ \ see-test see ] with-string-writer =
 ] unit-test
 
+[ f ] [ \ see-test macro? ] unit-test
+
 [ ] [ "USING: macros stack-checker kernel ; IN: hanging-macro MACRO: c ( quot -- ) infer drop [ ] ; : a ( -- ) [ a ] c ;" eval ] unit-test
 
index 21a91e567d4e193756b3f03a41d47e53268cdf5b..a86b711340526c4b19b12d68005abd66d19c0d36 100644 (file)
@@ -6,17 +6,18 @@ IN: macros
 
 <PRIVATE
 
-: real-macro-effect ( word -- effect' )
-    stack-effect in>> 1 <effect> ;
+: real-macro-effect ( effect -- effect' )
+    in>> { "quot" } <effect> ;
 
 PRIVATE>
 
-: define-macro ( word definition -- )
-    [ "macro" set-word-prop ]
-    [ over real-macro-effect memoize-quot [ call ] append define ]
-    2bi ;
+: define-macro ( word definition effect -- )
+    real-macro-effect
+    [ [ memoize-quot [ call ] append ] keep define-declared ]
+    [ drop "macro" set-word-prop ]
+    3bi ;
 
-: MACRO: (:) define-macro ; parsing
+SYNTAX: MACRO: (:) define-macro ;
 
 PREDICATE: macro < word "macro" word-prop >boolean ;
 
index 3846dea3be6317944c30690230c60c36daca12cf..b21d8c6d733983bf237c6fc521dcdb16da43769a 100644 (file)
@@ -16,8 +16,8 @@ SYMBOL: _
 : define-match-vars ( seq -- )
     [ define-match-var ] each ;
 
-: MATCH-VARS: ! vars ...
-    ";" parse-tokens define-match-vars ; parsing
+SYNTAX: MATCH-VARS: ! vars ...
+    ";" parse-tokens define-match-vars ;
 
 : match-var? ( symbol -- bool )
     dup word? [ "match-var" word-prop ] [ drop f ] if ;
index 358c984276665182a774815dfec360c41151af06..fca06526e0501eb6c5665dfa264c169d4b5fa783 100644 (file)
@@ -139,8 +139,8 @@ HELP: flags
 { $examples
     { $example "USING: math.bitwise kernel prettyprint ;"
         "IN: scratchpad"
-        ": MY-CONSTANT HEX: 1 ; inline"
-        "{ HEX: 20 MY-CONSTANT BIN: 100 } flags .h"
+        "CONSTANT: x HEX: 1"
+        "{ HEX: 20 x BIN: 100 } flags .h"
         "25"
     }
 } ;
index 4f639c02a7ce5d6cbbe29f8c5f2e42ecf5d535ae..3148567bc0a0cdf9649dbf822ce9fce4b59f0f69 100755 (executable)
@@ -37,7 +37,7 @@ IN: math.bitwise
 
 ! flags
 MACRO: flags ( values -- )
-    [ 0 ] [ [ dup word? [ execute ] when bitor ] curry compose ] reduce ;
+    [ 0 ] [ [ ?execute bitor ] curry compose ] reduce ;
 
 ! bitfield
 <PRIVATE
diff --git a/basis/math/blas/config/config-docs.factor b/basis/math/blas/config/config-docs.factor
new file mode 100644 (file)
index 0000000..60eaff2
--- /dev/null
@@ -0,0 +1,23 @@
+USING: alien.fortran help.markup help.syntax math.blas.config multiline ;
+IN: math.blas.config
+
+ARTICLE: "math.blas.config" "Configuring the BLAS interface"
+"The " { $link "math.blas-summary" } " chooses the underlying BLAS interface to use based on the values of the following global variables:"
+{ $subsection blas-library }
+{ $subsection blas-fortran-abi }
+"The interface attempts to set default values based on the ones encountered on the Factor project's build machines. If these settings don't work with your system's BLAS, or you wish to use a commercial BLAS, you may change the global values of those variables in your " { $link "factor-rc" } ". For example, to use AMD's ACML library on Windows with " { $snippet "math.blas" } ", your " { $snippet "factor-rc" } " would look like this:"
+{ $code <"
+USING: math.blas.config namespaces ;
+"X:\\path\\to\\acml.dll" blas-library set-global
+intel-windows-abi blas-fortran-abi set-global
+"> }
+"To take effect, the " { $snippet "blas-library" } " and " { $snippet "blas-fortran-abi" } " variables must be set before any other " { $snippet "math.blas" } " vocabularies are loaded."
+;
+
+HELP: blas-library
+{ $description "The name of the shared library containing the BLAS interface to load. The value of this variable must be a valid shared library name that can be passed to " { $link add-fortran-library } ". To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
+
+HELP: blas-fortran-abi
+{ $description "The Fortran ABI used by the BLAS interface specified in the " { $link blas-library } " variable. The value of " { $snippet "blas-fortran-abi" } " must be one of the " { $link "alien.fortran-abis" } " that can be passed to " { $link add-fortran-library } ". To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
+
+ABOUT: "math.blas.config"
diff --git a/basis/math/blas/config/config.factor b/basis/math/blas/config/config.factor
new file mode 100644 (file)
index 0000000..327c546
--- /dev/null
@@ -0,0 +1,24 @@
+USING: alien.fortran combinators kernel namespaces system ;
+IN: math.blas.config
+
+SYMBOLS: blas-library blas-fortran-abi ;
+
+blas-library [
+    {
+        { [ os macosx?  ] [ "libblas.dylib" ] }
+        { [ os windows? ] [ "blas.dll"      ] }
+        [ "libblas.so" ]
+    } cond
+] initialize
+
+blas-fortran-abi [
+    {
+        { [ os macosx?                  ] [ intel-unix-abi ] }
+        { [ os windows? cpu x86.32? and ] [ f2c-abi        ] }
+        { [ os netbsd?  cpu x86.64? and ] [ g95-abi        ] }
+        { [ os windows? cpu x86.64? and ] [ gfortran-abi   ] }
+        { [ os freebsd?                 ] [ gfortran-abi   ] }
+        { [ os linux?   cpu x86.32? and ] [ gfortran-abi   ] }
+        [ f2c-abi ]
+    } cond
+] initialize
index 1749103ce41a47b8c5e70e1e77ac9726ca4cebae..b7748f500f825db77ea536c4d19cfd928a3a7bdf 100644 (file)
@@ -1,14 +1,9 @@
-USING: alien alien.fortran kernel system combinators ;
+USING: alien.fortran kernel math.blas.config namespaces ;
 IN: math.blas.ffi
 
 <<
-"blas" {
-    { [ os macosx? ] [ "libblas.dylib" intel-unix-abi add-fortran-library ] }
-    { [ os windows? cpu x86.32? and ] [ "blas.dll" f2c-abi add-fortran-library ] }
-    { [ os windows? cpu x86.64? and ] [ "blas.dll" gfortran-abi add-fortran-library ] }
-    { [ os freebsd? ] [ "libblas.so" gfortran-abi add-fortran-library ] }
-    [ "libblas.so" f2c-abi add-fortran-library ]
-} cond
+"blas" blas-library blas-fortran-abi [ get ] bi@
+add-fortran-library
 >>
 
 LIBRARY: blas
index 17d2f9ccd1cb83feb17c771800953e5b501308f1..5662cd99059744be7455532a11acda14f1d90cf2 100644 (file)
@@ -2,13 +2,14 @@ USING: alien byte-arrays help.markup help.syntax math math.blas.vectors sequence
 IN: math.blas.matrices
 
 ARTICLE: "math.blas-summary" "Basic Linear Algebra Subroutines (BLAS) interface"
-"Factor provides an interface to high-performance vector and matrix math routines available in the system's BLAS library. A set of specialized types are provided for handling packed, unboxed vector data:"
+"Factor provides an interface to high-performance vector and matrix math routines available in implementations of the BLAS math library. A set of specialized types are provided for handling packed, unboxed vector data:"
 { $subsection "math.blas-types" }
 "Scalar-vector and vector-vector operations are available in the " { $vocab-link "math.blas.vectors" } " vocabulary:"
 { $subsection "math.blas.vectors" }
 "Vector-matrix and matrix-matrix operations are available in the " { $vocab-link "math.blas.matrices" } " vocabulary:"
 { $subsection "math.blas.matrices" }
-"The low-level BLAS Fortran interface can be accessed directly through the " { $vocab-link "math.blas.ffi" } " vocabulary." ;
+"The low-level BLAS Fortran interface can be accessed directly through the " { $vocab-link "math.blas.ffi" } " vocabulary. The BLAS interface can be configured to use different underlying BLAS implementations:"
+{ $subsection "math.blas.config" } ;
 
 ARTICLE: "math.blas-types" "BLAS interface types"
 "BLAS vectors come in single- and double-precision, real and complex flavors:"
index 6fad54550104b00adeb1cbb463b52a65ddced9e8..1882ccd0d58ce4db8ad5359d0857e83c7f55ea9d 100755 (executable)
@@ -289,7 +289,7 @@ M: MATRIX n*V(*)V+M!
 M: MATRIX n*V(*)Vconj+M!
     (prepare-ger) [ XGERC ] dip ;
 
-: XMATRIX{ \ } [ >MATRIX ] parse-literal ; parsing
+SYNTAX: XMATRIX{ \ } [ >MATRIX ] parse-literal ;
 
 M: MATRIX pprint-delims
     drop \ XMATRIX{ \ } ;
index 84b5fd9e6f707490ca013ac89a3c997e93a71daa..d7c6ebc92739083c13b1dd176f489343a26ca124 100755 (executable)
@@ -179,7 +179,7 @@ M: VECTOR n*V+V!
 M: VECTOR n*V!
     (prepare-scal) [ XSCAL ] dip ;
 
-: XVECTOR{ \ } [ >VECTOR ] parse-literal ; parsing
+SYNTAX: XVECTOR{ \ } [ >VECTOR ] parse-literal ;
 
 M: VECTOR pprint-delims
     drop \ XVECTOR{ \ } ;
index 273fd0b2b52116759963f927d55234e429833bd7..c41faaf5585a1638e298b93638d00d220adb929d 100644 (file)
@@ -31,7 +31,7 @@ M: complex sqrt >polar [ fsqrt ] [ 2.0 / ] bi* polar> ;
 
 IN: syntax
 
-: C{ \ } [ first2 rect> ] parse-literal ; parsing
+SYNTAX: C{ \ } [ first2 rect> ] parse-literal ;
 
 USE: prettyprint.custom
 
index 33a5d96fc468dffd5bea90fe287fdc2d72b75f66..f7d0d5a94160ea527f967b853936e945ccd18b68 100644 (file)
@@ -13,7 +13,8 @@ ARTICLE: "integer-functions" "Integer functions"
 "Tests:"
 { $subsection power-of-2? }
 { $subsection even? }
-{ $subsection odd? } ;
+{ $subsection odd? }
+{ $subsection divisor? } ;
 
 ARTICLE: "arithmetic-functions" "Arithmetic functions"
 "Computing additive and multiplicative inverses:"
@@ -269,6 +270,11 @@ HELP: gcd
 { $description "Computes the positive greatest common divisor " { $snippet "d" } " of " { $snippet "x" } " and " { $snippet "y" } ", and another value " { $snippet "a" } " satisfying:" { $code "a*y = d mod x" } }
 { $notes "If " { $snippet "d" } " is 1, then " { $snippet "a" } " is the inverse of " { $snippet "y" } " modulo " { $snippet "x" } "." } ;
 
+HELP: divisor?
+{ $values { "m" integer } { "n" integer } { "?" "a boolean" } }
+{ $description "Tests if " { $snippet "n" } " is a divisor of " { $snippet "m" } ". This is the same thing as asking if " { $snippet "m" } " is divisible by " { $snippet "n" } "." }
+{ $notes "Returns t for both negative and positive divisors, as well as for trivial and non-trivial divisors." } ;
+
 HELP: mod-inv
 { $values { "x" integer } { "n" integer } { "y" integer } }
 { $description "Outputs an integer " { $snippet "y" } " such that " { $snippet "xy = 1 (mod n)" } "." }
index 9f5ce36be1fb593bafc1277b6e7e86f592476539..4c9d151fd8e057028d9aab66357b2264c0b70019 100644 (file)
@@ -32,13 +32,13 @@ IN: math.functions.tests
 
 [ 1.0 ] [ 0 cosh ] unit-test
 [ 0.0 ] [ 1 acosh ] unit-test
-            
+
 [ 1.0 ] [ 0 cos ] unit-test
 [ 0.0 ] [ 1 acos ] unit-test
-            
+
 [ 0.0 ] [ 0 sinh ] unit-test
 [ 0.0 ] [ 0 asinh ] unit-test
-            
+
 [ 0.0 ] [ 0 sin ] unit-test
 [ 0.0 ] [ 0 asin ] unit-test
 
@@ -97,11 +97,17 @@ IN: math.functions.tests
 
 : verify-gcd ( a b -- ? )
     2dup gcd
-    [ rot * swap rem ] dip = ; 
+    [ rot * swap rem ] dip = ;
 
 [ t ] [ 123 124 verify-gcd ] unit-test
 [ t ] [ 50 120 verify-gcd ] unit-test
 
+[ t ] [ 0 42 divisor? ] unit-test
+[ t ] [ 42 7 divisor? ] unit-test
+[ t ] [ 42 -7 divisor? ] unit-test
+[ t ] [ 42 42 divisor? ] unit-test
+[ f ] [ 42 16 divisor? ] unit-test
+
 [ 3 ] [ 5 7 mod-inv ] unit-test
 [ 78572682077 ] [ 234829342 342389423843 mod-inv ] unit-test
 
@@ -150,4 +156,4 @@ IN: math.functions.tests
     1067811677921310779
     2135623355842621559
     [ >bignum ] tri@ ^mod
-] unit-test
\ No newline at end of file
+] unit-test
index a87b3995d7eb03a6b0b65f46dba4f8c08ab160d7..1eac321e3b644b03a31f155c1a19d375096b0d04 100644 (file)
@@ -111,6 +111,9 @@ PRIVATE>
 : lcm ( a b -- c )
     [ * ] 2keep gcd nip /i ; foldable
 
+: divisor? ( m n -- ? )
+    mod 0 = ;
+
 : mod-inv ( x n -- y )
     [ nip ] [ gcd 1 = ] 2bi
     [ dup 0 < [ + ] [ nip ] if ]
@@ -198,7 +201,7 @@ M: real sin fsin ;
 
 GENERIC: sinh ( x -- y ) foldable
 
-M: complex sinh 
+M: complex sinh
     >float-rect
     [ [ fsinh ] [ fcos ] bi* * ]
     [ [ fcosh ] [ fsin ] bi* * ] 2bi rect> ;
index bcf7bb77b0c7fde12eec3732ec5ef99513be1d27..29979b62d357ceedb089676a4f216ea3282bdeb1 100644 (file)
@@ -26,3 +26,8 @@ tools.test math kernel sequences ;
 [ fixnum-bitnot ] [ \ bitnot modular-variant ] unit-test
 [ fixnum+fast ] [ \ fixnum+ modular-variant ] unit-test
 [ fixnum+fast ] [ \ fixnum+fast modular-variant ] unit-test
+
+[ 3 ] [ 1 2 +-integer-integer ] unit-test
+[ 3 ] [ 1 >bignum 2 +-integer-integer ] unit-test
+[ 3 ] [ 1 2 >bignum +-integer-integer ] unit-test
+[ 3 ] [ 1 >bignum 2 >bignum +-integer-integer ] unit-test
\ No newline at end of file
index 08cd8fb470d5df1615970d4ebb05fa4980c3bb42..6679e81fcde228dcc03b1261de2218afb2c23a55 100644 (file)
@@ -45,31 +45,41 @@ M: word integer-op-input-classes
         { bitnot fixnum-bitnot }
     } at swap or ;
 
+: bignum-fixnum-op-quot ( big-word -- quot )
+    '[ fixnum>bignum _ execute ] ;
+
+: fixnum-bignum-op-quot ( big-word -- quot )
+    '[ [ fixnum>bignum ] dip _ execute ] ;
+
 : integer-fixnum-op-quot ( fix-word big-word -- quot )
     [
         [ over fixnum? ] %
-        [ '[ _ execute ] , ]
-        [ '[ fixnum>bignum _ execute ] , ] bi*
-        \ if ,
+        [ '[ _ execute ] , ] [ bignum-fixnum-op-quot , ] bi* \ if ,
     ] [ ] make ;
 
 : fixnum-integer-op-quot ( fix-word big-word -- quot )
     [
         [ dup fixnum? ] %
-        [ '[ _ execute ] , ]
-        [ '[ [ fixnum>bignum ] dip _ execute ] , ] bi*
-        \ if ,
+        [ '[ _ execute ] , ] [ fixnum-bignum-op-quot , ] bi* \ if ,
+    ] [ ] make ;
+
+: integer-bignum-op-quot ( big-word -- quot )
+    [
+        [ over fixnum? ] %
+        [ fixnum-bignum-op-quot , ] [ '[ _ execute ] , ] bi \ if ,
     ] [ ] make ;
 
 : integer-integer-op-quot ( fix-word big-word -- quot )
     [
-        [ dup fixnum? ] %
-        2dup integer-fixnum-op-quot ,
+        [ 2dup both-fixnums? ] %
+        [ '[ _ execute ] , ]
         [
-            [ over fixnum? [ [ fixnum>bignum ] dip ] when ] %
-            nip ,
-        ] [ ] make ,
-        \ if ,
+            [
+                [ dup fixnum? ] %
+                [ bignum-fixnum-op-quot , ]
+                [ integer-bignum-op-quot , ] bi \ if ,
+            ] [ ] make ,
+        ] bi* \ if ,
     ] [ ] make ;
 
 : integer-op-word ( triple -- word )
index 199b72b7e146143f510a6752b4e8488db830b820..278bf70b3d28d9c263600e5c6511e89ef79bf003 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007-2009 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays combinators kernel make math math.primes sequences ;
+USING: arrays combinators kernel make math math.functions math.primes sequences ;
 IN: math.primes.factors
 
 <PRIVATE
@@ -11,7 +11,7 @@ IN: math.primes.factors
     swap ;
 
 : write-factor ( n d -- n' d' )
-    2dup mod zero? [
+    2dup divisor? [
         [ [ count-factor ] keep swap 2array , ] keep
         ! If the remainder is a prime number, increase d so that
         ! the caller stops looking for factors.
index 8987def80bbae6727504c3d32449e4d2de93089c..e35adb10e55e7b0d16b7b2ff3165f7eb64f5b002 100644 (file)
@@ -2,7 +2,7 @@ USING: help.syntax help.markup arrays sequences ;
 
 IN: math.ranges
 
-ARTICLE: "ranges" "Ranges"
+ARTICLE: "math.ranges" "Numeric ranges"
 "A " { $emphasis "range" } " is a virtual sequence with real number elements "
 "ranging from " { $emphasis "a" } " to " { $emphasis "b" } " by " { $emphasis "step" } ". Ascending as well as descending ranges are supported."
 $nl
@@ -24,4 +24,4 @@ $nl
 { $code "100 1 [a,b] product" }
 "A range can be converted into a concrete sequence using a word such as " { $link >array } ". In most cases this is unnecessary since ranges implement the sequence protocol already. It is necessary if a mutable sequence is needed, for use with words such as " { $link set-nth } " or " { $link change-each } "." ;
   
-ABOUT: "ranges"
\ No newline at end of file
+ABOUT: "math.ranges"
\ No newline at end of file
index a6f78970c8ddeaa6e5518952bd48b58fe5b93ec6..cfb5cffb37ad38f07f372a01a80324bb485e7a87 100644 (file)
@@ -1,10 +1,10 @@
-! Copyright (C) 2007 Slava Pestov, Daniel Ehrenberg.
+! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.syntax help.markup ;
+USING: help.syntax help.markup words quotations effects ;
 IN: memoize
 
 HELP: define-memoized
-{ $values { "word" "the word to be defined" } { "quot" "a quotation" } }
+{ $values { "word" word } { "quot" quotation } { "effect" effect } }
 { $description "defines the given word at runtime as one which memoizes its output given a particular input" }
 { $notes "A maximum of four input and four output arguments can be used" }
 { $see-also POSTPONE: MEMO: } ;
index 3bc573dff513c73bb0bb3d3d0efc2e9aea616509..4e10fc3de4548e3afc165ad5b8b5a64c055cfb9f 100644 (file)
@@ -34,14 +34,13 @@ M: too-many-arguments summary
 
 PRIVATE>
 
-: define-memoized ( word quot -- )
-    [ H{ } clone ] dip
-    [ pick stack-effect make-memoizer define ]
-    [ nip "memo-quot" set-word-prop ]
-    [ drop "memoize" set-word-prop ]
+: define-memoized ( word quot effect -- )
+    [ drop "memo-quot" set-word-prop ]
+    [ 2drop H{ } clone "memoize" set-word-prop ]
+    [ [ [ dup "memoize" word-prop ] 2dip make-memoizer ] keep define-declared ]
     3tri ;
 
-: MEMO: (:) define-memoized ; parsing
+SYNTAX: MEMO: (:) define-memoized ;
 
 PREDICATE: memoized < word "memoize" word-prop ;
 
index fcdfd166c5acc119f97cf2a61543e0bc9f1897d1..e0cf73c7f115560c689e49b7731c6f78d115dccb 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
-USING: accessors models kernel call ;\r
+USING: accessors models kernel ;\r
 IN: models.arrow\r
 \r
 TUPLE: arrow < model model quot ;\r
diff --git a/basis/models/arrow/smart/smart-docs.factor b/basis/models/arrow/smart/smart-docs.factor
new file mode 100644 (file)
index 0000000..45faf52
--- /dev/null
@@ -0,0 +1,21 @@
+IN: models.arrow.smart
+USING: help.syntax help.markup models.product ;
+
+HELP: <smart-arrow>
+{ $values { "quot" { $quotation "( ... -- output )" } } }
+{ $description "A macro that expands into a form with the stack effect of the quotation. The form constructs a model which applies the quotation to values from an underlying " { $link product } " model having as many components as the quotation has inputs." }
+{ $examples
+  "A model which adds the values of two existing models:"
+  { $example
+    "USING: models models.arrows.smart accessors math prettyprint ;"
+    "1 <model> 2 <model> [ + ] <smart-arrow>"
+    "[ activate-model ] [ value>> ] bi ."
+    "3"
+  }
+} ;
+
+ARTICLE: "models.arrows.smart" "Smart arrow models"
+"The " { $vocab-link "models.arrows.smart" } " vocabulary generalizes arrows to arbitrary input arity. They're called “smart” because they resemble " { $link "combinators.smart" } "."
+{ $subsection <smart-arrow> } ;
+
+ABOUT: "models.arrows.smart"
\ No newline at end of file
diff --git a/basis/models/history/history-docs.factor b/basis/models/history/history-docs.factor
deleted file mode 100644 (file)
index d157729..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-USING: help.syntax help.markup kernel math classes classes.tuple\r
-calendar models ;\r
-IN: models.history\r
-\r
-HELP: history\r
-{ $class-description "History models record a timeline of previous values on calls to " { $link add-history } ", and can travel back and forth on the timeline with " { $link go-back } " and " { $link go-forward } ". History models are constructed by " { $link <history> } "." } ;\r
-\r
-HELP: <history>\r
-{ $values { "value" object } { "history" "a new " { $link history } } }\r
-{ $description "Creates a new history model with an initial value." } ;\r
-\r
-{ <history> add-history go-back go-forward } related-words\r
-\r
-HELP: go-back\r
-{ $values { "history" history } }\r
-{ $description "Restores the previous value and calls " { $link model-changed } " on all observers registered with " { $link add-connection } "." } ;\r
-\r
-HELP: go-forward\r
-{ $values { "history" history } }\r
-{ $description "Restores the value set prior to the last call to " { $link go-back } " and calls " { $link model-changed } " on all observers registered with " { $link add-connection } "." } ;\r
-\r
-HELP: add-history\r
-{ $values { "history" history } }\r
-{ $description "Adds the current value to the history." } ;\r
-\r
-ARTICLE: "models-history" "History models"\r
-"History models record previous values."\r
-{ $subsection history }\r
-{ $subsection <history> }\r
-"Recording history:"\r
-{ $subsection add-history }\r
-"Navigating the history:"\r
-{ $subsection go-back }\r
-{ $subsection go-forward } ;\r
-\r
-ABOUT: "models-history"\r
diff --git a/basis/models/history/history-tests.factor b/basis/models/history/history-tests.factor
deleted file mode 100644 (file)
index c89dd5c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-USING: arrays generic kernel math models namespaces sequences assocs\r
-tools.test models.history accessors ;\r
-IN: models.history.tests\r
-\r
-f <history> "history" set\r
-\r
-"history" get add-history\r
-\r
-[ t ] [ "history" get back>> empty? ] unit-test\r
-[ t ] [ "history" get forward>> empty? ] unit-test\r
-\r
-"history" get add-history\r
-3 "history" get set-model\r
-\r
-[ t ] [ "history" get back>> empty? ] unit-test\r
-[ t ] [ "history" get forward>> empty? ] unit-test\r
-\r
-"history" get add-history\r
-4 "history" get set-model\r
-\r
-[ f ] [ "history" get back>> empty? ] unit-test\r
-[ t ] [ "history" get forward>> empty? ] unit-test\r
-\r
-"history" get go-back\r
-\r
-[ 3 ] [ "history" get value>> ] unit-test\r
-\r
-[ t ] [ "history" get back>> empty? ] unit-test\r
-[ f ] [ "history" get forward>> empty? ] unit-test\r
-\r
-"history" get go-forward\r
-\r
-[ 4 ] [ "history" get value>> ] unit-test\r
-\r
-[ f ] [ "history" get back>> empty? ] unit-test\r
-[ t ] [ "history" get forward>> empty? ] unit-test\r
-\r
diff --git a/basis/models/history/history.factor b/basis/models/history/history.factor
deleted file mode 100644 (file)
index 90d6b59..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: accessors kernel models sequences ;\r
-IN: models.history\r
-\r
-TUPLE: history < model back forward ;\r
-\r
-: reset-history ( history -- history )\r
-    V{ } clone >>back\r
-    V{ } clone >>forward ; inline\r
-\r
-: <history> ( value -- history )\r
-    history new-model\r
-        reset-history ;\r
-\r
-: (add-history) ( history to -- )\r
-    swap value>> dup [ swap push ] [ 2drop ] if ;\r
-\r
-: go-back/forward ( history to from -- )\r
-    [ 2drop ]\r
-    [ [ dupd (add-history) ] dip pop swap set-model ] if-empty ;\r
-\r
-: go-back ( history -- )\r
-    dup [ forward>> ] [ back>> ] bi go-back/forward ;\r
-\r
-: go-forward ( history -- )\r
-    dup [ back>> ] [ forward>> ] bi go-back/forward ;\r
-\r
-: add-history ( history -- )\r
-    dup forward>> delete-all\r
-    dup back>> (add-history) ;\r
diff --git a/basis/models/history/summary.txt b/basis/models/history/summary.txt
deleted file mode 100644 (file)
index 76f7b88..0000000
+++ /dev/null
@@ -1 +0,0 @@
-History models remember prior values
index 82dd0354677873760a09f1ac721e23409c3db65f..8f40a8adbe90c725f975632e933243e3716c9fa4 100644 (file)
@@ -5,12 +5,13 @@ IN: models
 HELP: model
 { $class-description "A mutable cell holding a single value. When the value is changed, a sequence of connected objects are notified. Models have the following slots:"
     { $list
-        { { $snippet "value" } " - the value of the model. Use " { $link set-model } " to change the value." }
-        { { $snippet "connections" } " - a sequence of objects implementing the " { $link model-changed } " generic word, to be notified when the model's value changes." }
-        { { $snippet "dependencies" } " - a sequence of models which should have this model added to their sequence of connections when activated." }
-        { { $snippet "ref" } " - a reference count tracking the number of models which depend on this one." }
+        { { $slot "value" } " - the value of the model. Use " { $link set-model } " to change the value." }
+        { { $slot "connections" } " - a sequence of objects implementing the " { $link model-changed } " generic word, to be notified when the model's value changes." }
+        { { $slot "dependencies" } " - a sequence of models which should have this model added to their sequence of connections when activated." }
+        { { $slot "ref" } " - a reference count tracking the number of models which depend on this one." }
+        { { $slot "locked?" } " - a slot set by " { $link with-locked-model } " to ensure that the model doesn't get changed recursively" }
     }
-"Other classes may delegate to " { $link model } "."
+"Other classes may inherit from " { $link model } "."
 } ;
 
 HELP: <model>
@@ -132,7 +133,6 @@ $nl
 { $subsection "models-impl" }
 { $subsection "models.arrow" }
 { $subsection "models.product" }
-{ $subsection "models-history" }
 { $subsection "models-range" }
 { $subsection "models-delay" } ;
 
index 67155b83032f2ae6d877a63a45ab756bdfd99d81..f875fa31400d069b132c581388bb2796fcff6b69 100644 (file)
@@ -4,7 +4,7 @@ IN: models.tests
 
 TUPLE: model-tester hit? ;
 
-: <model-tester> model-tester new ;
+: <model-tester> ( -- model-tester ) model-tester new ;
 
 M: model-tester model-changed nip t >>hit? drop ;
 
index 50c0365728246e1ebc2fc0554de74d0045569197..e9119e8452e5e8896fbd98365c4e6192b3d06aea 100644 (file)
@@ -3,7 +3,7 @@ USING: arrays generic kernel math models namespaces sequences assocs
 tools.test models.range ;\r
 \r
 ! Test <range> \r
-: setup-range 0 0 0 255 <range> ;\r
+: setup-range ( -- range ) 0 0 0 255 <range> ;\r
 \r
 ! clamp-value should not go past range ends\r
 [ 0   ] [ -10 setup-range clamp-value ] unit-test\r
index 53c2789c50b669eb8355c5a30eebfb48a9b2b015..2e8f8eb4c497d1fb9252ee15b1b554f2d6645a6f 100644 (file)
@@ -20,10 +20,10 @@ PRIVATE>
     [ (parse-here) ] "" make but-last
     lexer get next-line ;
 
-: STRING:
+SYNTAX: STRING:
     CREATE-WORD
     parse-here 1quotation
-    (( -- string )) define-inline ; parsing
+    (( -- string )) define-inline ;
 
 <PRIVATE
 
@@ -48,16 +48,16 @@ PRIVATE>
         change-column drop
     ] "" make ;
 
-: <"
-    "\">" parse-multiline-string parsed ; parsing
+SYNTAX: <"
+    "\">" parse-multiline-string parsed ;
 
-: <'
-    "'>" parse-multiline-string parsed ; parsing
+SYNTAX: <'
+    "'>" parse-multiline-string parsed ;
 
-: {'
-    "'}" parse-multiline-string parsed ; parsing
+SYNTAX: {'
+    "'}" parse-multiline-string parsed ;
 
-: {"
-    "\"}" parse-multiline-string parsed ; parsing
+SYNTAX: {"
+    "\"}" parse-multiline-string parsed ;
 
-: /* "*/" parse-multiline-string drop ; parsing
+SYNTAX: /* "*/" parse-multiline-string drop ;
index 22a1515908fa7a1e8238c631cce6e20adaea2e08..16bea56862fe19bd921ae11d591cd89473043f7d 100644 (file)
@@ -62,7 +62,7 @@ M: nibble-array resize
 
 M: nibble-array byte-length length nibbles>bytes ;
 
-: N{ \ } [ >nibble-array ] parse-literal ; parsing
+SYNTAX: N{ \ } [ >nibble-array ] parse-literal ;
 
 INSTANCE: nibble-array sequence
 
index 55ac3c728e5f18205c67bd0b04ff03d7476e7035..f4e25322b8837d0e372b21d2d236b93c349ff615 100644 (file)
@@ -1,3 +1,4 @@
 Slava Pestov
 Eduardo Cavazos
 Joe Groff
+Alex Chapman
index 09d49b33c284645939a952a03696b9acb8babb60..ad04ce7fa5ce72547a841ab979f2a39636cba985 100755 (executable)
@@ -32,6 +32,8 @@ IN: opengl.capabilities
     (gl-version) drop ;
 : gl-vendor-version ( -- version )
     (gl-version) nip ;
+: gl-vendor ( -- name )
+    GL_VENDOR glGetString ;
 : has-gl-version? ( version -- ? )
     gl-version version-before? ;
 : (make-gl-version-error) ( required-version -- )
index 1901f27a24507e2512d93a1f956aaaa0d2f05714..e9c193bac72836f0710fc5440af248256e9fc736 100644 (file)
@@ -1 +1 @@
-Slava Pestov
+Alex Chapman
index fb2ddfaf3e411498e22f449a7fb13d98d5e9c74b..ccd3f5fad74e2ed9806fe53f5b349fe91a3efd47 100644 (file)
@@ -47,7 +47,7 @@ reset-gl-function-number-counter
     parameters return parse-arglist [ abi indirect-quot ] dip
     define-declared ;
 
-: GL-FUNCTION:
+SYNTAX: GL-FUNCTION:
     gl-function-calling-convention
     scan
     scan dup
@@ -55,5 +55,4 @@ reset-gl-function-number-counter
     gl-function-number
     [ gl-function-pointer ] 2curry swap
     ";" parse-tokens [ "()" subseq? not ] filter
-    define-indirect
-    ; parsing
+    define-indirect ;
index eb8dda5e33ebd14345347a75d32dc20430e287f6..9e095a62e6b205314023943dfde6fca03fc893e7 100644 (file)
@@ -1,4 +1,4 @@
-USING: kernel alien ;
+USING: kernel alien alien.libraries ;
 IN: opengl.gl.macosx
 
 : gl-function-context ( -- context ) 0 ; inline
diff --git a/basis/opengl/glu/authors.txt b/basis/opengl/glu/authors.txt
deleted file mode 100644 (file)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/opengl/glu/glu.factor b/basis/opengl/glu/glu.factor
deleted file mode 100644 (file)
index d603724..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-! Copyright (C) 2005 Alex Chapman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax kernel sequences words ;
-IN: opengl.glu
-
-! These are defined as structs in glu.h, but we only ever use pointers to them
-TYPEDEF: void* GLUnurbs*
-TYPEDEF: void* GLUquadric*
-TYPEDEF: void* GLUtesselator*
-TYPEDEF: void* GLubyte*
-TYPEDEF: void* GLUfuncptr
-
-! StringName
-CONSTANT: GLU_VERSION                        100800
-CONSTANT: GLU_EXTENSIONS                     100801
-
-! ErrorCode
-CONSTANT: GLU_INVALID_ENUM                   100900
-CONSTANT: GLU_INVALID_VALUE                  100901
-CONSTANT: GLU_OUT_OF_MEMORY                  100902
-CONSTANT: GLU_INCOMPATIBLE_GL_VERSION        100903
-CONSTANT: GLU_INVALID_OPERATION              100904
-
-! NurbsDisplay
-CONSTANT: GLU_OUTLINE_POLYGON                100240
-CONSTANT: GLU_OUTLINE_PATCH                  100241
-
-! NurbsCallback
-CONSTANT: GLU_NURBS_ERROR                    100103
-CONSTANT: GLU_ERROR                          100103
-CONSTANT: GLU_NURBS_BEGIN                    100164
-CONSTANT: GLU_NURBS_BEGIN_EXT                100164
-CONSTANT: GLU_NURBS_VERTEX                   100165
-CONSTANT: GLU_NURBS_VERTEX_EXT               100165
-CONSTANT: GLU_NURBS_NORMAL                   100166
-CONSTANT: GLU_NURBS_NORMAL_EXT               100166
-CONSTANT: GLU_NURBS_COLOR                    100167
-CONSTANT: GLU_NURBS_COLOR_EXT                100167
-CONSTANT: GLU_NURBS_TEXTURE_COORD            100168
-CONSTANT: GLU_NURBS_TEX_COORD_EXT            100168
-CONSTANT: GLU_NURBS_END                      100169
-CONSTANT: GLU_NURBS_END_EXT                  100169
-CONSTANT: GLU_NURBS_BEGIN_DATA               100170
-CONSTANT: GLU_NURBS_BEGIN_DATA_EXT           100170
-CONSTANT: GLU_NURBS_VERTEX_DATA              100171
-CONSTANT: GLU_NURBS_VERTEX_DATA_EXT          100171
-CONSTANT: GLU_NURBS_NORMAL_DATA              100172
-CONSTANT: GLU_NURBS_NORMAL_DATA_EXT          100172
-CONSTANT: GLU_NURBS_COLOR_DATA               100173
-CONSTANT: GLU_NURBS_COLOR_DATA_EXT           100173
-CONSTANT: GLU_NURBS_TEXTURE_COORD_DATA       100174
-CONSTANT: GLU_NURBS_TEX_COORD_DATA_EXT       100174
-CONSTANT: GLU_NURBS_END_DATA                 100175
-CONSTANT: GLU_NURBS_END_DATA_EXT             100175
-
-! NurbsError
-CONSTANT: GLU_NURBS_ERROR1                   100251
-CONSTANT: GLU_NURBS_ERROR2                   100252
-CONSTANT: GLU_NURBS_ERROR3                   100253
-CONSTANT: GLU_NURBS_ERROR4                   100254
-CONSTANT: GLU_NURBS_ERROR5                   100255
-CONSTANT: GLU_NURBS_ERROR6                   100256
-CONSTANT: GLU_NURBS_ERROR7                   100257
-CONSTANT: GLU_NURBS_ERROR8                   100258
-CONSTANT: GLU_NURBS_ERROR9                   100259
-CONSTANT: GLU_NURBS_ERROR10                  100260
-CONSTANT: GLU_NURBS_ERROR11                  100261
-CONSTANT: GLU_NURBS_ERROR12                  100262
-CONSTANT: GLU_NURBS_ERROR13                  100263
-CONSTANT: GLU_NURBS_ERROR14                  100264
-CONSTANT: GLU_NURBS_ERROR15                  100265
-CONSTANT: GLU_NURBS_ERROR16                  100266
-CONSTANT: GLU_NURBS_ERROR17                  100267
-CONSTANT: GLU_NURBS_ERROR18                  100268
-CONSTANT: GLU_NURBS_ERROR19                  100269
-CONSTANT: GLU_NURBS_ERROR20                  100270
-CONSTANT: GLU_NURBS_ERROR21                  100271
-CONSTANT: GLU_NURBS_ERROR22                  100272
-CONSTANT: GLU_NURBS_ERROR23                  100273
-CONSTANT: GLU_NURBS_ERROR24                  100274
-CONSTANT: GLU_NURBS_ERROR25                  100275
-CONSTANT: GLU_NURBS_ERROR26                  100276
-CONSTANT: GLU_NURBS_ERROR27                  100277
-CONSTANT: GLU_NURBS_ERROR28                  100278
-CONSTANT: GLU_NURBS_ERROR29                  100279
-CONSTANT: GLU_NURBS_ERROR30                  100280
-CONSTANT: GLU_NURBS_ERROR31                  100281
-CONSTANT: GLU_NURBS_ERROR32                  100282
-CONSTANT: GLU_NURBS_ERROR33                  100283
-CONSTANT: GLU_NURBS_ERROR34                  100284
-CONSTANT: GLU_NURBS_ERROR35                  100285
-CONSTANT: GLU_NURBS_ERROR36                  100286
-CONSTANT: GLU_NURBS_ERROR37                  100287
-
-! NurbsProperty
-CONSTANT: GLU_AUTO_LOAD_MATRIX               100200
-CONSTANT: GLU_CULLING                        100201
-CONSTANT: GLU_SAMPLING_TOLERANCE             100203
-CONSTANT: GLU_DISPLAY_MODE                   100204
-CONSTANT: GLU_PARAMETRIC_TOLERANCE           100202
-CONSTANT: GLU_SAMPLING_METHOD                100205
-CONSTANT: GLU_U_STEP                         100206
-CONSTANT: GLU_V_STEP                         100207
-CONSTANT: GLU_NURBS_MODE                     100160
-CONSTANT: GLU_NURBS_MODE_EXT                 100160
-CONSTANT: GLU_NURBS_TESSELLATOR              100161
-CONSTANT: GLU_NURBS_TESSELLATOR_EXT          100161
-CONSTANT: GLU_NURBS_RENDERER                 100162
-CONSTANT: GLU_NURBS_RENDERER_EXT             100162
-
-! NurbsSampling
-CONSTANT: GLU_OBJECT_PARAMETRIC_ERROR        100208
-CONSTANT: GLU_OBJECT_PARAMETRIC_ERROR_EXT    100208
-CONSTANT: GLU_OBJECT_PATH_LENGTH             100209
-CONSTANT: GLU_OBJECT_PATH_LENGTH_EXT         100209
-CONSTANT: GLU_PATH_LENGTH                    100215
-CONSTANT: GLU_PARAMETRIC_ERROR               100216
-CONSTANT: GLU_DOMAIN_DISTANCE                100217
-
-! NurbsTrim
-CONSTANT: GLU_MAP1_TRIM_2                    100210
-CONSTANT: GLU_MAP1_TRIM_3                    100211
-
-! QuadricDrawStyle
-CONSTANT: GLU_POINT                          100010
-CONSTANT: GLU_LINE                           100011
-CONSTANT: GLU_FILL                           100012
-CONSTANT: GLU_SILHOUETTE                     100013
-
-! QuadricNormal
-CONSTANT: GLU_SMOOTH                         100000
-CONSTANT: GLU_FLAT                           100001
-CONSTANT: GLU_NONE                           100002
-
-! QuadricOrientation
-CONSTANT: GLU_OUTSIDE                        100020
-CONSTANT: GLU_INSIDE                         100021
-
-! TessCallback
-CONSTANT: GLU_TESS_BEGIN                     100100
-CONSTANT: GLU_BEGIN                          100100
-CONSTANT: GLU_TESS_VERTEX                    100101
-CONSTANT: GLU_VERTEX                         100101
-CONSTANT: GLU_TESS_END                       100102
-CONSTANT: GLU_END                            100102
-CONSTANT: GLU_TESS_ERROR                     100103
-CONSTANT: GLU_TESS_EDGE_FLAG                 100104
-CONSTANT: GLU_EDGE_FLAG                      100104
-CONSTANT: GLU_TESS_COMBINE                   100105
-CONSTANT: GLU_TESS_BEGIN_DATA                100106
-CONSTANT: GLU_TESS_VERTEX_DATA               100107
-CONSTANT: GLU_TESS_END_DATA                  100108
-CONSTANT: GLU_TESS_ERROR_DATA                100109
-CONSTANT: GLU_TESS_EDGE_FLAG_DATA            100110
-CONSTANT: GLU_TESS_COMBINE_DATA              100111
-
-! TessContour
-CONSTANT: GLU_CW                             100120
-CONSTANT: GLU_CCW                            100121
-CONSTANT: GLU_INTERIOR                       100122
-CONSTANT: GLU_EXTERIOR                       100123
-CONSTANT: GLU_UNKNOWN                        100124
-
-! TessProperty
-CONSTANT: GLU_TESS_WINDING_RULE              100140
-CONSTANT: GLU_TESS_BOUNDARY_ONLY             100141
-CONSTANT: GLU_TESS_TOLERANCE                 100142
-
-! TessError
-CONSTANT: GLU_TESS_ERROR1                    100151
-CONSTANT: GLU_TESS_ERROR2                    100152
-CONSTANT: GLU_TESS_ERROR3                    100153
-CONSTANT: GLU_TESS_ERROR4                    100154
-CONSTANT: GLU_TESS_ERROR5                    100155
-CONSTANT: GLU_TESS_ERROR6                    100156
-CONSTANT: GLU_TESS_ERROR7                    100157
-CONSTANT: GLU_TESS_ERROR8                    100158
-CONSTANT: GLU_TESS_MISSING_BEGIN_POLYGON     100151
-CONSTANT: GLU_TESS_MISSING_BEGIN_CONTOUR     100152
-CONSTANT: GLU_TESS_MISSING_END_POLYGON       100153
-CONSTANT: GLU_TESS_MISSING_END_CONTOUR       100154
-CONSTANT: GLU_TESS_COORD_TOO_LARGE           100155
-CONSTANT: GLU_TESS_NEED_COMBINE_CALLBACK     100156
-
-! TessWinding
-CONSTANT: GLU_TESS_WINDING_ODD               100130
-CONSTANT: GLU_TESS_WINDING_NONZERO           100131
-CONSTANT: GLU_TESS_WINDING_POSITIVE          100132
-CONSTANT: GLU_TESS_WINDING_NEGATIVE          100133
-CONSTANT: GLU_TESS_WINDING_ABS_GEQ_TWO       100134
-
-LIBRARY: glu
-
-FUNCTION: void gluBeginCurve ( GLUnurbs* nurb ) ;
-FUNCTION: void gluBeginPolygon ( GLUtesselator* tess ) ;
-FUNCTION: void gluBeginSurface ( GLUnurbs* nurb ) ;
-FUNCTION: void gluBeginTrim ( GLUnurbs* nurb ) ;
-
-FUNCTION: void gluCylinder ( GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks ) ;
-FUNCTION: void gluDeleteNurbsRenderer ( GLUnurbs* nurb ) ;
-FUNCTION: void gluDeleteQuadric ( GLUquadric* quad ) ;
-FUNCTION: void gluDeleteTess ( GLUtesselator* tess ) ;
-FUNCTION: void gluDisk ( GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops ) ;
-FUNCTION: void gluEndCurve ( GLUnurbs* nurb ) ;
-FUNCTION: void gluEndPolygon ( GLUtesselator* tess ) ;
-FUNCTION: void gluEndSurface ( GLUnurbs* nurb ) ;
-FUNCTION: void gluEndTrim ( GLUnurbs* nurb ) ;
-FUNCTION: char* gluErrorString ( GLenum error ) ;
-FUNCTION: void gluGetNurbsProperty ( GLUnurbs* nurb, GLenum property, GLfloat* data ) ;
-FUNCTION: char* gluGetString ( GLenum name ) ;
-FUNCTION: void gluGetTessProperty ( GLUtesselator* tess, GLenum which, GLdouble* data ) ;
-FUNCTION: void gluLoadSamplingMatrices ( GLUnurbs* nurb, GLfloat* model, GLfloat* perspective, GLint* view ) ;
-FUNCTION: void gluLookAt ( GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ ) ;
-FUNCTION: GLUnurbs* gluNewNurbsRenderer ( ) ;
-FUNCTION: GLUquadric* gluNewQuadric ( ) ;
-FUNCTION: GLUtesselator* gluNewTess ( ) ;
-FUNCTION: void gluNextContour ( GLUtesselator* tess, GLenum type ) ;
-FUNCTION: void gluNurbsCallback ( GLUnurbs* nurb, GLenum which, GLUfuncptr CallBackFunc ) ;
-! FUNCTION: void gluNurbsCallbackData ( GLUnurbs* nurb, GLvoid* userData ) ;
-! FUNCTION: void gluNurbsCallbackDataEXT ( GLUnurbs* nurb, GLvoid* userData ) ;
-FUNCTION: void gluNurbsCurve ( GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type ) ;
-FUNCTION: void gluNurbsProperty ( GLUnurbs* nurb, GLenum property, GLfloat value ) ;
-FUNCTION: void gluNurbsSurface ( GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type ) ;
-FUNCTION: void gluOrtho2D ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top ) ;
-FUNCTION: void gluPartialDisk ( GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep ) ;
-FUNCTION: void gluPerspective ( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) ;
-FUNCTION: void gluPickMatrix ( GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint* viewport ) ;
-FUNCTION: GLint gluProject ( GLdouble objX, GLdouble objY, GLdouble objZ, GLdouble* model, GLdouble* proj, GLint* view, GLdouble* winX, GLdouble* winY, GLdouble* winZ ) ;
-FUNCTION: void gluPwlCurve ( GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type ) ;
-FUNCTION: void gluQuadricCallback ( GLUquadric* quad, GLenum which, GLUfuncptr CallBackFunc ) ;
-FUNCTION: void gluQuadricDrawStyle ( GLUquadric* quad, GLenum draw ) ;
-FUNCTION: void gluQuadricNormals ( GLUquadric* quad, GLenum normal ) ;
-FUNCTION: void gluQuadricOrientation ( GLUquadric* quad, GLenum orientation ) ;
-FUNCTION: void gluQuadricTexture ( GLUquadric* quad, GLboolean texture ) ;
-FUNCTION: GLint gluScaleImage ( GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, void* dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut ) ;
-FUNCTION: void gluSphere ( GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks ) ;
-FUNCTION: void gluTessBeginContour ( GLUtesselator* tess ) ;
-FUNCTION: void gluTessBeginPolygon ( GLUtesselator* tess, GLvoid* data ) ;
-FUNCTION: void gluTessCallback ( GLUtesselator* tess, GLenum which, GLUfuncptr CallBackFunc ) ;
-FUNCTION: void gluTessEndContour ( GLUtesselator* tess ) ;
-FUNCTION: void gluTessEndPolygon ( GLUtesselator* tess ) ;
-FUNCTION: void gluTessNormal ( GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ ) ;
-FUNCTION: void gluTessProperty ( GLUtesselator* tess, GLenum which, GLdouble data ) ;
-FUNCTION: void gluTessVertex ( GLUtesselator* tess, GLdouble* location, GLvoid* data ) ;
-FUNCTION: GLint gluUnProject ( GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble* model, GLdouble* proj, GLint* view, GLdouble* objX, GLdouble* objY, GLdouble* objZ ) ;
-
-! Not present on Windows
-! FUNCTION: GLint gluBuild1DMipmapLevels ( GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data ) ;
-! FUNCTION: GLint gluBuild1DMipmaps ( GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, void* data ) ;
-! FUNCTION: GLint gluBuild2DMipmapLevels ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data ) ;
-! FUNCTION: GLint gluBuild2DMipmaps ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, void* data ) ;
-! FUNCTION: GLint gluBuild3DMipmapLevels ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data ) ;
-! FUNCTION: GLint gluBuild3DMipmaps ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* data ) ;
-! FUNCTION: GLboolean gluCheckExtension ( GLubyte* extName, GLubyte* extString ) ;
-! FUNCTION: GLint gluUnProject4 ( GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, GLdouble* model, GLdouble* proj, GLint* view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW ) ;
diff --git a/basis/opengl/glu/summary.txt b/basis/opengl/glu/summary.txt
deleted file mode 100644 (file)
index a90f4a3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-OpenGL binding - libGLU
diff --git a/basis/opengl/glu/tags.txt b/basis/opengl/glu/tags.txt
deleted file mode 100644 (file)
index bb863cf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-bindings
index acff2dcd9e0a7b04b5b1e418b56e51052b9af0ea..b7738332804694ba8dd5ae7ca708064ace7f1e6f 100644 (file)
@@ -15,19 +15,19 @@ HELP: do-enabled
 { $description "Wraps a quotation in " { $link glEnable } "/" { $link glDisable } " calls." } ;
 
 HELP: do-matrix
-{ $values { "mode" { $link GL_MODELVIEW } " or " { $link GL_PROJECTION } } { "quot" quotation } }
-{ $description "Saves and restores the matrix specified by " { $snippet "mode" } " before and after calling the quotation." } ;
+{ $values { "quot" quotation } }
+{ $description "Saves and restores the current matrix before and after calling the quotation." } ;
 
 HELP: gl-line
 { $values { "a" "a pair of integers" } { "b" "a pair of integers" } }
 { $description "Draws a line between two points." } ;
 
 HELP: gl-fill-rect
-{ $values { "dim" "a pair of integers" } }
+{ $values { "loc" "a pair of integers" } { "dim" "a pair of integers" } }
 { $description "Draws a filled rectangle with the top-left corner at the origin and the given dimensions." } ;
 
 HELP: gl-rect
-{ $values { "dim" "a pair of integers" } }
+{ $values { "loc" "a pair of integers" } { "dim" "a pair of integers" } }
 { $description "Draws the outline of a rectangle with the top-left corner at the origin and the given dimensions." } ;
 
 HELP: gen-gl-buffer
index e08a7487aec51fb941cf819d0399d1edea637c02..72ca8b8cdbbb2306d7a647aac6251b3197aea9b1 100644 (file)
@@ -3,8 +3,8 @@
 ! Portions copyright (C) 2008 Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types continuations kernel libc math macros
-namespaces math.vectors math.parser opengl.gl opengl.glu
-combinators arrays sequences splitting words byte-arrays assocs
+namespaces math.vectors math.parser opengl.gl combinators
+combinators.smart arrays sequences splitting words byte-arrays assocs
 colors colors.constants accessors generalizations locals fry
 specialized-arrays.float specialized-arrays.uint ;
 IN: opengl
@@ -16,10 +16,23 @@ IN: opengl
 : gl-clear ( color -- )
     gl-clear-color GL_COLOR_BUFFER_BIT glClear ;
 
+: error>string ( n -- string )
+    H{
+        { HEX: 0 "No error" }
+        { HEX: 0501 "Invalid value" }
+        { HEX: 0500 "Invalid enumerant" }
+        { HEX: 0502 "Invalid operation" }
+        { HEX: 0503 "Stack overflow" }
+        { HEX: 0504 "Stack underflow" }
+        { HEX: 0505 "Out of memory" }
+    } at "Unknown error" or ;
+
+TUPLE: gl-error code string ;
+
 : gl-error ( -- )
-    glGetError dup zero? [
-        "GL error: " over gluErrorString append throw
-    ] unless drop ;
+    glGetError dup 0 = [ drop ] [
+        dup error>string \ gl-error boa throw
+    ] if ;
 
 : do-enabled ( what quot -- )
     over glEnable dip glDisable ; inline
@@ -28,7 +41,7 @@ IN: opengl
     over glEnableClientState dip glDisableClientState ; inline
 
 : words>values ( word/value-seq -- value-seq )
-    [ dup word? [ execute ] when ] map ;
+    [ ?execute ] map ;
 
 : (all-enabled) ( seq quot -- )
     over [ glEnable ] each dip [ glDisable ] each ; inline
@@ -44,9 +57,8 @@ MACRO: all-enabled ( seq quot -- )
 MACRO: all-enabled-client-state ( seq quot -- )
     [ words>values ] dip '[ _ _ (all-enabled-client-state) ] ;
 
-: do-matrix ( mode quot -- )
-    swap [ glMatrixMode glPushMatrix call ] keep
-    glMatrixMode glPopMatrix ; inline
+: do-matrix ( quot -- )
+    glPushMatrix call glPopMatrix ; inline
 
 : gl-material ( face pname params -- )
     float-array{ } like glMaterialfv ;
@@ -67,42 +79,46 @@ MACRO: all-enabled-client-state ( seq quot -- )
 : gl-line ( a b -- )
     line-vertices GL_LINES 0 2 glDrawArrays ;
 
-: (rect-vertices) ( dim -- vertices )
+:: (rect-vertices) ( loc dim -- vertices )
     #! We use GL_LINE_STRIP with a duplicated first vertex
     #! instead of GL_LINE_LOOP to work around a bug in Apple's
     #! X3100 driver.
-    {
-        [ drop 0.5 0.5 ]
-        [ first 0.3 - 0.5 ]
-        [ [ first 0.3 - ] [ second 0.3 - ] bi ]
-        [ second 0.3 - 0.5 swap ]
-        [ drop 0.5 0.5 ]
-    } cleave 10 float-array{ } nsequence ;
-
-: rect-vertices ( dim -- )
+    loc first2 :> y :> x
+    dim first2 :> h :> w
+    [
+        x 0.5 +     y 0.5 +
+        x w + 0.3 - y 0.5 +
+        x w + 0.3 - y h + 0.3 -
+        x           y h + 0.3 -
+        x 0.5 +     y 0.5 +
+    ] float-array{ } output>sequence ;
+
+: rect-vertices ( loc dim -- )
     (rect-vertices) gl-vertex-pointer ;
 
 : (gl-rect) ( -- )
     GL_LINE_STRIP 0 5 glDrawArrays ;
 
-: gl-rect ( dim -- )
+: gl-rect ( loc dim -- )
     rect-vertices (gl-rect) ;
 
-: (fill-rect-vertices) ( dim -- vertices )
-    {
-        [ drop 0 0 ]
-        [ first 0 ]
-        [ first2 ]
-        [ second 0 swap ]
-    } cleave 8 float-array{ } nsequence ;
-
-: fill-rect-vertices ( dim -- )
+:: (fill-rect-vertices) ( loc dim -- vertices )
+    loc first2 :> y :> x
+    dim first2 :> h :> w
+    [
+        x      y
+        x w +  y
+        x w +  y h +
+        x      y h +
+    ] float-array{ } output>sequence ;
+
+: fill-rect-vertices ( loc dim -- )
     (fill-rect-vertices) gl-vertex-pointer ;
 
 : (gl-fill-rect) ( -- )
     GL_QUADS 0 4 glDrawArrays ;
 
-: gl-fill-rect ( dim -- )
+: gl-fill-rect ( loc dim -- )
     fill-rect-vertices (gl-fill-rect) ;
 
 : do-attribs ( bits quot -- )
@@ -148,9 +164,6 @@ MACRO: all-enabled-client-state ( seq quot -- )
 MACRO: set-draw-buffers ( buffers -- )
     words>values '[ _ (set-draw-buffers) ] ;
 
-: gl-look-at ( eye focus up -- )
-    [ first3 ] tri@ gluLookAt ;
-
 : gen-dlist ( -- id ) 1 glGenLists ;
 
 : make-dlist ( type quot -- id )
@@ -161,7 +174,7 @@ MACRO: set-draw-buffers ( buffers -- )
 : delete-dlist ( id -- ) 1 glDeleteLists ;
 
 : with-translation ( loc quot -- )
-    GL_MODELVIEW [ [ gl-translate ] dip call ] do-matrix ; inline
+    [ [ gl-translate ] dip call ] do-matrix ; inline
 
 : fix-coordinates ( point1 point2 -- x1 y2 x2 y2 )
     [ first2 [ >fixnum ] bi@ ] bi@ ;
@@ -173,6 +186,7 @@ MACRO: set-draw-buffers ( buffers -- )
     fix-coordinates glViewport ;
 
 : init-matrices ( -- )
+    #! Leaves with matrix mode GL_MODELVIEW
     GL_PROJECTION glMatrixMode
     glLoadIdentity
     GL_MODELVIEW glMatrixMode
index 7141caa67d03adafb8ce356ade68f5ea25246f63..3efdb43cd8b9616c4a662b5fe3458ce5fb06af79 100644 (file)
@@ -1,55 +1,19 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: tools.test opengl.textures opengl.textures.private
-images kernel namespaces ;
+opengl.textures.private images kernel namespaces accessors
+sequences ;
 IN: opengl.textures.tests
 
-[ ] [
-    T{ image
-       { dim { 3 5 } }
-       { component-order RGB }
-       { bitmap
-         B{
-             1 2 3 4 5 6 7 8 9
-             10 11 12 13 14 15 16 17 18
-             19 20 21 22 23 24 25 26 27
-             28 29 30 31 32 33 34 35 36
-             37 38 39 40 41 42 43 44 45
-         }
-       }
-    } "image" set
-] unit-test
-
 [
-    T{ image
-        { dim { 4 8 } }
-        { component-order RGB }
-        { bitmap
-          B{
-              1 2 3 4 5 6 7 8 9 7 8 9
-              10 11 12 13 14 15 16 17 18 16 17 18
-              19 20 21 22 23 24 25 26 27 25 26 27
-              28 29 30 31 32 33 34 35 36 34 35 36
-              37 38 39 40 41 42 43 44 45 43 44 45
-              37 38 39 40 41 42 43 44 45 43 44 45
-              37 38 39 40 41 42 43 44 45 43 44 45
-              37 38 39 40 41 42 43 44 45 43 44 45
-          }
-        }
+    {
+        { { 0 0 } { 10 0 } }
+        { { 0 20 } { 10 20 } }
     }
 ] [
-    "image" get power-of-2-image
-] unit-test
-
-[
-    T{ image
-       { dim { 0 0 } }
-       { component-order R32G32B32 }
-       { bitmap B{ } } }
-] [
-    T{ image
-       { dim { 0 0 } }
-       { component-order R32G32B32 }
-       { bitmap B{ } }
-    } power-of-2-image
+    {
+        { { 10 20 } { 30 20 } }
+        { { 10 30 } { 30 300 } }
+    }
+    [ [ image new swap >>dim ] map ] map image-locs
 ] unit-test
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 48cdafb..76e0c47
@@ -1,16 +1,27 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs cache colors.constants destructors fry kernel
-opengl opengl.gl combinators images grouping specialized-arrays.float
-locals sequences math math.vectors generalizations ;
+opengl opengl.gl opengl.capabilities combinators images
+images.tesselation grouping specialized-arrays.float sequences math
+math.vectors math.matrices generalizations fry arrays namespaces
+system ;
 IN: opengl.textures
 
+SYMBOL: non-power-of-2-textures?
+
+: check-extensions ( -- )
+    #! ATI frglx driver doesn't implement GL_ARB_texture_non_power_of_two properly.
+    #! See thread 'Linux font display problem' April 2009 on Factor-talk
+    gl-vendor "ATI Technologies Inc." = not os macosx? or [
+        "2.0" { "GL_ARB_texture_non_power_of_two" }
+        has-gl-version-or-extensions?
+        non-power-of-2-textures? set
+    ] when ;
+
 : gen-texture ( -- id ) [ glGenTextures ] (gen-gl-object) ;
 
 : delete-texture ( id -- ) [ glDeleteTextures ] (delete-gl-object) ;
 
-TUPLE: texture loc dim texture-coords texture display-list disposed ;
-
 GENERIC: component-order>format ( component-order -- format type )
 
 M: RGB component-order>format drop GL_RGB GL_UNSIGNED_BYTE ;
@@ -18,99 +29,150 @@ M: BGR component-order>format drop GL_BGR GL_UNSIGNED_BYTE ;
 M: RGBA component-order>format drop GL_RGBA GL_UNSIGNED_BYTE ;
 M: ARGB component-order>format drop GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8_REV ;
 M: BGRA component-order>format drop GL_BGRA_EXT GL_UNSIGNED_BYTE ;
+M: BGRX component-order>format drop GL_BGRA_EXT GL_UNSIGNED_BYTE ;
+M: LA component-order>format drop GL_LUMINANCE_ALPHA GL_UNSIGNED_BYTE ;
+M: L component-order>format drop GL_LUMINANCE GL_UNSIGNED_BYTE ;
 
-<PRIVATE
+SLOT: display-list
 
-: repeat-last ( seq n -- seq' )
-    over peek pad-tail concat ;
+: draw-texture ( texture -- ) display-list>> [ glCallList ] when* ;
 
-: power-of-2-bitmap ( rows dim size -- bitmap dim )
-    '[
-        first2
-        [ [ _ ] dip '[ _ group _ repeat-last ] map ]
-        [ repeat-last ]
-        bi*
-    ] keep ;
+GENERIC: draw-scaled-texture ( dim texture -- )
+
+<PRIVATE
 
-: image-rows ( image -- rows )
-    [ bitmap>> ]
-    [ dim>> first ]
-    [ component-order>> bytes-per-pixel ]
-    tri * group ; inline
-
-: power-of-2-image ( image -- image )
-    dup dim>> [ 0 = ] all? [
-        clone dup
-        [ image-rows ]
-        [ dim>> [ next-power-of-2 ] map ]
-        [ component-order>> bytes-per-pixel ] tri
-        power-of-2-bitmap
-        [ >>bitmap ] [ >>dim ] bi*
+TUPLE: single-texture image dim loc texture-coords texture display-list disposed ;
+
+: adjust-texture-dim ( dim -- dim' )
+    non-power-of-2-textures? get [
+        [ next-power-of-2 ] map
     ] unless ;
 
-:: make-texture ( image -- id )
+: (tex-image) ( image bitmap -- )
+    [
+        [ GL_TEXTURE_2D 0 GL_RGBA ] dip
+        [ dim>> adjust-texture-dim first2 0 ]
+        [ component-order>> component-order>format ] bi
+    ] dip
+    glTexImage2D ;
+
+: (tex-sub-image) ( image -- )
+    [ GL_TEXTURE_2D 0 0 0 ] dip
+    [ dim>> first2 ] [ component-order>> component-order>format ] [ bitmap>> ] tri
+    glTexSubImage2D ;
+
+: make-texture ( image -- id )
+    #! We use glTexSubImage2D to work around the power of 2 texture size
+    #! limitation
     gen-texture [
         GL_TEXTURE_BIT [
             GL_TEXTURE_2D swap glBindTexture
-            GL_TEXTURE_2D
-            0
-            GL_RGBA
-            image dim>> first2
-            0
-            image component-order>> component-order>format
-            image bitmap>>
-            glTexImage2D
+            non-power-of-2-textures? get
+            [ dup bitmap>> (tex-image) ]
+            [ [ f (tex-image) ] [ (tex-sub-image) ] bi ] if
         ] do-attribs
     ] keep ;
 
 : init-texture ( -- )
-    GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_LINEAR glTexParameteri
-    GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR glTexParameteri
+    GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST glTexParameteri
+    GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST glTexParameteri
     GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEAT glTexParameteri
     GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEAT glTexParameteri ;
 
-: draw-textured-rect ( dim texture -- )
+: with-texturing ( quot -- )
     GL_TEXTURE_2D [
         GL_TEXTURE_BIT [
             GL_TEXTURE_COORD_ARRAY [
                 COLOR: white gl-color
-                dup loc>> [
-                    [ [ GL_TEXTURE_2D ] dip texture>> glBindTexture ]
-                    [ init-texture texture-coords>> gl-texture-coord-pointer ] bi
-                    fill-rect-vertices (gl-fill-rect)
-                    GL_TEXTURE_2D 0 glBindTexture
-                ] with-translation
+                call
             ] do-enabled-client-state
         ] do-attribs
-    ] do-enabled ;
+    ] do-enabled ; inline
+
+: (draw-textured-rect) ( dim texture -- )
+    [ loc>> ]
+    [ [ GL_TEXTURE_2D ] dip texture>> glBindTexture ]
+    [ init-texture texture-coords>> gl-texture-coord-pointer ] tri
+    swap gl-fill-rect ;
 
-: texture-coords ( dim -- coords )
-    [ dup next-power-of-2 /f ] map
-    { { 0 0 } { 1 0 } { 1 1 } { 0 1 } } [ v* ] with map
-    float-array{ } join ;
+: draw-textured-rect ( dim texture -- )
+    [
+        [ image>> has-alpha? [ GL_BLEND glDisable ] unless ]
+        [ (draw-textured-rect) GL_TEXTURE_2D 0 glBindTexture ]
+        [ image>> has-alpha? [ GL_BLEND glEnable ] unless ]
+        tri
+    ] with-texturing ;
+
+: texture-coords ( texture -- coords )
+    [ [ dim>> ] [ image>> dim>> adjust-texture-dim ] bi v/ ]
+    [
+        image>> upside-down?>>
+        { { 0 1 } { 1 1 } { 1 0 } { 0 0 } }
+        { { 0 0 } { 1 0 } { 1 1 } { 0 1 } } ?
+    ] bi
+    [ v* ] with map float-array{ } join ;
 
 : make-texture-display-list ( texture -- dlist )
     GL_COMPILE [ [ dim>> ] keep draw-textured-rect ] make-dlist ;
 
-PRIVATE>
-
-: <texture> ( image loc -- texture )
-    texture new swap >>loc
-    swap
-    [ dim>> >>dim ] keep
-    [ dim>> product 0 = ] keep '[
-        _
-        [ dim>> texture-coords >>texture-coords ]
-        [ power-of-2-image make-texture >>texture ] bi
+: <single-texture> ( image loc -- texture )
+    single-texture new swap >>loc swap [ >>image ] [ dim>> >>dim ] bi
+    dup image>> dim>> product 0 = [
+        dup texture-coords >>texture-coords
+        dup image>> make-texture >>texture
         dup make-texture-display-list >>display-list
     ] unless ;
 
-M: texture dispose*
+M: single-texture dispose*
     [ texture>> [ delete-texture ] when* ]
     [ display-list>> [ delete-dlist ] when* ] bi ;
 
-: draw-texture ( texture -- )
-    display-list>> [ glCallList ] when* ;
+M: single-texture draw-scaled-texture
+    dup texture>> [ draw-textured-rect ] [ 2drop ] if ;
+
+TUPLE: multi-texture grid display-list loc disposed ;
+
+: image-locs ( image-grid -- loc-grid )
+    [ first [ dim>> first ] map ] [ [ first dim>> second ] map ] bi
+    [ 0 [ + ] accumulate nip ] bi@
+    cross-zip flip ;
+
+: <texture-grid> ( image-grid loc -- grid )
+    [ dup image-locs ] dip
+    '[ [ _ v+ <single-texture> |dispose ] 2map ] 2map ;
+
+: draw-textured-grid ( grid -- )
+    [ [ [ dim>> ] keep (draw-textured-rect) ] each ] each ;
+
+: grid-has-alpha? ( grid -- ? )
+    first first image>> has-alpha? ;
+
+: make-textured-grid-display-list ( grid -- dlist )
+    GL_COMPILE [
+        [
+            [ grid-has-alpha? [ GL_BLEND glDisable ] unless ]
+            [ [ [ [ dim>> ] keep (draw-textured-rect) ] each ] each ]
+            [ grid-has-alpha? [ GL_BLEND glEnable ] unless ] tri
+            GL_TEXTURE_2D 0 glBindTexture
+        ] with-texturing
+    ] make-dlist ;
 
-: draw-scaled-texture ( dim texture -- )
-    dup texture>> [ draw-textured-rect ] [ 2drop ] if ;
\ No newline at end of file
+: <multi-texture> ( image-grid loc -- multi-texture )
+    [
+        [
+            <texture-grid> dup
+            make-textured-grid-display-list
+        ] keep
+        f multi-texture boa
+    ] with-destructors ;
+
+M: multi-texture dispose* grid>> [ [ dispose ] each ] each ;
+
+CONSTANT: max-texture-size { 512 512 }
+
+PRIVATE>
+
+: <texture> ( image loc -- texture )
+    over dim>> max-texture-size [ <= ] 2all?
+    [ <single-texture> ]
+    [ [ max-texture-size tesselate ] dip <multi-texture> ] if ;
index 9cbed1f752e961dab54e20c53eed411730713263..b9e00b6c8d879f550ccf256fe801a175bcb0712b 100644 (file)
@@ -1,11 +1,12 @@
-! Copyright (C) 2007 Elie CHAFTARI
+! Copyright (C) 2007 Elie CHAFTARI, 2009 Maxim Savchenko
 ! See http://factorcode.org/license.txt for BSD license.
 !
 ! Tested with OpenSSL 0.9.8a_0 on Mac OS X 10.4.9 PowerPC
 !
 ! export LD_LIBRARY_PATH=/opt/local/lib
 
-USING: alien alien.syntax combinators kernel system ;
+USING: alien alien.syntax combinators kernel system
+alien.libraries ;
 
 IN: openssl.libcrypto
 
@@ -159,3 +160,65 @@ FUNCTION: int RSA_check_key ( void* rsa ) ;
 FUNCTION: void RSA_free ( void* rsa ) ;
 
 FUNCTION: int RSA_print_fp ( void* fp, void* x, int offset ) ;
+
+! ===============================================
+! objects.h
+! ===============================================
+
+FUNCTION: int OBJ_sn2nid ( char* s ) ;
+
+! ===============================================
+! bn.h
+! ===============================================
+
+FUNCTION: int BN_num_bits ( void* a ) ;
+
+FUNCTION: void* BN_bin2bn ( void* s, int len, void* ret ) ;
+
+FUNCTION: int BN_bn2bin ( void* a, void* to ) ;
+
+FUNCTION: void BN_clear_free ( void* a ) ;
+
+! ===============================================
+! ec.h
+! ===============================================
+
+CONSTANT: POINT_CONVERSION_COMPRESSED 2
+CONSTANT: POINT_CONVERSION_UNCOMPRESSED 4
+CONSTANT: POINT_CONVERSION_HYBRID 6
+
+FUNCTION: int EC_GROUP_get_degree ( void* group ) ;
+
+FUNCTION: void* EC_POINT_new ( void* group ) ;
+
+FUNCTION: void EC_POINT_clear_free ( void* point ) ;
+
+FUNCTION: int EC_POINT_point2oct ( void* group, void* point, int form, void* buf, int len, void* ctx ) ;
+
+FUNCTION: int EC_POINT_oct2point ( void* group, void* point, void* buf, int len, void* ctx ) ;
+
+FUNCTION: void* EC_KEY_new_by_curve_name ( int nid ) ;
+
+FUNCTION: void EC_KEY_free ( void* r ) ;
+
+FUNCTION: int EC_KEY_set_private_key ( void* key, void* priv_key ) ;
+
+FUNCTION: int EC_KEY_set_public_key ( void* key, void* pub_key ) ;
+
+FUNCTION: int EC_KEY_generate_key ( void* eckey ) ;
+
+FUNCTION: void* EC_KEY_get0_group ( void* key ) ;
+
+FUNCTION: void* EC_KEY_get0_private_key ( void* key ) ;
+
+FUNCTION: void* EC_KEY_get0_public_key ( void* key ) ;
+
+! ===============================================
+! ecdsa.h
+! ===============================================
+
+FUNCTION: int ECDSA_size ( void* eckey ) ;
+
+FUNCTION: int ECDSA_sign ( int type, void* dgst, int dgstlen, void* sig, void* siglen, void* eckey ) ;
+
+FUNCTION: int ECDSA_verify ( int type, void* dgst, int dgstlen, void* sig, int siglen, void* eckey ) ;
index e512e3134c66e644de062a9e8826fc1c02c2ab48..21f712fdc85f9420af21bf4e3d2e43a0436360a6 100644 (file)
@@ -2,7 +2,8 @@
 ! Portions copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.syntax combinators kernel system namespaces
-assocs parser lexer sequences words quotations math.bitwise ;
+assocs parser lexer sequences words quotations math.bitwise
+alien.libraries ;
 
 IN: openssl.libssl
 
@@ -279,12 +280,12 @@ H{ } clone verify-messages set-global
 
 : verify-message ( n -- word ) verify-messages get-global at ;
 
-: X509_V_:
+SYNTAX: X509_V_:
     scan "X509_V_" prepend create-in
     scan-word
     [ 1quotation (( -- value )) define-inline ]
     [ verify-messages get set-at ]
-    2bi ; parsing
+    2bi ;
 
 >>
 
index 27cba6d6e729b22a7e45bd01a31e25b5c2642edc..3b9739fb0f143dc6169b06dcfb972737d1de99b3 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types arrays assocs byte-arrays io
 io.binary io.streams.string kernel math math.parser namespaces
-make parser prettyprint quotations sequences strings vectors
+make parser quotations sequences strings vectors
 words macros math.functions math.bitwise fry generalizations
 combinators.smart io.streams.byte-array io.encodings.binary
 math.vectors combinators multiline endian ;
index 7683b788900748fda40c732349e8ea8c630733ec..45b7a9cb319c72e4507284ed3cb34f45c2c6614e 100644 (file)
@@ -3,7 +3,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 !
 ! pangocairo bindings, from pango/pangocairo.h
-USING: alien alien.syntax combinators system cairo.ffi ;
+USING: alien alien.syntax combinators system cairo.ffi
+alien.libraries ;
 IN: pango.cairo
 
 << {
@@ -85,4 +86,4 @@ FUNCTION: void
 pango_cairo_layout_path ( cairo_t* cr, PangoLayout* layout ) ;
 
 FUNCTION: void
-pango_cairo_error_underline_path ( cairo_t* cr, double x, double y, double width, double height ) ;
\ No newline at end of file
+pango_cairo_error_underline_path ( cairo_t* cr, double x, double y, double width, double height ) ;
index 540d1cb9f770a932d51f219ba792ac3fe1b07cfc..ec5afa3c3d1b924d85c436806e738c0caec12240 100644 (file)
@@ -2,7 +2,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license
 USING: arrays system alien.destructors alien.c-types alien.syntax alien
-combinators math.rectangles kernel math ;
+combinators math.rectangles kernel math alien.libraries ;
 IN: pango
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -34,4 +34,4 @@ C-STRUCT: PangoRectangle
 : PangoRectangle>rect ( PangoRectangle -- rect )
     [ [ PangoRectangle-x pango>float ] [ PangoRectangle-y pango>float ] bi 2array ]
     [ [ PangoRectangle-width pango>float ] [ PangoRectangle-height pango>float ] bi 2array ] bi
-    <rect> ;
\ No newline at end of file
+    <rect> ;
index a6d3cf0b21c610414d4dd4e2626f8b5529c0d702..cc83a55c7e65c2aed4ccf87afa2278e1fff37c3e 100644 (file)
@@ -3,7 +3,7 @@
 !
 USING: kernel tools.test peg peg.ebnf words math math.parser 
        sequences accessors peg.parsers parser namespaces arrays 
-       strings eval ;
+       strings eval unicode.data multiline ;
 IN: peg.ebnf.tests
 
 { T{ ebnf-non-terminal f "abc" } } [
@@ -520,3 +520,13 @@ Tok                = Spaces (Number | Special )
 { "\\" } [
   "\\" [EBNF foo="\\" EBNF]
 ] unit-test
+
+[ "USE: peg.ebnf [EBNF EBNF]" eval ] must-fail
+
+[ <" USE: peg.ebnf [EBNF
+    lol = a
+    lol = b
+  EBNF] "> eval
+] [
+    error>> [ redefined-rule? ] [ name>> "lol" = ] bi and
+] must-fail-with
index ca978862353cddd32fd420868e649e529652f1b4..b50ba685b8c06582583cb370ca972ac4660859a8 100644 (file)
@@ -5,13 +5,18 @@ sequences quotations vectors namespaces make math assocs
 continuations peg peg.parsers unicode.categories multiline\r
 splitting accessors effects sequences.deep peg.search\r
 combinators.short-circuit lexer io.streams.string stack-checker\r
-io combinators parser ;\r
+io combinators parser summary ;\r
 IN: peg.ebnf\r
 \r
 : rule ( name word -- parser )\r
   #! Given an EBNF word produced from EBNF: return the EBNF rule\r
   "ebnf-parser" word-prop at ;\r
 \r
+ERROR: no-rule rule parser ;\r
+\r
+: lookup-rule ( rule parser -- rule' )\r
+    2dup rule [ 2nip ] [ no-rule ] if* ; \r
+\r
 TUPLE: tokenizer any one many ;\r
 \r
 : default-tokenizer ( -- tokenizer )\r
@@ -34,9 +39,14 @@ TUPLE: tokenizer any one many ;
 : reset-tokenizer ( -- )\r
   default-tokenizer \ tokenizer set-global ;\r
 \r
-: TOKENIZER: \r
-  scan search [ "Tokenizer not found" throw ] unless*\r
-  execute \ tokenizer set-global ; parsing\r
+ERROR: no-tokenizer name ;\r
+\r
+M: no-tokenizer summary\r
+    drop "Tokenizer not found" ;\r
+\r
+SYNTAX: TOKENIZER: \r
+  scan dup search [ nip ] [ no-tokenizer ] if*\r
+  execute( -- tokenizer ) \ tokenizer set-global ;\r
 \r
 TUPLE: ebnf-non-terminal symbol ;\r
 TUPLE: ebnf-terminal symbol ;\r
@@ -128,28 +138,28 @@ PEG: escaper ( string -- ast )
   #! in the EBNF syntax itself.\r
   [\r
     {\r
-      [ dup blank?    ]\r
-      [ dup CHAR: " = ]\r
-      [ dup CHAR: ' = ]\r
-      [ dup CHAR: | = ]\r
-      [ dup CHAR: { = ]\r
-      [ dup CHAR: } = ]\r
-      [ dup CHAR: = = ]\r
-      [ dup CHAR: ) = ]\r
-      [ dup CHAR: ( = ]\r
-      [ dup CHAR: ] = ]\r
-      [ dup CHAR: [ = ]\r
-      [ dup CHAR: . = ]\r
-      [ dup CHAR: ! = ]\r
-      [ dup CHAR: & = ]\r
-      [ dup CHAR: * = ]\r
-      [ dup CHAR: + = ]\r
-      [ dup CHAR: ? = ]\r
-      [ dup CHAR: : = ]\r
-      [ dup CHAR: ~ = ]\r
-      [ dup CHAR: < = ]\r
-      [ dup CHAR: > = ]\r
-    } 0|| not nip    \r
+      [ blank?    ]\r
+      [ CHAR: " = ]\r
+      [ CHAR: ' = ]\r
+      [ CHAR: | = ]\r
+      [ CHAR: { = ]\r
+      [ CHAR: } = ]\r
+      [ CHAR: = = ]\r
+      [ CHAR: ) = ]\r
+      [ CHAR: ( = ]\r
+      [ CHAR: ] = ]\r
+      [ CHAR: [ = ]\r
+      [ CHAR: . = ]\r
+      [ CHAR: ! = ]\r
+      [ CHAR: & = ]\r
+      [ CHAR: * = ]\r
+      [ CHAR: + = ]\r
+      [ CHAR: ? = ]\r
+      [ CHAR: : = ]\r
+      [ CHAR: ~ = ]\r
+      [ CHAR: < = ]\r
+      [ CHAR: > = ]\r
+    } 1|| not\r
   ] satisfy repeat1 [ >string <ebnf-non-terminal> ] action ;\r
 \r
 : 'terminal' ( -- parser )\r
@@ -161,9 +171,9 @@ PEG: escaper ( string -- ast )
   #! Parse a valid foreign parser name\r
   [\r
     {\r
-      [ dup blank?    ]\r
-      [ dup CHAR: > = ]\r
-    } 0|| not nip    \r
+      [ blank?    ]\r
+      [ CHAR: > = ]\r
+    } 1|| not\r
   ] satisfy repeat1 [ >string ] action ;\r
 \r
 : 'foreign' ( -- parser )\r
@@ -258,7 +268,7 @@ DEFER: 'choice'
     "]]" token ensure-not ,\r
     "]?" token ensure-not ,\r
     [ drop t ] satisfy ,\r
-  ] seq* [ first ] action repeat0 [ >string ] action ;\r
+  ] seq* repeat0 [ concat >string ] action ;\r
 \r
 : 'ensure-not' ( -- parser )\r
   #! Parses the '!' syntax to ensure that \r
@@ -367,15 +377,16 @@ M: ebnf-tokenizer (transform) ( ast -- parser )
   (transform) \r
   dup parser-tokenizer \ tokenizer set-global\r
   ] if ;\r
+\r
+ERROR: redefined-rule name ;\r
+\r
+M: redefined-rule summary\r
+  name>> "Rule '" "' defined more than once" surround ;\r
   \r
 M: ebnf-rule (transform) ( ast -- parser )\r
   dup elements>> \r
   (transform) [\r
-    swap symbol>> dup get parser? [ \r
-      "Rule '" over append "' defined more than once" append throw \r
-    ] [ \r
-      set \r
-    ] if\r
+    swap symbol>> dup get parser? [ redefined-rule ] [ set ] if\r
   ] keep ;\r
 \r
 M: ebnf-sequence (transform) ( ast -- parser )\r
@@ -391,7 +402,7 @@ M: ebnf-choice (transform) ( ast -- parser )
   options>> [ (transform) ] map choice ;\r
 \r
 M: ebnf-any-character (transform) ( ast -- parser )\r
-  drop tokenizer any>> call ;\r
+  drop tokenizer any>> call( -- parser ) ;\r
 \r
 M: ebnf-range (transform) ( ast -- parser )\r
   pattern>> range-pattern ;\r
@@ -466,34 +477,39 @@ ERROR: bad-effect quot effect ;
     { [ dup (( -- b )) effect<= ] [ drop [ drop ] prepose ] }\r
     [ bad-effect ]\r
   } cond ;\r
+\r
+: ebnf-transform ( ast -- parser quot )\r
+  [ parser>> (transform) ]\r
+  [ code>> insert-escapes ]\r
+  [ parser>> ] tri build-locals  \r
+  [ string-lines parse-lines ] call( string -- quot ) ;\r
  \r
 M: ebnf-action (transform) ( ast -- parser )\r
-  [ parser>> (transform) ] [ code>> insert-escapes ] [ parser>> ] tri build-locals  \r
-  string-lines parse-lines check-action-effect action ;\r
+  ebnf-transform check-action-effect action ;\r
 \r
 M: ebnf-semantic (transform) ( ast -- parser )\r
-  [ parser>> (transform) ] [ code>> insert-escapes ] [ parser>> ] tri build-locals \r
-  string-lines parse-lines semantic ;\r
+  ebnf-transform semantic ;\r
 \r
 M: ebnf-var (transform) ( ast -- parser )\r
   parser>> (transform) ;\r
 \r
 M: ebnf-terminal (transform) ( ast -- parser )\r
-  symbol>> tokenizer one>> call ;\r
+  symbol>> tokenizer one>> call( symbol -- parser ) ;\r
+\r
+ERROR: ebnf-foreign-not-found name ;\r
+\r
+M: ebnf-foreign-not-found summary\r
+  name>> "Foreign word '" "' not found" surround ;\r
 \r
 M: ebnf-foreign (transform) ( ast -- parser )\r
-  dup word>> search\r
-  [ "Foreign word '" swap word>> append "' not found" append throw ] unless*\r
+  dup word>> search [ word>> ebnf-foreign-not-found ] unless*\r
   swap rule>> [ main ] unless* over rule [\r
     nip\r
   ] [\r
-    execute\r
+    execute( -- parser )\r
   ] if* ;\r
 \r
-: parser-not-found ( name -- * )\r
-  [\r
-    "Parser '" % % "' not found." %\r
-  ] "" make throw ;\r
+ERROR: parser-not-found name ;\r
 \r
 M: ebnf-non-terminal (transform) ( ast -- parser )\r
   symbol>>  [\r
@@ -504,16 +520,16 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   'ebnf' parse transform ;\r
 \r
 : check-parse-result ( result -- result )\r
-  dup [\r
-    dup remaining>> [ blank? ] trim empty? [\r
+  [\r
+    dup remaining>> [ blank? ] trim [\r
       [ \r
         "Unable to fully parse EBNF. Left to parse was: " %\r
         remaining>> % \r
       ] "" make throw\r
-    ] unless\r
+    ] unless-empty\r
   ] [\r
     "Could not parse EBNF" throw\r
-  ] if ;\r
+  ] if* ;\r
 \r
 : parse-ebnf ( string -- hashtable )\r
   'ebnf' (parse) check-parse-result ast>> transform ;\r
@@ -522,16 +538,18 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   parse-ebnf dup dup parser [ main swap at compile ] with-variable\r
   [ compiled-parse ] curry [ with-scope ast>> ] curry ;\r
 \r
-: <EBNF "EBNF>" reset-tokenizer parse-multiline-string parse-ebnf main swap at  \r
-  parsed reset-tokenizer ; parsing\r
+SYNTAX: <EBNF\r
+  "EBNF>"\r
+  reset-tokenizer parse-multiline-string parse-ebnf main swap at  \r
+  parsed reset-tokenizer ;\r
 \r
-: [EBNF "EBNF]" reset-tokenizer parse-multiline-string ebnf>quot nip \r
-  parsed \ call parsed reset-tokenizer ; parsing\r
+SYNTAX: [EBNF\r
+  "EBNF]"\r
+  reset-tokenizer parse-multiline-string ebnf>quot nip \r
+  parsed \ call parsed reset-tokenizer ;\r
 \r
-: EBNF: \r
+SYNTAX: EBNF: \r
   reset-tokenizer CREATE-WORD dup ";EBNF" parse-multiline-string  \r
-  ebnf>quot swapd 1 1 <effect> define-declared "ebnf-parser" set-word-prop \r
-  reset-tokenizer ; parsing\r
-\r
-\r
-\r
+  ebnf>quot swapd\r
+  (( input -- ast )) define-declared "ebnf-parser" set-word-prop \r
+  reset-tokenizer ;\r
index 5af5dba74811bd315ffe3b3b2e9775ea15fca681..1ccdafb2bbe27ecce00b298124ca756bc956f389 100644 (file)
@@ -1,2 +1,3 @@
+extensions
 text
 parsing
index aadbbaff16710a36a2c08e3c2cdca4a1affab7d3..93f407681e04f418c2ea02c979984cba7b482a28 100644 (file)
@@ -9,14 +9,14 @@ TUPLE: just-parser p1 ;
 
 CONSTANT: just-pattern
   [
-    execute dup [
+    dup [
       dup remaining>> empty? [ drop f ] unless
     ] when
   ]
 
 
 M: just-parser (compile) ( parser -- quot )
-  p1>> compile-parser just-pattern curry ;
+  p1>> compile-parser-quot just-pattern compose ;
 
 : just ( parser -- parser )
   just-parser boa wrap-peg ;
index 9a15dd210575ffc9f6629fbb9e66c252c8aaee44..7d5cb1e76a834c177d4352f7af700c74d1860d6b 100644 (file)
@@ -5,6 +5,8 @@ USING: kernel tools.test strings namespaces make arrays sequences
        peg peg.private peg.parsers accessors words math accessors ;
 IN: peg.tests
 
+\ parse must-infer
+
 [ ] [ reset-pegs ] unit-test
 
 [
index 5ac62239d787104da33d7f63aa46b7f74d29182c..dda36432e729aafd7184a96e9d2f46f323425128 100644 (file)
@@ -116,7 +116,7 @@ TUPLE: peg-head rule-id involved-set eval-set ;
   #! Evaluate a rule, return an ast resulting from it.
   #! Return fail if the rule failed. The rule has
   #! stack effect ( -- parse-result )
-  pos get swap execute process-rule-result ; inline
+  pos get swap execute( -- parse-result ) process-rule-result ; inline
 
 : memo ( pos id -- memo-entry )
   #! Return the result from the memo cache. 
@@ -155,18 +155,21 @@ TUPLE: peg-head rule-id involved-set eval-set ;
   dup pos>> pos set ans>>
   ; inline
 
-:: (setup-lr) ( r l s -- )
-  s head>> l head>> eq? [
-    l head>> s (>>head)
-    l head>> [ s rule-id>> suffix ] change-involved-set drop
-    r l s next>> (setup-lr)
-  ] unless ;
+:: (setup-lr) ( l s -- )
+  s [ 
+    s left-recursion? [ s throw ] unless
+    s head>> l head>> eq? [
+      l head>> s (>>head)
+      l head>> [ s rule-id>> suffix ] change-involved-set drop
+      l s next>> (setup-lr)
+    ] unless 
+  ] when ;
 
 :: setup-lr ( r l -- )
   l head>> [
     r rule-id V{ } clone V{ } clone peg-head boa l (>>head)
   ] unless
-  l lrstack get (setup-lr) ;
+  l lrstack get (setup-lr) ;
 
 :: lr-answer ( r p m -- ast )
   [let* |
@@ -216,8 +219,10 @@ TUPLE: peg-head rule-id involved-set eval-set ;
     lrstack get next>> lrstack set
     pos get m (>>pos)
     lr head>> [
-      ans lr (>>seed)
-      r p m lr-answer
+      m ans>> left-recursion? [
+        ans lr (>>seed)
+        r p m lr-answer
+     ] [ ans ] if 
     ] [
       ans m (>>ans)
       ans
@@ -244,14 +249,15 @@ TUPLE: peg-head rule-id involved-set eval-set ;
 
 : with-packrat ( input quot -- result )
   #! Run the quotation with a packrat cache active.
-  swap 
-    input set
+  [ 
+    swap input set
     0 pos set
     f lrstack set
     V{ } clone error-stack set
     H{ } clone \ heads set
     H{ } clone \ packrat set
-  ] H{ } make-assoc swap bind ; inline
+    call
+  ] with-scope ; inline
 
 
 GENERIC: (compile) ( peg -- quot )
@@ -264,20 +270,16 @@ GENERIC: (compile) ( peg -- quot )
   ] if ;
     
 : execute-parser ( word -- result )
-  pos get apply-rule process-parser-result ; inline
-
-: parser-body ( parser -- quot )
-  #! Return the body of the word that is the compiled version
-  #! of the parser.
-  gensym 2dup swap peg>> (compile) (( -- result )) define-declared
-  swap dupd id>> "peg-id" set-word-prop
-  [ execute-parser ] curry ;
+  pos get apply-rule process-parser-result ;
 
 : preset-parser-word ( parser -- parser word )
   gensym [ >>compiled ] keep ;
 
 : define-parser-word ( parser word -- )
-  swap parser-body (( -- result )) define-declared ;
+  #! Return the body of the word that is the compiled version
+  #! of the parser.
+  2dup swap peg>> (compile) (( -- result )) define-declared
+  swap id>> "peg-id" set-word-prop ;
 
 : compile-parser ( parser -- word )
   #! Look to see if the given parser has been compiled.
@@ -292,24 +294,27 @@ GENERIC: (compile) ( peg -- quot )
     preset-parser-word [ define-parser-word ] keep
   ] if* ;
 
+: compile-parser-quot ( parser -- quot )
+  compile-parser [ execute-parser ] curry ;
+
 SYMBOL: delayed
 
 : fixup-delayed ( -- )
   #! Work through all delayed parsers and recompile their
   #! words to have the correct bodies.
   delayed get [
-    call compile-parser 1quotation (( -- result )) define-declared
+    call( -- parser ) compile-parser-quot (( -- result )) define-declared
   ] assoc-each ;
 
 : compile ( parser -- word )
   [
     H{ } clone delayed [ 
-      compile-parser fixup-delayed 
+      compile-parser-quot (( -- result )) define-temp fixup-delayed 
     ] with-variable
   ] with-compilation-unit ;
 
 : compiled-parse ( state word -- result )
-  swap [ execute [ error-stack get first throw ] unless* ] with-packrat ; inline 
+  swap [ execute( -- result ) [ error-stack get first throw ] unless* ] with-packrat ;
 
 : (parse) ( input parser -- result )
   dup word? [ compile ] unless compiled-parse ;
@@ -411,8 +416,8 @@ M: seq-parser (compile) ( peg -- quot )
   [
     [ input-slice V{ } clone <parse-result> ] %
     [
-      parsers>> unclip compile-parser 1quotation [ parse-seq-element ] curry ,
-      [ compile-parser 1quotation [ merge-errors ] compose [ parse-seq-element ] curry , ] each 
+      parsers>> unclip compile-parser-quot [ parse-seq-element ] curry ,
+      [ compile-parser-quot [ merge-errors ] compose [ parse-seq-element ] curry , ] each 
     ] { } make , \ 1&& , 
   ] [ ] make ;
 
@@ -421,8 +426,8 @@ TUPLE: choice-parser parsers ;
 M: choice-parser (compile) ( peg -- quot )
   [ 
     [
-      parsers>> [ compile-parser ] map 
-      unclip 1quotation , [ 1quotation [ merge-errors ] compose , ] each
+      parsers>> [ compile-parser-quot ] map 
+      unclip , [ [ merge-errors ] compose , ] each
     ] { } make , \ 0|| ,
   ] [ ] make ;
 
@@ -438,7 +443,7 @@ TUPLE: repeat0-parser p1 ;
   ] if* ; inline recursive
 
 M: repeat0-parser (compile) ( peg -- quot )
-  p1>> compile-parser 1quotation '[ 
+  p1>> compile-parser-quot '[ 
     input-slice V{ } clone <parse-result> _ swap (repeat) 
   ] ; 
 
@@ -452,7 +457,7 @@ TUPLE: repeat1-parser p1 ;
   ] if* ;
 
 M: repeat1-parser (compile) ( peg -- quot )
-  p1>> compile-parser 1quotation '[ 
+  p1>> compile-parser-quot '[ 
     input-slice V{ } clone <parse-result> _ swap (repeat) repeat1-empty-check  
   ] ; 
 
@@ -462,7 +467,7 @@ TUPLE: optional-parser p1 ;
   [ input-slice f <parse-result> ] unless* ;
 
 M: optional-parser (compile) ( peg -- quot )
-  p1>> compile-parser 1quotation '[ @ check-optional ] ;
+  p1>> compile-parser-quot '[ @ check-optional ] ;
 
 TUPLE: semantic-parser p1 quot ;
 
@@ -474,7 +479,7 @@ TUPLE: semantic-parser p1 quot ;
   ] if ; inline
 
 M: semantic-parser (compile) ( peg -- quot )
-  [ p1>> compile-parser 1quotation ] [ quot>> ] bi  
+  [ p1>> compile-parser-quot ] [ quot>> ] bi  
   '[ @ _ check-semantic ] ;
 
 TUPLE: ensure-parser p1 ;
@@ -483,7 +488,7 @@ TUPLE: ensure-parser p1 ;
   [ ignore <parse-result> ] [ drop f ] if ;
 
 M: ensure-parser (compile) ( peg -- quot )
-  p1>> compile-parser 1quotation '[ input-slice @ check-ensure ] ;
+  p1>> compile-parser-quot '[ input-slice @ check-ensure ] ;
 
 TUPLE: ensure-not-parser p1 ;
 
@@ -491,7 +496,7 @@ TUPLE: ensure-not-parser p1 ;
   [ drop f ] [ ignore <parse-result> ] if ;
 
 M: ensure-not-parser (compile) ( peg -- quot )
-  p1>> compile-parser 1quotation '[ input-slice @ check-ensure-not ] ;
+  p1>> compile-parser-quot '[ input-slice @ check-ensure-not ] ;
 
 TUPLE: action-parser p1 quot ;
 
@@ -503,12 +508,12 @@ TUPLE: action-parser p1 quot ;
   ] if ; inline
 
 M: action-parser (compile) ( peg -- quot )
-  [ p1>> compile-parser 1quotation ] [ quot>> ] bi '[ @ _ check-action ] ;
+  [ p1>> compile-parser-quot ] [ quot>> ] bi '[ @ _ check-action ] ;
 
 TUPLE: sp-parser p1 ;
 
 M: sp-parser (compile) ( peg -- quot )
-  p1>> compile-parser 1quotation '[ 
+  p1>> compile-parser-quot '[ 
     input-slice [ blank? ] trim-head-slice input-from pos set @ 
   ] ;
 
@@ -527,7 +532,7 @@ M: box-parser (compile) ( peg -- quot )
   #! to produce the parser to be compiled.
   #! This differs from 'delay' which calls
   #! it at run time.
-  quot>> call compile-parser 1quotation ;
+  quot>> call( -- parser ) compile-parser-quot ;
 
 PRIVATE>
 
@@ -616,9 +621,9 @@ PRIVATE>
 
 ERROR: parse-failed input word ;
 
-: PEG:
+SYNTAX: PEG:
   (:)
-  [let | def [ ] word [ ] |
+  [let | effect [ ] def [ ] word [ ] |
     [
       [
         [let | compiled-def [ def call compile ] |
@@ -626,11 +631,11 @@ ERROR: parse-failed input word ;
             dup compiled-def compiled-parse
             [ ast>> ] [ word parse-failed ] ?if
           ]
-          word swap define
+          word swap effect define-declared
         ]
       ] with-compilation-unit
     ] over push-all
-  ] ; parsing
+  ] ;
 
 USING: vocabs vocabs.loader ;
 
index b22a5ef0d0da6a0f258ac48e142948e616680099..96d89d461166b0315c793f5b5a7268f4dc852efd 100644 (file)
@@ -17,3 +17,5 @@ IN: peg.search.tests
   "abc 123 def 456" 'integer' [ 2 * number>string ] action replace
 ] unit-test
 
+\ search must-infer
+\ replace must-infer
index 8c80782a2e5da3d8dfcda6d3e91ee63aa798848f..67886312c67379383fd7504e7e36178fc2ea5c7b 100644 (file)
@@ -48,7 +48,7 @@ M: persistent-hash hashcode* nip assoc-size ;
 
 M: persistent-hash clone ;
 
-: PH{ \ } [ >persistent-hash ] parse-literal ; parsing
+SYNTAX: PH{ \ } [ >persistent-hash ] parse-literal ;
 
 M: persistent-hash pprint-delims drop \ PH{ \ } ;
 M: persistent-hash >pprint-sequence >alist ;
index cecd6dab539bb57b72f4722c0b114d691e7415d9..3a1f910532cfcf07e83806fa219899818ea1d4dc 100644 (file)
@@ -1,9 +1,9 @@
 USING: persistent.heaps tools.test ;
 IN: persistent.heaps.tests
 
-: test-input
+CONSTANT: test-input
     { { "hello" 3 } { "goodbye" 2 } { "whatever" 5 }
-      { "foo" 1 } { "bar" -1 } { "baz" -7 } { "bing" 0 } } ;
+      { "foo" 1 } { "bar" -1 } { "baz" -7 } { "bing" 0 } }
 
 [
     { { "baz" -7 } { "bar" -1 } { "bing" 0 } { "foo" 1 }
index 478fc0ad254ade4c7cffdac81b4fa9147f57f4ca..ae33b7c39aa7f024d06e87ada22923e584a57cf8 100644 (file)
@@ -179,7 +179,7 @@ M: persistent-vector equal?
 : >persistent-vector ( seq -- pvec )
     T{ persistent-vector } like ;
 
-: PV{ \ } [ >persistent-vector ] parse-literal ; parsing
+SYNTAX: PV{ \ } [ >persistent-vector ] parse-literal ;
 
 M: persistent-vector pprint-delims drop \ PV{ \ } ;
 M: persistent-vector >pprint-sequence ;
index bcd91a4d942a5970be9c6c61f04e5ca71ae51638..8004c1141fb978a2b136b69c794c490789076d84 100644 (file)
@@ -41,18 +41,18 @@ M: effect pprint* effect>string "(" ")" surround text ;
 : pprint-prefix ( word quot -- )
     <block swap pprint-word call block> ; inline
 
+M: parsing-word pprint*
+    \ POSTPONE: [ pprint-word ] pprint-prefix ;
+
 M: word pprint*
-    dup parsing-word? [
-        \ POSTPONE: [ pprint-word ] pprint-prefix
-    ] [
-        {
-            [ "break-before" word-prop line-break ]
-            [ pprint-word ]
-            [ ?start-group ]
-            [ ?end-group ]
-            [ "break-after" word-prop line-break ]
-        } cleave
-    ] if ;
+    [ pprint-word ] [ ?start-group ] [ ?end-group ] tri ;
+
+M: method-body pprint*
+    <block
+    \ M\ pprint-word
+    [ "method-class" word-prop pprint-word ]
+    [ "method-generic" word-prop pprint-word ] bi
+    block> ;
 
 M: real pprint* number>string text ;
 
@@ -206,8 +206,8 @@ M: curry pprint* pprint-object ;
 M: compose pprint* pprint-object ;
 
 M: wrapper pprint*
-    dup wrapped>> word? [
-        <block \ \ pprint-word wrapped>> pprint-word block>
-    ] [
-        pprint-object
-    ] if ;
+    {
+        { [ dup wrapped>> method-body? ] [ wrapped>> pprint* ] }
+        { [ dup wrapped>> word? ] [ <block \ \ pprint-word wrapped>> pprint-word block> ] }
+        [ pprint-object ]
+    } cond ;
index 2be725c0f65247045addf65c91e77974249c6222..f938ab30f763b32e77383b9b253f60bcbcdcdddd 100644 (file)
@@ -96,12 +96,12 @@ ARTICLE: "prettyprint-literal" "Literal prettyprinting protocol"
 { $code
     "TUPLE: rect w h ;"
     ""
-    ": RECT["
+    "SYNTAX: RECT["
     "    scan-word"
     "    scan-word \\ * assert="
     "    scan-word"
     "    scan-word \\ ] assert="
-    "    <rect> parsed ; parsing"
+    "    <rect> parsed ;"
 }
 "An example literal might be:"
 { $code "RECT[ 100 * 200 ]" }
index aaaf6b80d1040df7e062c0d26890568afa8e43f4..799d500c188256ac8a6c2de5d6e7f293b7658bba 100644 (file)
@@ -63,7 +63,7 @@ unit-test
 [ "USING: math ;\nIN: prettyprint.tests\n: bar ( x -- y ) 2 + ;\n" ]
 [ [ \ bar see ] with-string-writer ] unit-test
 
-: blah 
+: blah ( a a a a a a a a a a a a a a a a a a a a -- )
     drop
     drop
     drop
@@ -102,7 +102,7 @@ unit-test
         ] keep =
     ] with-scope ;
 
-GENERIC: method-layout
+GENERIC: method-layout ( a -- b )
 
 M: complex method-layout
     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -135,7 +135,7 @@ M: object method-layout ;
     [ \ method-layout see-methods ] with-string-writer "\n" split
 ] unit-test
 
-: soft-break-test
+: soft-break-test ( -- str )
     {
         "USING: kernel math sequences strings ;"
         "IN: prettyprint.tests"
@@ -152,7 +152,7 @@ M: object method-layout ;
 
 DEFER: parse-error-file
 
-: another-soft-break-test
+: another-soft-break-test ( -- str )
     {
         "USING: make sequences ;"
         "IN: prettyprint.tests"
@@ -166,7 +166,7 @@ DEFER: parse-error-file
     check-see
 ] unit-test
 
-: string-layout
+: string-layout ( -- str )
     {
         "USING: accessors debugger io kernel ;"
         "IN: prettyprint.tests"
@@ -180,29 +180,7 @@ DEFER: parse-error-file
     "string-layout-test" string-layout check-see
 ] unit-test
 
-! Define dummy words for the below...
-: <NSRect> ( a b c d -- e ) ;
-: <PixelFormat> ( -- fmt ) ;
-: send ( obj -- ) ;
-
-\ send soft "break-after" set-word-prop
-
-: final-soft-break-test
-    {
-        "USING: kernel sequences ;"
-        "IN: prettyprint.tests"
-        ": final-soft-break-layout ( class dim -- view )"
-        "    [ \"alloc\" send 0 0 ] dip first2 <NSRect>"
-        "    <PixelFormat> \"initWithFrame:pixelFormat:\" send"
-        "    dup 1 \"setPostsBoundsChangedNotifications:\" send"
-        "    dup 1 \"setPostsFrameChangedNotifications:\" send ;"
-    } ;
-
-[ t ] [
-    "final-soft-break-layout" final-soft-break-test check-see
-] unit-test
-
-: narrow-test
+: narrow-test ( -- str )
     {
         "USING: arrays combinators continuations kernel sequences ;"
         "IN: prettyprint.tests"
@@ -218,7 +196,7 @@ DEFER: parse-error-file
     "narrow-layout" narrow-test check-see
 ] unit-test
 
-: another-narrow-test
+: another-narrow-test ( -- str )
     {
         "IN: prettyprint.tests"
         ": another-narrow-layout ( -- obj )"
@@ -300,11 +278,7 @@ GENERIC: generic-see-test-with-f ( obj -- obj )
 M: f generic-see-test-with-f ;
 
 [ "USING: prettyprint.tests ;\nM: f generic-see-test-with-f ;\n" ] [
-    [ { POSTPONE: f generic-see-test-with-f } see ] with-string-writer
-] unit-test
-
-[ "USING: prettyprint.tests ;\nM: f generic-see-test-with-f ;\n" ] [
-    [ \ f \ generic-see-test-with-f method see ] with-string-writer
+    [ M\ f generic-see-test-with-f see ] with-string-writer
 ] unit-test
 
 PREDICATE: predicate-see-test < integer even? ;
@@ -326,10 +300,10 @@ INTERSECTION: intersection-see-test sequence number ;
     
 TUPLE: started-out-hustlin' ;
 
-GENERIC: ended-up-ballin'
+GENERIC: ended-up-ballin' ( a -- b )
 
 M: started-out-hustlin' ended-up-ballin' ; inline
 
 [ "USING: prettyprint.tests ;\nM: started-out-hustlin' ended-up-ballin' ; inline\n" ] [
-    [ { started-out-hustlin' ended-up-ballin' } see ] with-string-writer
+    [ M\ started-out-hustlin' ended-up-ballin' see ] with-string-writer
 ] unit-test
index 7ef15b9a2fb22de4c0dbc05c2832d32af2192e63..2286417dd1d71aef5a6fa12ec0228e9e12319d30 100644 (file)
@@ -1,10 +1,10 @@
 ! Copyright (C) 2003, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs colors combinators grouping io
+USING: arrays accessors assocs colors combinators grouping io
 io.streams.string io.styles kernel make math math.parser namespaces
 parser prettyprint.backend prettyprint.config prettyprint.custom
 prettyprint.sections quotations sequences sorting strings vocabs
-vocabs.parser words ;
+vocabs.parser words sets ;
 IN: prettyprint
 
 <PRIVATE
@@ -32,7 +32,7 @@ IN: prettyprint
     [ \ IN: pprint-word pprint-vocab ] with-pprint ;
 
 : in. ( vocab -- )
-    [ write-in nl ] when* ;
+    [ write-in ] when* ;
 
 : use. ( seq -- )
     [
@@ -40,33 +40,39 @@ IN: prettyprint
             \ USING: pprint-word
             [ pprint-vocab ] each
             \ ; pprint-word
-        ] with-pprint nl
+        ] with-pprint
     ] unless-empty ;
 
 : use/in. ( in use -- )
-    dupd remove [ { "syntax" "scratchpad" } member? not ] filter
-    use. in. ;
+    over "syntax" 2array diff
+    [ nip use. ]
+    [ empty? not and [ nl ] when ]
+    [ drop in. ]
+    2tri ;
 
 : vocab-names ( words -- vocabs )
     dictionary get
     [ [ words>> eq? nip ] with assoc-find 2drop ] curry map sift ;
 
 : prelude. ( -- )
-    in get use get vocab-names use/in. ;
+    in get use get vocab-names prune in get ".private" append swap remove use/in. ;
 
 [
     nl
-    "Restarts were invoked adding vocabularies to the search path." print
-    "To avoid doing this in the future, add the following USING:" print
-    "and IN: forms at the top of the source file:" print nl
-    prelude.
-    nl
+    { { font-style bold } { font-name "sans-serif" } } [
+        "Restarts were invoked adding vocabularies to the search path." print
+        "To avoid doing this in the future, add the following USING:" print
+        "and IN: forms at the top of the source file:" print nl
+    ] with-style
+    { { page-color T{ rgba f 0.8 0.8 0.8 1.0 } } } [ prelude. ] with-nesting
+    nl nl
 ] print-use-hook set-global
 
 PRIVATE>
 
 : with-use ( obj quot -- )
-    make-pprint use/in. do-pprint ; inline
+    make-pprint [ use/in. ] [ empty? not or [ nl ] when ] 2bi
+    do-pprint ; inline
 
 : with-in ( obj quot -- )
     make-pprint drop [ write-in bl ] when* do-pprint ; inline
diff --git a/basis/promises/authors.txt b/basis/promises/authors.txt
new file mode 100644 (file)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/basis/promises/promises-docs.factor b/basis/promises/promises-docs.factor
new file mode 100755 (executable)
index 0000000..d416842
--- /dev/null
@@ -0,0 +1,20 @@
+! Copyright (C) 2006 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax ;
+IN: promises
+
+HELP: promise 
+{ $values { "quot" { $quotation "( -- X )" } } { "promise" "a promise object" } }
+{ $description "Creates a promise to return a value. When forced this quotation is called and the value returned. The value is memorised so that calling " { $link force } " again does not call the quotation again, instead the previous value is returned directly." } ;
+
+HELP: force
+{ $values { "promise" "a promise object" } { "value" "a factor object" } }
+{ $description "Calls the quotation associated with the promise if it has not been called before, and returns the value. If the promise has been forced previously, returns the value from the previous call." } ;
+
+HELP: LAZY:
+{ $syntax "LAZY: word ( stack -- effect ) definition... ;" } 
+{ $values { "word" "a new word to define" } { "definition" "a word definition" } }
+{ $description "Creates a lazy word in the current vocabulary. When executed the word will return a " { $link promise } " that when forced, executes the word definition. Any values on the stack that are required by the word definition are captured along with the promise." } 
+{ $examples
+  { $example "USING: arrays sequences prettyprint promises ;" "IN: scratchpad" "LAZY: zeroes ( -- pair ) 0 zeroes 2array ;" "zeroes force second force first ." "0" }
+} ;
diff --git a/basis/promises/promises-tests.factor b/basis/promises/promises-tests.factor
new file mode 100644 (file)
index 0000000..79e7dc5
--- /dev/null
@@ -0,0 +1,7 @@
+IN: promises.tests
+USING: promises math tools.test ;
+
+LAZY: lazy-test ( a -- b ) 1 + ;
+
+{ 1 1 } [ lazy-test ] must-infer-as
+[ 3 ] [ 2 lazy-test force ] unit-test
\ No newline at end of file
diff --git a/basis/promises/promises.factor b/basis/promises/promises.factor
new file mode 100755 (executable)
index 0000000..c3951f4
--- /dev/null
@@ -0,0 +1,22 @@
+! Copyright (C) 2004, 2006 Chris Double, Matthew Willis.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays kernel sequences math arrays namespaces
+parser effects generalizations fry words accessors ;
+IN: promises
+
+TUPLE: promise quot forced? value ;
+
+: promise ( quot -- promise ) f f \ promise boa ;
+
+: force ( promise -- value )
+    dup forced?>> [
+        dup quot>> call( -- value ) >>value
+        t >>forced?
+    ] unless
+    value>> ;
+
+: make-lazy-quot ( quot effect -- quot )
+    in>> length '[ _ _ ncurry promise ] ;
+
+SYNTAX: LAZY:
+    (:) [ make-lazy-quot ] [ 2nip ] 3bi define-declared ;
diff --git a/basis/promises/summary.txt b/basis/promises/summary.txt
new file mode 100644 (file)
index 0000000..d64fe20
--- /dev/null
@@ -0,0 +1 @@
+Lazy thunks
diff --git a/basis/promises/tags.txt b/basis/promises/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/basis/quoting/quoting-docs.factor b/basis/quoting/quoting-docs.factor
deleted file mode 100644 (file)
index 5fb68db..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-! Copyright (C) 2009 Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax strings ;
-IN: quoting
-
-HELP: quote?
-{ $values
-     { "ch" "a character" }
-     { "?" "a boolean" }
-}
-{ $description "Returns true if the character is a single or double quote." } ;
-
-HELP: quoted?
-{ $values
-     { "str" string }
-     { "?" "a boolean" }
-}
-{ $description "Returns true if a string is surrounded by matching single or double quotes as the first and last characters." } ;
-
-HELP: unquote
-{ $values
-     { "str" string }
-     { "newstr" string }
-}
-{ $description "Removes a pair of matching single or double quotes from a string." } ;
-
-ARTICLE: "quoting" "Quotation marks"
-"The " { $vocab-link "quoting" } " vocabulary is for removing quotes from a string." $nl
-"Removing quotes:"
-{ $subsection unquote } ;
-
-ABOUT: "quoting"
index 0cc28a135401b7d5be36c0c718ac39f3800ff05b..f024d9c4a7ce9d6f433d3a7c9343d40918d7ed48 100644 (file)
@@ -3,8 +3,9 @@
 USING: tools.test quoting ;
 IN: quoting.tests
 
-
-[ "abc" ] [ "'abc'" unquote ] unit-test
-[ "abc" ] [ "\"abc\"" unquote ] unit-test
-[ "'abc" ] [ "'abc" unquote ] unit-test
-[ "abc'" ] [ "abc'" unquote ] unit-test
+[ f ] [ "" quoted? ] unit-test
+[ t ] [ "''" quoted? ] unit-test
+[ t ] [ "\"\"" quoted? ] unit-test
+[ t ] [ "\"Circus Maximus\"" quoted? ] unit-test
+[ t ] [ "'Circus Maximus'" quoted? ] unit-test
+[ f ] [ "Circus Maximus" quoted? ] unit-test
index 9e25037cd996952df3f2cc7ece96236b470663ca..5b09347c8c21ca1cc3b7e2f7984104a553d4b7f5 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators.short-circuit kernel math sequences strings ;
+USING: sequences math kernel strings combinators.short-circuit ;
 IN: quoting
 
 : quote? ( ch -- ? ) "'\"" member? ;
@@ -13,4 +13,4 @@ IN: quoting
     } 1&& ;
 
 : unquote ( str -- newstr )
-    dup quoted? [ but-last-slice rest-slice >string ] when ;
+    dup quoted? [ but-last-slice rest-slice >string ] when ;
\ No newline at end of file
index b6f222cce98c6062f8f1da3d2c2b5f43fd729f4e..a219f0ba8b24cfcb6f21e5ffef844c2c099a3e20 100644 (file)
@@ -37,14 +37,14 @@ HELP: key-ref
 { $class-description "Instances of this class identify a key in an associative structure. New key references are created by calling " { $link <key-ref> } "." } ;
 
 HELP: <key-ref>
-{ $values { "key" object } { "assoc" "an assoc" } { "ref" key-ref } }
+{ $values { "assoc" "an assoc" } { "key" object } { "key-ref" key-ref } }
 { $description "Creates a reference to a key stored in an assoc." } ;
 
 HELP: value-ref
 { $class-description "Instances of this class identify a value associated to a key in an associative structure. New value references are created by calling " { $link <value-ref> } "." } ;
 
 HELP: <value-ref>
-{ $values { "key" object } { "assoc" "an assoc" } { "ref" value-ref } }
+{ $values { "assoc" "an assoc" } { "key" object } { "value-ref" value-ref } }
 { $description "Creates a reference to the value associated with " { $snippet "key" } " in " { $snippet "assoc" } "." } ;
 
 { get-ref set-ref delete-ref } related-words
index 5f21dad7760c2dd91d153adcc6ca895016df9ab5..0164a1ea57872c3b5c33ca25056af2cffd542fc7 100644 (file)
@@ -12,11 +12,11 @@ GENERIC: get-ref ( ref -- obj )
 GENERIC: set-ref ( obj ref -- )
 
 TUPLE: key-ref < ref ;
-C: <key-ref> key-ref ( assoc key -- ref )
+C: <key-ref> key-ref
 M: key-ref get-ref key>> ;
 M: key-ref set-ref >ref< rename-at ;
 
 TUPLE: value-ref < ref ;
-C: <value-ref> value-ref ( assoc key -- ref )
+C: <value-ref> value-ref
 M: value-ref get-ref >ref< at ;
 M: value-ref set-ref >ref< set-at ;
index ffaed2db62367001df0bec3c848bc9b05133ef84..2916ef7c32be08352ba6ed3836443e663e37b8a3 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel arrays accessors fry sequences regexp.classes ;
-FROM: math.ranges => [a,b] ;
+USING: kernel arrays accessors fry sequences regexp.classes
+math.ranges math ;
 IN: regexp.ast
 
 TUPLE: negation term ;
@@ -21,12 +21,12 @@ CONSTANT: epsilon T{ tagged-epsilon { tag t } }
 TUPLE: concatenation first second ;
 
 : <concatenation> ( seq -- concatenation )
-    [ epsilon ] [ unclip [ concatenation boa ] reduce ] if-empty ;
+    [ epsilon ] [ [ ] [ concatenation boa ] map-reduce ] if-empty ;
 
 TUPLE: alternation first second ;
 
 : <alternation> ( seq -- alternation )
-    unclip [ alternation boa ] reduce ;
+    [ ] [ alternation boa ] map-reduce ;
 
 TUPLE: star term ;
 C: <star> star
@@ -37,8 +37,7 @@ C: <with-options> with-options
 TUPLE: options on off ;
 C: <options> options
 
-SINGLETONS: unix-lines dotall multiline comments case-insensitive
-unicode-case reversed-regexp ;
+SINGLETONS: unix-lines dotall multiline case-insensitive reversed-regexp ;
 
 : <maybe> ( term -- term' )
     f <concatenation> 2array <alternation> ;
@@ -50,10 +49,20 @@ unicode-case reversed-regexp ;
     <array> <concatenation> ;
 
 GENERIC: <times> ( term times -- term' )
+
 M: at-least <times>
     n>> swap [ repetition ] [ <star> ] bi 2array <concatenation> ;
+
+: to-times ( term n -- ast )
+    dup zero?
+    [ 2drop epsilon ]
+    [ dupd 1- to-times 2array <concatenation> <maybe> ]
+    if ;
+
 M: from-to <times>
-    [ n>> ] [ m>> ] bi [a,b] swap '[ _ repetition ] map <alternation> ;
+    [ n>> swap repetition ]
+    [ [ m>> ] [ n>> ] bi - to-times ] 2bi
+    2array <concatenation> ;
 
 : char-class ( ranges ? -- term )
     [ <or-class> ] dip [ <not-class> ] when ;
index 7c1b2f22790bfdca05f14a555a40b7eaa3ce2abd..a4a77d97e963679ec4dbe6317c19e936c2ce96d9 100644 (file)
@@ -1 +1,2 @@
 Doug Coleman
+Daniel Ehrenberg
index d26ff7f69ceab3e20812c1d96a5f34a3b233456b..a1c4e3ca2a53cc3e01725d62f307a8a45b3e823c 100644 (file)
@@ -2,20 +2,33 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel math math.order words combinators locals
 ascii unicode.categories combinators.short-circuit sequences
-fry macros arrays assocs sets classes mirrors ;
+fry macros arrays assocs sets classes mirrors unicode.script
+unicode.data ;
 IN: regexp.classes
 
-SINGLETONS: any-char any-char-no-nl
-letter-class LETTER-class Letter-class digit-class
+SINGLETONS: dot letter-class LETTER-class Letter-class digit-class
 alpha-class non-newline-blank-class
 ascii-class punctuation-class java-printable-class blank-class
 control-character-class hex-digit-class java-blank-class c-identifier-class
 unmatchable-class terminator-class word-boundary-class ;
 
-SINGLETONS: beginning-of-input ^ end-of-input $ end-of-file word-break ;
+SINGLETONS: beginning-of-input ^ end-of-input $ end-of-file
+^unix $unix word-break ;
 
-TUPLE: range from to ;
-C: <range> range
+TUPLE: range-class from to ;
+C: <range-class> range-class
+
+TUPLE: primitive-class class ;
+C: <primitive-class> primitive-class
+
+TUPLE: category-class category ;
+C: <category-class> category-class
+
+TUPLE: category-range-class category ;
+C: <category-range-class> category-range-class
+
+TUPLE: script-class script ;
+C: <script-class> script-class
 
 GENERIC: class-member? ( obj class -- ? )
 
@@ -23,15 +36,9 @@ M: t class-member? ( obj class -- ? ) 2drop t ;
 
 M: integer class-member? ( obj class -- ? ) = ;
 
-M: range class-member? ( obj class -- ? )
+M: range-class class-member? ( obj class -- ? )
     [ from>> ] [ to>> ] bi between? ;
 
-M: any-char class-member? ( obj class -- ? )
-    2drop t ;
-
-M: any-char-no-nl class-member? ( obj class -- ? )
-    drop CHAR: \n = not ;
-
 M: letter-class class-member? ( obj class -- ? )
     drop letter? ;
             
@@ -99,21 +106,27 @@ M: unmatchable-class class-member? ( obj class -- ? )
 M: terminator-class class-member? ( obj class -- ? )
     drop "\r\n\u000085\u002029\u002028" member? ;
 
-M: ^ class-member? ( obj class -- ? )
-    2drop f ;
+M: f class-member? 2drop f ;
 
-M: $ class-member? ( obj class -- ? )
-    2drop f ;
+: same? ( obj1 obj2 quot1: ( obj1 -- val1 ) quot2: ( obj2 -- val2 ) -- ? )
+    bi* = ; inline
 
-M: f class-member? 2drop f ;
+M: script-class class-member?
+    [ script-of ] [ script>> ] same? ;
 
-TUPLE: primitive-class class ;
-C: <primitive-class> primitive-class
+M: category-class class-member?
+    [ category ] [ category>> ] same? ;
+
+M: category-range-class class-member?
+    [ category first ] [ category>> ] same? ;
 
 TUPLE: not-class class ;
 
 PREDICATE: not-integer < not-class class>> integer? ;
-PREDICATE: not-primitive < not-class class>> primitive-class? ;
+
+UNION: simple-class
+    primitive-class range-class dot ;
+PREDICATE: not-simple < not-class class>> simple-class? ;
 
 M: not-class class-member?
     class>> class-member? not ;
@@ -140,14 +153,14 @@ DEFER: substitute
         [ drop class new seq { } like >>seq ]
     } case ; inline
 
-TUPLE: class-partition integers not-integers primitives not-primitives and or other ;
+TUPLE: class-partition integers not-integers simples not-simples and or other ;
 
 : partition-classes ( seq -- class-partition )
     prune
     [ integer? ] partition
     [ not-integer? ] partition
-    [ primitive-class? ] partition ! extend primitive-class to epsilon tags
-    [ not-primitive? ] partition
+    [ simple-class? ] partition
+    [ not-simple? ] partition
     [ and-class? ] partition
     [ or-class? ] partition
     class-partition boa ;
@@ -161,17 +174,17 @@ TUPLE: class-partition integers not-integers primitives not-primitives and or ot
 
 : filter-not-integers ( partition -- partition' )
     dup
-    [ primitives>> ] [ not-primitives>> ] [ or>> ] tri
+    [ simples>> ] [ not-simples>> ] [ or>> ] tri
     3append and-class boa
     '[ [ class>> _ class-member? ] filter ] change-not-integers ;
 
 : answer-ors ( partition -- partition' )
-    dup [ not-integers>> ] [ not-primitives>> ] [ primitives>> ] tri 3append
+    dup [ not-integers>> ] [ not-simples>> ] [ simples>> ] tri 3append
     '[ [ _ [ t substitute ] each ] map ] change-or ;
 
 : contradiction? ( partition -- ? )
     {
-        [ [ primitives>> ] [ not-primitives>> ] bi intersects? ]
+        [ [ simples>> ] [ not-simples>> ] bi intersects? ]
         [ other>> f swap member? ]
     } 1|| ;
 
@@ -192,17 +205,17 @@ TUPLE: class-partition integers not-integers primitives not-primitives and or ot
 
 : filter-integers ( partition -- partition' )
     dup
-    [ primitives>> ] [ not-primitives>> ] [ and>> ] tri
+    [ simples>> ] [ not-simples>> ] [ and>> ] tri
     3append or-class boa
     '[ [ _ class-member? not ] filter ] change-integers ;
 
 : answer-ands ( partition -- partition' )
-    dup [ integers>> ] [ not-primitives>> ] [ primitives>> ] tri 3append
+    dup [ integers>> ] [ not-simples>> ] [ simples>> ] tri 3append
     '[ [ _ [ f substitute ] each ] map ] change-and ;
 
 : tautology? ( partition -- ? )
     {
-        [ [ primitives>> ] [ not-primitives>> ] bi intersects? ]
+        [ [ simples>> ] [ not-simples>> ] bi intersects? ]
         [ other>> t swap member? ]
     } 1|| ;
 
@@ -217,7 +230,10 @@ TUPLE: class-partition integers not-integers primitives not-primitives and or ot
     dup or-class flatten partition-classes
     dup not-integers>> length {
         { 0 [ nip make-or-class ] }
-        { 1 [ not-integers>> first [ class>> '[ _ swap class-member? ] any? ] keep or ] }
+        { 1 [
+            not-integers>> first
+            [ class>> '[ _ swap class-member? ] any? ] keep or
+        ] }
         [ 3drop t ]
     } case ;
 
@@ -238,11 +254,15 @@ M: or-class <not-class>
 M: t <not-class> drop f ;
 M: f <not-class> drop t ;
 
+: <minus-class> ( a b -- a-b )
+    <not-class> 2array <and-class> ;
+
+: <sym-diff-class> ( a b -- a~b )
+    2array [ <or-class> ] [ <and-class> ] bi <minus-class> ;
+
 M: primitive-class class-member?
     class>> class-member? ;
 
-UNION: class primitive-class not-class or-class and-class range ;
-
 TUPLE: condition question yes no ;
 C: <condition> condition
 
index 7cb214f42bb7079e4f5588abedca2bb7caf9f225..a49b16b585ce14d62b507de1842e63b02f86429e 100644 (file)
@@ -5,16 +5,32 @@ IN: regexp.combinators
 
 ABOUT: "regexp.combinators"
 
+ARTICLE: "regexp.combinators.intro" "Regular expression combinator rationale"
+"Regular expression combinators are useful when part of the regular expression contains user input. For example, given a sequence of strings on the stack, a regular expression which matches any one of them can be constructed:"
+{ $code
+  "[ <literal> ] map <or>"
+}
+"Without combinators, a naive approach would look as follows:"
+{ $code
+  "\"|\" join <regexp>"
+}
+"However, this code is incorrect, because one of the strings in the sequence might contain characters which have special meaning inside a regular expression. Combinators avoid this problem by building a regular expression syntax tree directly, without any parsing." ;
+
 ARTICLE: "regexp.combinators" "Regular expression combinators"
-"The " { $vocab-link "regexp.combinators" } " vocabulary defines combinators which can be used to build up regular expressions to match strings. This is in addition to the traditional syntax defined in the " { $vocab-link "regexp" } " vocabulary."
+"The " { $vocab-link "regexp.combinators" } " vocabulary defines combinators which can be used to build up regular expressions to match strings. This complements the traditional syntax defined in the " { $vocab-link "regexp" } " vocabulary."
+{ $subsection "regexp.combinators.intro" }
+"Basic combinators:"
 { $subsection <literal> }
 { $subsection <nothing> }
+"Higher-order combinators for building new regular expressions from existing ones:"
 { $subsection <or> }
 { $subsection <and> }
 { $subsection <not> }
 { $subsection <sequence> }
 { $subsection <zero-or-more> }
+"Derived combinators implemented in terms of the above:"
 { $subsection <one-or-more> }
+"Setting options:"
 { $subsection <option> } ;
 
 HELP: <literal>
index 2941afd99e59c9aa96f6bd423ef823c179fbd315..3bb5fcef6d96ca8f692b8b859f52ef8fdf9f61dc 100644 (file)
@@ -13,14 +13,14 @@ IN: regexp.combinators
 
 PRIVATE>
 
-CONSTANT: <nothing> R/ (?~.*)/
+CONSTANT: <nothing> R/ (?~.*)/s
 
 : <literal> ( string -- regexp )
     [ "\\Q" "\\E" surround ] [ <concatenation> ] bi make-regexp ; foldable
 
 : <char-range> ( char1 char2 -- regexp )
     [ [ "[" "-" surround ] [ "]" append ] bi* append ]
-    [ <range> ]
+    [ <range-class> ]
     2bi make-regexp ;
 
 : <or> ( regexps -- disjunction )
index 186d683f8219939ce5848741f04db479253d3e6e..548273486589cfbcbcc22a96a020be4c4542fd1b 100644 (file)
@@ -3,7 +3,7 @@
 USING: regexp.classes kernel sequences regexp.negation
 quotations assocs fry math locals combinators
 accessors words compiler.units kernel.private strings
-sequences.private arrays call namespaces unicode.breaks
+sequences.private arrays namespaces unicode.breaks
 regexp.transition-tables combinators.short-circuit ;
 IN: regexp.compiler
 
@@ -17,9 +17,6 @@ SYMBOL: backwards?
 M: t question>quot drop [ 2drop t ] ;
 M: f question>quot drop [ 2drop f ] ;
 
-M: not-class question>quot
-    class>> question>quot [ not ] compose ;
-
 M: beginning-of-input question>quot
     drop [ drop zero? ] ;
 
@@ -40,6 +37,12 @@ M: $ question>quot
 M: ^ question>quot
     drop [ { [ drop zero? ] [ [ 1- ] dip ?nth "\r\n" member? ] } 2|| ] ;
 
+M: $unix question>quot
+    drop [ { [ length = ] [ ?nth CHAR: \n = ] } 2|| ] ;
+
+M: ^unix question>quot
+    drop [ { [ drop zero? ] [ [ 1- ] dip ?nth CHAR: \n = ] } 2|| ] ;
+
 M: word-break question>quot
     drop [ word-break-at? ] ;
 
@@ -81,21 +84,24 @@ C: <box> box
     { } assoc-like [ first integer? ] partition
     [ [ literals>cases ] keep ] dip non-literals>dispatch ;
 
-:: step ( last-match index str quot final? direction -- last-index/f )
+: advance ( index backwards? -- index+/-1 )
+    -1 1 ? + >fixnum ; inline
+
+: check ( index string backwards? -- in-bounds? )
+    [ drop -1 eq? not ] [ length < ] if ; inline
+
+:: step ( last-match index str quot final? backwards? -- last-index/f )
     final? index last-match ?
-    index str bounds-check? [
-        index direction + str
+    index str backwards? check [
+        index backwards? advance str
         index str nth-unsafe
         quot call
     ] when ; inline
 
-: direction ( -- n )
-    backwards? get -1 1 ? ;
-
 : transitions>quot ( transitions final-state? -- quot )
     dup shortest? get and [ 2drop [ drop nip ] ] [
-        [ split-literals swap case>quot ] dip direction
-        '[ { array-capacity string } declare _ _ _ step ]
+        [ split-literals swap case>quot ] dip backwards? get
+        '[ { fixnum string } declare _ _ _ step ]
     ] if ;
 
 : word>quot ( word dfa -- quot )
@@ -104,15 +110,11 @@ C: <box> box
     transitions>quot ;
 
 : states>code ( words dfa -- )
-    [ ! with-compilation-unit doesn't compile, so we need call( -- )
-        [
-            '[
-                dup _ word>quot
-                (( last-match index string -- ? ))
-                define-declared
-            ] each
-        ] with-compilation-unit
-    ] call( words dfa -- ) ;
+    '[
+        dup _ word>quot
+        (( last-match index string -- ? ))
+        define-declared
+    ] each ;
 
 : states>words ( dfa -- words dfa )
     dup transitions>> keys [ gensym ] H{ } map>assoc
@@ -123,14 +125,14 @@ C: <box> box
 : dfa>main-word ( dfa -- word )
     states>words [ states>code ] keep start-state>> ;
 
-PRIVATE>
+: word-template ( quot -- quot' )
+    '[ drop [ f ] 2dip over array-capacity? _ [ 2drop ] if ] ;
 
-: simple-define-temp ( quot effect -- word )
-    [ [ define-temp ] with-compilation-unit ] call( quot effect -- word ) ;
+PRIVATE>
 
 : dfa>word ( dfa -- quot )
-    dfa>main-word execution-quot '[ drop [ f ] 2dip @ ]
-    (( start-index string regexp -- i/f )) simple-define-temp ;
+    dfa>main-word execution-quot word-template
+    (( start-index string regexp -- i/f )) define-temp ;
 
 : dfa>shortest-word ( dfa -- word )
     t shortest? [ dfa>word ] with-variable ;
index d137ee3e4f1c6087488be5fd67c19afc4912e91e..2de4e8b0e02322d7a3391c86f607944d18125ace 100644 (file)
@@ -51,10 +51,13 @@ IN: regexp.dfa
     [ condition-states ] 2dip
     '[ _ _ add-todo-state ] each ;
 
+: ensure-state ( key table -- )
+    2dup key? [ 2drop ] [ [ H{ } clone ] 2dip set-at ] if ; inline
+
 :: new-transitions ( nfa dfa new-states visited-states -- nfa dfa )
     new-states [ nfa dfa ] [
         pop :> state
-        state dfa transitions>> maybe-initialize-key
+        state dfa transitions>> ensure-state
         state nfa find-transitions
         [| trans |
             state trans nfa find-closure :> new-state
index 67b1503f9b7b9ca33851d11f6dffb4e51b1582af..876d898cb4e48ca36ad058bf5758b704bdbc7f4e 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2009 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors regexp.classes math.bits assocs sequences
-arrays sets regexp.dfa math fry regexp.minimize regexp.ast regexp.transition-tables ;
+arrays sets regexp.dfa math fry regexp.minimize regexp.ast
+locals regexp.transition-tables ;
 IN: regexp.disambiguate
 
 TUPLE: parts in out ;
@@ -9,7 +10,7 @@ TUPLE: parts in out ;
 : make-partition ( choices classes -- partition )
     zip [ first ] partition [ values ] bi@ parts boa ;
 
-: powerset-partition ( classes -- partitions )
+: powerset-partition ( sequence -- partitions )
     [ length [ 2^ ] keep ] keep '[
         _ <bits> _ make-partition
     ] map rest ;
@@ -19,19 +20,49 @@ TUPLE: parts in out ;
     [ in>> <and-class> ] bi
     prefix <and-class> ;
 
-: get-transitions ( partition state-transitions -- next-states )
-    [ in>> ] dip '[ _ at ] gather sift ;
+: singleton-partition ( integer non-integers -- {class,partition} )
+    dupd
+    '[ _ [ class-member? ] with filter ] keep
+    prefix f parts boa
+    2array ;
+
+: add-out ( seq partition -- partition' )
+    [ out>> append ] [ in>> ] bi swap parts boa ;
+
+: intersection ( seq -- elts )
+    [ f ] [ unclip [ intersect ] reduce ] if-empty ;
+
+: meaningful-integers ( partition table -- integers )
+    [ [ in>> ] [ out>> ] bi ] dip
+    '[ [ _ at ] map intersection ] bi@ diff ;
+
+: class-integers ( classes integers -- table )
+    '[ _ over '[ _ class-member? ] filter ] H{ } map>assoc ;
+
+: add-integers ( partitions classes integers -- partitions )
+    class-integers '[
+        [ _ meaningful-integers ] keep add-out
+    ] map ;
+
+: class-partitions ( classes -- assoc )
+    [ integer? ] partition [
+        dup powerset-partition spin add-integers
+        [ [ partition>class ] keep 2array ] map
+        [ first ] filter
+    ] [ '[ _ singleton-partition ] map ] 2bi append ;
 
 : new-transitions ( transitions -- assoc ) ! assoc is class, partition
     values [ keys ] gather
     [ tagged-epsilon? not ] filter
-    powerset-partition
-    [ [ partition>class ] keep ] { } map>assoc
-    [ drop ] assoc-filter ;
+    class-partitions ;
+
+: get-transitions ( partition state-transitions -- next-states )
+    [ in>> ] dip '[ _ at ] gather sift ;
 
 : preserving-epsilon ( state-transitions quot -- new-state-transitions )
     [ [ drop tagged-epsilon? ] assoc-filter ] bi
     assoc-union H{ } assoc-like ; inline
+
 : disambiguate ( nfa -- nfa )  
     expand-ors [
         dup new-transitions '[
index 2dc2c1798bef4bd8d5e2d0088a89d2bc3c59fb65..a692f707780f239754fe7570ce116f580f304542 100644 (file)
@@ -1,13 +1,13 @@
 ! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs grouping kernel
-locals math namespaces sequences fry quotations
-math.order math.ranges vectors unicode.categories
-regexp.transition-tables words sets hashtables combinators.short-circuit
-unicode.case.private regexp.ast regexp.classes ;
+USING: accessors arrays assocs grouping kernel locals math namespaces
+sequences fry quotations math.order math.ranges vectors
+unicode.categories regexp.transition-tables words sets hashtables
+combinators.short-circuit unicode.data regexp.ast
+regexp.classes memoize ;
 IN: regexp.nfa
 
-! This uses unicode.case.private for ch>upper and ch>lower
+! This uses unicode.data for ch>upper and ch>lower
 ! but case-insensitive matching should be done by case-folding everything
 ! before processing starts
 
@@ -60,11 +60,16 @@ GENERIC: modify-epsilon ( tag -- newtag )
 
 M: object modify-epsilon ;
 
+: line-option ( multiline unix-lines default -- option )
+    multiline option? [
+        drop [ unix-lines option? ] 2dip swap ?
+    ] [ 2nip ] if ;
+
 M: $ modify-epsilon
-    multiline option? [ drop end-of-input ] unless ;
+    $unix end-of-input line-option ;
 
 M: ^ modify-epsilon
-    multiline option? [ drop beginning-of-input ] unless ;
+    ^unix beginning-of-input line-option ;
 
 M: tagged-epsilon nfa-node
     clone [ modify-epsilon ] change-tag add-simple-entry ;
@@ -112,8 +117,17 @@ M: or-class modify-class
 M: not-class modify-class
     class>> modify-class <not-class> ;
 
-M: any-char modify-class
-    drop dotall option? t any-char-no-nl ? ;
+MEMO: unix-dot ( -- class )
+    CHAR: \n <not-class> ;
+
+MEMO: nonl-dot ( -- class )
+    { CHAR: \n CHAR: \r } <or-class> <not-class> ;
+
+M: dot modify-class
+    drop dotall option? [ t ] [
+        unix-lines option?
+        unix-dot nonl-dot ?
+    ] if ;
 
 : modify-letter-class ( class -- newclass )
     case-insensitive option? [ drop Letter-class ] when ;
@@ -126,17 +140,17 @@ M: LETTER-class modify-class modify-letter-class ;
         [ [ LETTER? ] bi@ and ]
     } 2|| ;
 
-M: range modify-class
+M: range-class modify-class
     case-insensitive option? [
         dup cased-range? [
             [ from>> ] [ to>> ] bi
-            [ [ ch>lower ] bi@ <range> ]
-            [ [ ch>upper ] bi@ <range> ] 2bi 
+            [ [ ch>lower ] bi@ <range-class> ]
+            [ [ ch>upper ] bi@ <range-class> ] 2bi 
             2array <or-class>
         ] when
     ] when ;
 
-M: class nfa-node
+M: object nfa-node
     modify-class add-simple-entry ;
 
 M: with-options nfa-node ( node -- start end )
index d606015f617e19e5e3a181174e0425df838593c1..5ea9753fbaf66b9ec2a964a7a8db951f30a0cb9d 100644 (file)
@@ -11,7 +11,7 @@ IN: regexp.parser.tests
     "a|b" "a.b" "a|b|c" "abc|b" "a|bcd" "a|(b)" "(?-i:a)" "||"
     "(a)|b" "(a|b)" "((a)|(b))" "(?:a)" "(?i:a)" "|b" "b|"
     "[abc]" "[a-c]" "[^a-c]" "[^]]" "[]a]" "[[]" "[]-a]" "[a-]" "[-]"
-    "[--a]" "foo*" "(foo)*" "(a|b)|c" "(foo){2,3}" "(foo){2,}"
+    "foo*" "(foo)*" "(a|b)|c" "(foo){2,3}" "(foo){2,}"
     "(foo){2}" "{2,3}" "{," "{,}" "}" "foo}" "[^]-a]" "[^-]a]"
     "[a-]" "[^a-]" "[^a-]" "a{,2}" "(?#foobar)"
     "\\p{Space}" "\\t" "\\[" "[\\]]" "\\P{Space}"
index c6a69f250875a2ddf999844f19c10a0f79dda013..70281aa798d38708f2d234265634cbe65d62c6fc 100644 (file)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: peg.ebnf kernel math.parser sequences assocs arrays fry math
 combinators regexp.classes strings splitting peg locals accessors
-regexp.ast ;
+regexp.ast unicode.case unicode.script.private unicode.categories
+memoize interval-maps sets unicode.data combinators.short-circuit ;
 IN: regexp.parser
 
 : allowed-char? ( ch -- ? )
@@ -18,23 +19,54 @@ ERROR: bad-number ;
 
 ERROR: bad-class name ;
 
-: name>class ( name -- class )
+: simple ( str -- simple )
+    ! Alternatively, first collation key level?
+    >case-fold [ " \t_" member? not ] filter ;
+
+: simple-table ( seq -- table )
+    [ [ simple ] keep ] H{ } map>assoc ;
+
+MEMO: simple-script-table ( -- table )
+    script-table interval-values prune simple-table ;
+
+MEMO: simple-category-table ( -- table )
+    categories simple-table ;
+
+: parse-unicode-class ( name -- class )
     {
-        { "Lower" letter-class }
-        { "Upper" LETTER-class }
-        { "Alpha" Letter-class }
-        { "ASCII" ascii-class }
-        { "Digit" digit-class }
-        { "Alnum" alpha-class }
-        { "Punct" punctuation-class }
-        { "Graph" java-printable-class }
-        { "Print" java-printable-class }
-        { "Blank" non-newline-blank-class }
-        { "Cntrl" control-character-class }
-        { "XDigit" hex-digit-class }
-        { "Space" java-blank-class }
-        ! TODO: unicode-character-class
-    } [ bad-class ] at-error ;
+        { [ dup { [ length 1 = ] [ first "clmnpsz" member? ] } 1&& ] [
+            >upper first
+            <category-range-class>
+        ] }
+        { [ dup >title categories member? ] [
+            simple-category-table at <category-class>
+        ] }
+        { [ "script=" ?head ] [
+            dup simple-script-table at
+            [ <script-class> ]
+            [ "script=" prepend bad-class ] ?if
+        ] }
+        [ bad-class ]
+    } cond ;
+
+: unicode-class ( name -- class )
+    dup parse-unicode-class [ ] [ bad-class ] ?if ;
+
+: name>class ( name -- class )
+    >string simple {
+        { "lower" letter-class }
+        { "upper" LETTER-class }
+        { "alpha" Letter-class }
+        { "ascii" ascii-class }
+        { "digit" digit-class }
+        { "alnum" alpha-class }
+        { "punct" punctuation-class }
+        { "graph" java-printable-class }
+        { "blank" non-newline-blank-class }
+        { "cntrl" control-character-class }
+        { "xdigit" hex-digit-class }
+        { "space" java-blank-class }
+    } [ unicode-class ] at-error ;
 
 : lookup-escape ( char -- ast )
     {
@@ -66,15 +98,14 @@ ERROR: bad-class name ;
         { CHAR: i case-insensitive }
         { CHAR: d unix-lines }
         { CHAR: m multiline }
-        { CHAR: n multiline }
         { CHAR: r reversed-regexp }
         { CHAR: s dotall }
-        { CHAR: u unicode-case }
-        { CHAR: x comments }
     } ;
 
+ERROR: nonexistent-option name ;
+
 : ch>option ( ch -- singleton )
-    options-assoc at ;
+    dup options-assoc at [ ] [ nonexistent-option ] ?if ;
 
 : option>ch ( option -- string )
     options-assoc value-at ;
@@ -101,8 +132,8 @@ CharacterInBracket = !("}") Character
 
 QuotedCharacter = !("\\E") .
 
-Escape = "p{" CharacterInBracket*:s "}" => [[ s >string name>class <primitive-class> ]]
-       | "P{" CharacterInBracket*:s "}" => [[ s >string name>class <primitive-class> <negation> ]]
+Escape = "p{" CharacterInBracket*:s "}" => [[ s name>class <primitive-class> ]]
+       | "P{" CharacterInBracket*:s "}" => [[ s name>class <primitive-class> <negation> ]]
        | "Q" QuotedCharacter*:s "\\E" => [[ s <concatenation> ]]
        | "u" Character:a Character:b Character:c Character:d
             => [[ { a b c d } hex> ensure-number ]]
@@ -119,19 +150,29 @@ Character = EscapeSequence
           | "^" => [[ ^ <tagged-epsilon> ]]
           | . ?[ allowed-char? ]?
 
-AnyRangeCharacter = EscapeSequence | .
+AnyRangeCharacter = !("&&"|"||"|"--"|"~~") (EscapeSequence | .)
 
 RangeCharacter = !("]") AnyRangeCharacter
 
-Range = RangeCharacter:a "-" RangeCharacter:b => [[ a b <range> ]]
+Range = RangeCharacter:a "-" !("-") RangeCharacter:b => [[ a b <range-class> ]]
       | RangeCharacter
 
-StartRange = AnyRangeCharacter:a "-" RangeCharacter:b => [[ a b <range> ]]
+StartRange = AnyRangeCharacter:a "-" !("-") RangeCharacter:b => [[ a b <range-class> ]]
            | AnyRangeCharacter
 
 Ranges = StartRange:s Range*:r => [[ r s prefix ]]
 
-CharClass = "^"?:n Ranges:e => [[ e n char-class ]]
+BasicCharClass =  "^"?:n Ranges:e => [[ e n char-class ]]
+
+CharClass = BasicCharClass:b "&&" CharClass:c
+                => [[ b c 2array <and-class> ]]
+          | BasicCharClass:b "||" CharClass:c
+                => [[ b c 2array <or-class> ]]
+          | BasicCharClass:b "~~" CharClass:c
+                => [[ b c <sym-diff-class> ]]
+          | BasicCharClass:b "--" CharClass:c
+                => [[ b c <minus-class> ]]
+          | BasicCharClass
 
 Options = [idmsux]*
 
@@ -148,7 +189,7 @@ Parenthized = "?:" Alternation:a => [[ a ]]
 
 Element = "(" Parenthized:p ")" => [[ p ]]
         | "[" CharClass:r "]" => [[ r ]]
-        | ".":d => [[ any-char <primitive-class> ]]
+        | ".":d => [[ dot ]]
         | Character
 
 Number = (!(","|"}").)* => [[ string>number ensure-number ]]
diff --git a/basis/regexp/prettyprint/authors.txt b/basis/regexp/prettyprint/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/regexp/prettyprint/prettyprint.factor b/basis/regexp/prettyprint/prettyprint.factor
new file mode 100644 (file)
index 0000000..7af762a
--- /dev/null
@@ -0,0 +1,13 @@
+! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel make prettyprint.backend
+prettyprint.custom regexp regexp.parser regexp.private ;
+IN: regexp.prettyprint
+
+M: regexp pprint*
+    [
+        [
+            [ raw>> dup find-regexp-syntax swap % swap % % ]
+            [ options>> options>string % ] bi
+        ] "" make
+    ] keep present-text ;
\ No newline at end of file
index adbeb341bb37272de2245f13d57e7247adb89d2f..2ff31f0cecdba204c80f231728bc5b89b50b33e1 100644 (file)
 ! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel strings help.markup help.syntax math ;
+USING: kernel strings help.markup help.syntax math regexp.parser
+regexp.ast multiline ;
 IN: regexp
 
 ABOUT: "regexp"
 
 ARTICLE: "regexp" "Regular expressions"
 "The " { $vocab-link "regexp" } " vocabulary provides word for creating and using regular expressions."
+{ $subsection { "regexp" "intro" } }
+"The class of regular expressions:"
+{ $subsection regexp }
+"Basic usage:"
 { $subsection { "regexp" "syntax" } }
+{ $subsection { "regexp" "options" } }
 { $subsection { "regexp" "construction" } }
-{ $vocab-subsection "regexp.combinators" "Regular expression combinators" }
 { $subsection { "regexp" "operations" } }
-{ $subsection regexp }
-{ $subsection { "regexp" "theory" } } ;
+"Advanced topics:"
+{ $vocab-subsection "Regular expression combinators" "regexp.combinators" }
+{ $subsection { "regexp" "theory" } }
+{ $subsection { "regexp" "deploy" } } ;
+
+ARTICLE: { "regexp" "intro" } "A quick introduction to regular expressions"
+"Regular expressions are a terse way to do certain simple string processing tasks. For example, to replace all instances of " { $snippet "foo" } " in one string with " { $snippet "bar" } ", the following can be used:"
+{ $code "R/ foo/ \"bar\" re-replace" }
+"That could be done with sequence operations, but consider doing this replacement for an arbitrary number of o's, at least two:"
+{ $code "R/ foo+/ \"bar\" re-replace" }
+"The " { $snippet "+" } " operator matches one or more occurrences of the previous expression; in this case " { $snippet "o" } ". Another useful feature is alternation. Say we want to do this replacement with fooooo or boooo. Then we could use the code"
+{ $code "R/ (f|b)oo+/ \"bar\" re-replace" }
+"To search a file for all lines that match a given regular expression, you could use code like this:"
+{ $code <" "file.txt" ascii file-lines [ R/ (f|b)oo+/ re-contains? ] filter "> }
+"To test if a string in its entirety matches a regular expression, the following can be used:"
+{ $example <" USING: regexp prettyprint ; "fooo" R/ (b|f)oo+/ matches? . "> "t" }
+"Regular expressions can't be used for all parsing tasks. For example, they are not powerful enough to match balancing parentheses." ;
 
 ARTICLE: { "regexp" "construction" } "Constructing regular expressions"
-"Words which are useful for creating regular expressions:"
+"Most of the time, regular expressions are literals and the parsing word should be used, to construct them at parse time. This ensures that they are only compiled once, and gives parse time syntax checking."
 { $subsection POSTPONE: R/ }
+"Sometimes, regular expressions need to be constructed at run time instead; for example, in a text editor, the user might input a regular expression to search for in a document."
 { $subsection <regexp> } 
 { $subsection <optioned-regexp> }
-{ $heading "See also" }
-{ $vocab-link "regexp.combinators" } ;
+"Another approach is to use " { $vocab-link "regexp.combinators" } "." ;
 
 ARTICLE: { "regexp" "syntax" } "Regular expression syntax"
-"Regexp syntax is largely compatible with Perl, Java and extended POSIX regexps, but not completely." $nl
-"A new addition is the inclusion of a negation operator, with the syntax " { $snippet "(?~foo)" } " to match everything that does not match " { $snippet "foo" } "." $nl
-"One missing feature is backreferences. This is because of a design decision to allow only regular expressions following the formal theory of regular languages. For more information, see " { $link { "regexp" "theory" } } ". You can create a new regular expression to match a particular string using " { $vocab-link "regexp.combinators" } " and group capture is available to extract parts of a regular expression match." $nl
-"A distinction from Perl is that " { $snippet "\\G" } ", which references the previous match, is not included. This is because that sequence is inherently stateful, and Factor regexps don't hold state." $nl
-"Additionally, none of the operations which embed code into a regexp are supported, as this would require the inclusion of the Factor parser and compiler in any application which wants to expose regexps to the user. None of the casing operations are included, for simplicity." ; ! Also describe syntax, from the beginning
+"Regexp syntax is largely compatible with Perl, Java and extended POSIX regexps, but not completely. Below, the syntax is documented."
+{ $heading "Characters" }
+"At its core, regular expressions consist of character literals. For example, " { $snippet "R/ f/" } " is a regular expression matching just the string 'f'. In addition, the normal escape codes are provided, like " { $snippet "\\t" } " for the tab character and " { $snippet "\\uxxxxxx" } " for an arbitrary Unicode code point, by its hex value. In addition, any character can be preceded by a backslash to escape it, unless this has special meaning. For example, to match a literal opening parenthesis, use " { $snippet "\\(" } "."
+{ $heading "Concatenation, alternation and grouping" }
+"Regular expressions can be built out of multiple characters by concatenation. For example, " { $snippet "R/ ab/" } " matches a followed by b. The " { $snippet "|" } " (alternation) operator can construct a regexp which matches one of two alternatives. Parentheses can be used for grouping. So " { $snippet "R/ f(oo|ar)/" } " would match either 'foo' or 'far'."
+{ $heading "Character classes" }
+"Square brackets define a convenient way to refer to a set of characters. For example, " { $snippet "[ab]" } " refers to either a or b. And " { $snippet "[a-z]" } " refers to all of the characters between a and z, in code point order. You can use these together, as in " { $snippet "[ac-fz]" } " which matches all of the characters between c and f, in addition to a and z. Character classes can be negated using a caret, as in " { $snippet "[^a]" } " which matches all characters which are not a."
+{ $heading "Predefined character classes" }
+"Several character classes are predefined, both for convenience and because they are too large to represent directly. In Factor regular expressions, all character classes are Unicode-aware."
+{ $table
+    { { $snippet "\\d" } "Digits" }
+    { { $snippet "\\D" } "Not digits" }
+    { { $snippet "\\s" } "Whitespace" }
+    { { $snippet "\\S" } "Not whitespace" }
+    { { $snippet "\\w" } "Word character (alphanumeric or underscore)" }
+    { { $snippet "\\W" } "Not word character" }
+    { { $snippet "\\p{property}" } "Character which fulfils the property" }
+    { { $snippet "\\P{property}" } "Character which does not fulfil the property" } }
+"Properties for " { $snippet "\\p" } " and " { $snippet "\\P" } " (case-insensitive):"
+{ $table
+    { { $snippet "\\p{lower}" } "Lower case letters" }
+    { { $snippet "\\p{upper}" } "Upper case letters" }
+    { { $snippet "\\p{alpha}" } "Letters" }
+    { { $snippet "\\p{ascii}" } "Characters in the ASCII range" }
+    { { $snippet "\\p{alnum}" } "Letters or numbers" }
+    { { $snippet "\\p{punct}" } "Punctuation" }
+    { { $snippet "\\p{blank}" } "Non-newline whitespace" }
+    { { $snippet "\\p{cntrl}" } "Control character" }
+    { { $snippet "\\p{space}" } "Whitespace" }
+    { { $snippet "\\p{xdigit}" } "Hexadecimal digit" }
+    { { $snippet "\\p{Nd}" } "Character in Unicode category Nd" } 
+    { { $snippet "\\p{Z}" } "Character in Unicode category beginning with Z" } 
+    { { $snippet "\\p{script=Cham}" } "Character in the Cham writing system" } }
+{ $heading "Character class operations" }
+"Character classes can be composed using four binary operations: " { $snippet "|| && ~~ --" } ". These do the operations union, intersection, symmetric difference and difference, respectively. For example, characters which are lower-case but not Latin script could be matched as " { $snippet "[\\p{lower}--\\p{script=latin}]" } ". These operations are right-associative, and " { $snippet "^" } " binds tighter than them. There is no syntax for grouping."
+{ $heading "Boundaries" }
+"Special operators exist to match certain points in the string. These are called 'zero-width' because they do not consume any characters."
+{ $table
+    { { $snippet "^" } "Beginning of a line" }
+    { { $snippet "$" } "End of a line" }
+    { { $snippet "\\A" } "Beginning of text" }
+    { { $snippet "\\z" } "End of text" }
+    { { $snippet "\\Z" } "Almost end of text: only thing after is newline" }
+    { { $snippet "\\b" } "Word boundary (by Unicode word boundaries)" }
+    { { $snippet "\\b" } "Not word boundary (by Unicode word boundaries)" } }
+{ $heading "Greedy quantifiers" }
+"It is possible to have a regular expression which matches a variable number of occurrences of another regular expression."
+{ $table
+    { { $snippet "a*" } "Zero or more occurrences of a" }
+    { { $snippet "a+" } "One or more occurrences of a" }
+    { { $snippet "a?" } "Zero or one occurrences of a" }
+    { { $snippet "a{n}" } "n occurrences of a" }
+    { { $snippet "a{n,}" } "At least n occurrences of a" }
+    { { $snippet "a{,m}" } "At most m occurrences of a" }
+    { { $snippet "a{n,m}" } "Between n and m occurrences of a" } }
+"All of these quantifiers are " { $emphasis "greedy" } ", meaning that they take as many repetitions as possible within the larger regular expression. Reluctant and posessive quantifiers are not yet supported."
+{ $heading "Lookaround" }
+"Operators are provided to look ahead and behind the current point in the regular expression. These can be used in any context, but they're the most useful at the beginning or end of a regular expression."
+{ $table
+    { { $snippet "(?=a)" } "Asserts that the current position is immediately followed by a" }
+    { { $snippet "(?!a)" } "Asserts that the current position is not immediately followed by a" }
+    { { $snippet "(?<=a)" } "Asserts that the current position is immediately preceded by a" }
+    { { $snippet "(?<!a)" } "Asserts that the current position is not immediately preceded by a" } }
+{ $heading "Quotation" }
+"To make it convenient to have a long string which uses regexp operators, a special syntax is provided. If a substring begins with " { $snippet "\\Q" } " then everything until " { $snippet "\\E" } " is quoted (escaped). For example, " { $snippet "R/ \\Qfoo\\bar|baz()\\E/" } " matches exactly the string " { $snippet "\"foo\\bar|baz()\"" } "."
+{ $heading "Unsupported features" }
+{ $subheading "Group capture" }
+{ $subheading "Reluctant and posessive quantifiers" }
+{ $subheading "Backreferences" }
+"Backreferences were omitted because of a design decision to allow only regular expressions following the formal theory of regular languages. For more information, see " { $link { "regexp" "theory" } } "."
+$nl
+"To work around the lack of backreferences, consider using group capture and then creating a new regular expression to match the captured string using " { $vocab-link "regexp.combinators" } "."
+{ $subheading "Previous match" }
+"Another feature that is not included is Perl's " { $snippet "\\G" } " syntax, which references the previous match. This is because that sequence is inherently stateful, and Factor regexps don't hold state."
+{ $subheading "Embedding code" }
+"Operations which embed code into a regexp are not supported. This would require the inclusion of the Factor parser and compiler in any deployed application which wants to expose regexps to the user, leading to an undesirable increase in the code size."
+{ $heading "Casing operations" }
+"No special casing operations are included, for example Perl's " { $snippet "\\L" } "." ;
+
+ARTICLE: { "regexp" "options" } "Regular expression options"
+"When " { $link { "regexp" "construction" } } ", various options can be provided. Options have single-character names. A string of options has one of the following two forms:"
+{ $code "on" "on-off" }
+"The latter syntax allows some options to be disabled. The " { $snippet "on" } " and " { $snippet "off" } " strings name options to be enabled and disabled, respectively."
+$nl
+"The following options are supported:"
+{ $table
+  { "i" { $link case-insensitive } }
+  { "d" { $link unix-lines } }
+  { "m" { $link multiline } }
+  { "s" { $link dotall } }
+  { "r" { $link reversed-regexp } }
+} ;
+
+HELP: case-insensitive
+{ $syntax "R/ .../i" }
+{ $description "On regexps, the " { $snippet "i" } " option makes the match case-insenstive. Currently, this is handled incorrectly with respect to Unicode, as characters like ß do not expand into SS in upper case. This should be fixed in a future version." } ;
+
+HELP: unix-lines
+{ $syntax "R/ .../d" }
+{ $description "With this mode, only newlines (" { $snippet "\\n" } ") are recognized for line breaking. This affects " { $snippet "$" } " and " { $snippet "^" } " when in multiline mode." } ;
+
+HELP: multiline
+{ $syntax "R/ .../m" }
+{ $description "This mode makes the zero-width constraints " { $snippet "$" } " and " { $snippet "^" } " match the beginning or end of a line. Otherwise, they only match the beginning or end of the input text. This can be used together with " { $link dotall } "." } ;
+
+HELP: dotall
+{ $syntax "R/ .../s" }
+{ $description "This mode, traditionally called single line mode, makes " { $snippet "." } " match everything, including line breaks. By default, it does not match line breaking characters. This can be used together with " { $link multiline } "." } ;
+
+HELP: reversed-regexp
+{ $syntax "R/ .../r" }
+{ $description "When running a regexp compiled with this mode, matches will start from the end of the input string, going towards the beginning." } ;
 
 ARTICLE: { "regexp" "theory" } "The theory of regular expressions"
 "Far from being just a practical tool invented by Unix hackers, regular expressions were studied formally before computer programs were written to process them." $nl
@@ -36,29 +163,44 @@ ARTICLE: { "regexp" "theory" } "The theory of regular expressions"
 "This implies, by DeMorgan's law, that, if you have two regular languages, their intersection is also regular. That is, for any two regular expressions, there exists a regular expression which matches strings that match both inputs." $nl
 "Traditionally, regular expressions on computer support an additional operation: backreferences. For example, the Perl regexp " { $snippet "/(.*)$1/" } " matches a string repated twice. If a backreference refers to a string with a predetermined maximum length, then the resulting language is still regular." $nl
 "But, if not, the language is not regular. There is strong evidence that there is no efficient way to parse with backreferences in the general case. Perl uses a naive backtracking algorithm which has pathological behavior in some cases, taking exponential time to match even if backreferences aren't used. Additionally, expressions with backreferences don't have the properties with negation and intersection described above." $nl
-"The Factor regular expression engine was built with the design decision to support negation and intersection at the expense of backreferences. This lets us have a guaranteed linear-time matching algorithm. Systems like Ragel and Lex also use this algorithm, but in the Factor regular expression engine, all other features of regexps are still present." ;
+"The Factor regular expression engine was built with the design decision to support negation and intersection at the expense of backreferences. This lets us have a guaranteed linear-time matching algorithm. Systems like Ragel and Lex use the same algorithm." ;
 
 ARTICLE: { "regexp" "operations" } "Matching operations with regular expressions"
+"Testing if a string matches a regular expression:"
 { $subsection matches? }
+"Finding a match inside a string:"
 { $subsection re-contains? }
 { $subsection first-match }
+"Finding all matches inside a string:"
+{ $subsection count-matches }
 { $subsection all-matching-slices }
 { $subsection all-matching-subseqs }
+"Splitting a string into tokens delimited by a regular expression:"
 { $subsection re-split }
-{ $subsection re-replace }
-{ $subsection count-matches } ;
+"Replacing occurrences of a regular expression with a string:"
+{ $subsection re-replace } ;
+
+ARTICLE: { "regexp" "deploy" } "Regular expressions and the deploy tool"
+"The " { $link "tools.deploy" } " tool has the option to strip out the optimizing compiler from the resulting image. Since regular expressions compile to Factor code, this creates a minor performance-related caveat."
+$nl
+"Regular expressions constructed at runtime from a deployed application will be compiled with the non-optimizing compiler, which is always available because it is built into the Factor VM. This will result in lower performance than when using the optimizing compiler."
+$nl
+"Literal regular expressions constructed at parse time do not suffer from this restriction, since the deployed application is loaded and compiled before anything is stripped out."
+$nl
+"None of this applies to deployed applications which include the optimizing compiler, or code running inside a development image."
+{ $see-also "compiler" { "regexp" "construction" } "deploy-flags" } ;
 
 HELP: <regexp>
 { $values { "string" string } { "regexp" regexp } }
 { $description "Creates a regular expression object, given a string in regular expression syntax. When it is first used for matching, a DFA is compiled, and this DFA is stored for reuse so it is only compiled once." } ;
 
 HELP: <optioned-regexp>
-{ $values { "string" string } { "options" string } { "regexp" regexp } }
+{ $values { "string" string } { "options" "a string of " { $link { "regexp" "options" } } } { "regexp" regexp } }
 { $description "Given a string in regular expression syntax, and a string of options, creates a regular expression object. When it is first used for matching, a DFA is compiled, and this DFA is stored for reuse so it is only compiled once." } ;
 
 HELP: R/
-{ $syntax "R/ foo.*|[a-zA-Z]bar/i" }
-{ $description "Literal syntax for a regular expression. When this syntax is used, the DFA is compiled at compile-time, rather than on first use." } ;
+{ $syntax "R/ foo.*|[a-zA-Z]bar/options" }
+{ $description "Literal syntax for a regular expression. When this syntax is used, the DFA is compiled at compile-time, rather than on first use. The syntax for the " { $snippet "options" } " string is documented in " { $link { "regexp" "options" } } "." } ;
 
 HELP: regexp
 { $class-description "The class of regular expressions. To construct these, see " { $link { "regexp" "construction" } } "." } ;
index a449b3e2f0b0891bbaa01aecdf68cc1642d90784..22343868032108956f864c87579bf6f61736c5be 100644 (file)
@@ -470,3 +470,67 @@ IN: regexp-tests
 [ t ] [ "abcdefg" "a(?:bcdefg)" <regexp> matches? ] unit-test
 
 [ 3 ] [ "caba" "(?<=b)a" <regexp> first-match from>> ] unit-test
+
+[ t ] [ "\ra" R/ .^a/ms matches? ] unit-test
+[ f ] [ "\ra" R/ .^a/mds matches? ] unit-test
+[ t ] [ "\na" R/ .^a/ms matches? ] unit-test
+[ t ] [ "\na" R/ .^a/mds matches? ] unit-test
+
+[ t ] [ "a\r" R/ a$./ms matches? ] unit-test
+[ f ] [ "a\r" R/ a$./mds matches? ] unit-test
+[ t ] [ "a\n" R/ a$./ms matches? ] unit-test
+[ t ] [ "a\n" R/ a$./mds matches? ] unit-test
+
+! Unicode categories
+[ t ] [ "a" R/ \p{L}/ matches? ] unit-test
+[ t ] [ "A" R/ \p{L}/ matches? ] unit-test
+[ f ] [ " " R/ \p{L}/ matches? ] unit-test
+[ f ] [ "a" R/ \P{L}/ matches? ] unit-test
+[ f ] [ "A" R/ \P{L}/ matches? ] unit-test
+[ t ] [ " " R/ \P{L}/ matches? ] unit-test
+
+[ t ] [ "a" R/ \p{Ll}/ matches? ] unit-test
+[ f ] [ "A" R/ \p{Ll}/ matches? ] unit-test
+[ f ] [ " " R/ \p{Ll}/ matches? ] unit-test
+[ f ] [ "a" R/ \P{Ll}/ matches? ] unit-test
+[ t ] [ "A" R/ \P{Ll}/ matches? ] unit-test
+[ t ] [ " " R/ \P{Ll}/ matches? ] unit-test
+
+[ t ] [ "a" R/ \p{script=Latin}/ matches? ] unit-test
+[ f ] [ " " R/ \p{script=Latin}/ matches? ] unit-test
+[ f ] [ "a" R/ \P{script=Latin}/ matches? ] unit-test
+[ t ] [ " " R/ \P{script=Latin}/ matches? ] unit-test
+
+! These should be case-insensitive
+[ f ] [ " " R/ \p{l}/ matches? ] unit-test
+[ f ] [ "a" R/ \P{l}/ matches? ] unit-test
+[ f ] [ "a" R/ \P{ll}/ matches? ] unit-test
+[ t ] [ " " R/ \P{LL}/ matches? ] unit-test
+[ f ] [ "a" R/ \P{sCriPt = latin}/ matches? ] unit-test
+[ t ] [ " " R/ \P{SCRIPT = laTIn}/ matches? ] unit-test
+
+! Logical operators
+[ t ] [ "a" R/ [\p{script=latin}\p{lower}]/ matches? ] unit-test
+[ t ] [ "π" R/ [\p{script=latin}\p{lower}]/ matches? ] unit-test
+[ t ] [ "A" R/ [\p{script=latin}\p{lower}]/ matches? ] unit-test
+[ f ] [ "3" R/ [\p{script=latin}\p{lower}]/ matches? ] unit-test
+
+[ t ] [ "a" R/ [\p{script=latin}||\p{lower}]/ matches? ] unit-test
+[ t ] [ "π" R/ [\p{script=latin}||\p{lower}]/ matches? ] unit-test
+[ t ] [ "A" R/ [\p{script=latin}||\p{lower}]/ matches? ] unit-test
+[ f ] [ "3" R/ [\p{script=latin}||\p{lower}]/ matches? ] unit-test
+
+[ t ] [ "a" R/ [\p{script=latin}&&\p{lower}]/ matches? ] unit-test
+[ f ] [ "π" R/ [\p{script=latin}&&\p{lower}]/ matches? ] unit-test
+[ f ] [ "A" R/ [\p{script=latin}&&\p{lower}]/ matches? ] unit-test
+[ f ] [ "3" R/ [\p{script=latin}&&\p{lower}]/ matches? ] unit-test
+
+[ f ] [ "a" R/ [\p{script=latin}~~\p{lower}]/ matches? ] unit-test
+[ t ] [ "π" R/ [\p{script=latin}~~\p{lower}]/ matches? ] unit-test
+[ t ] [ "A" R/ [\p{script=latin}~~\p{lower}]/ matches? ] unit-test
+[ f ] [ "3" R/ [\p{script=latin}~~\p{lower}]/ matches? ] unit-test
+
+[ f ] [ "a" R/ [\p{script=latin}--\p{lower}]/ matches? ] unit-test
+[ f ] [ "π" R/ [\p{script=latin}--\p{lower}]/ matches? ] unit-test
+[ t ] [ "A" R/ [\p{script=latin}--\p{lower}]/ matches? ] unit-test
+[ f ] [ "3" R/ [\p{script=latin}--\p{lower}]/ matches? ] unit-test
index 29f7e3e84e079bfe2e62d5430b3e7a498c75355f..21439640fe18f6934606946006062c301265ab14 100644 (file)
@@ -1,10 +1,9 @@
 ! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors combinators kernel kernel.private math sequences
-sequences.private strings sets assocs prettyprint.backend
-prettyprint.custom make lexer namespaces parser arrays fry locals
-regexp.parser splitting sorting regexp.ast regexp.negation
-regexp.compiler words call call.private math.ranges ;
+sequences.private strings sets assocs make lexer namespaces parser
+arrays fry locals regexp.parser splitting sorting regexp.ast
+regexp.negation regexp.compiler compiler.units words math.ranges ;
 IN: regexp
 
 TUPLE: regexp
@@ -35,7 +34,7 @@ M: lookbehind question>quot ! Returns ( index string -- ? )
 : match-index-from ( i string regexp -- index/f )
     ! This word is unsafe. It assumes that i is a fixnum
     ! and that string is a string.
-    dup dfa>> execute-unsafe( index string regexp -- i/f ) ;
+    dup dfa>> execute( index string regexp -- i/f ) ; inline
 
 GENERIC: end/start ( string regexp -- end start )
 M: regexp end/start drop length 0 ;
@@ -68,7 +67,7 @@ PRIVATE>
 
 : do-next-match ( i string regexp -- i start end ? )
     dup next-match>>
-    execute-unsafe( i string regexp -- i start end ? ) ; inline
+    execute( i string regexp -- i start end ? ) ; inline
 
 :: (each-match) ( i string regexp quot: ( start end string -- ) -- )
     i string regexp do-next-match [| i' start end |
@@ -129,31 +128,28 @@ PRIVATE>
 GENERIC: compile-regexp ( regex -- regexp )
 
 : regexp-initial-word ( i string regexp -- i/f )
-    compile-regexp match-index-from ;
+    [ compile-regexp ] with-compilation-unit match-index-from ;
 
-: do-compile-regexp ( regexp -- regexp )
+M: regexp compile-regexp ( regexp -- regexp )
     dup '[
         dup \ regexp-initial-word =
         [ drop _ get-ast ast>dfa dfa>word ] when
     ] change-dfa ;
 
-M: regexp compile-regexp ( regexp -- regexp )
-    do-compile-regexp ;
-
 M: reverse-regexp compile-regexp ( regexp -- regexp )
-    t backwards? [ do-compile-regexp ] with-variable ;
+    t backwards? [ call-next-method ] with-variable ;
 
 DEFER: compile-next-match
 
 : next-initial-word ( i string regexp -- i start end string )
-    compile-next-match do-next-match ;
+    [ compile-next-match ] with-compilation-unit do-next-match ;
 
 : compile-next-match ( regexp -- regexp )
     dup '[
         dup \ next-initial-word = [
             drop _ [ compile-regexp dfa>> def>> ] [ reverse-regexp? ] bi
             '[ { array-capacity string regexp } declare _ _ next-match ]
-            (( i string regexp -- i start end string )) simple-define-temp
+            (( i string regexp -- i start end string )) define-temp
         ] when
     ] change-next-match ;
 
@@ -208,23 +204,20 @@ PRIVATE>
 
 PRIVATE>
 
-: R! CHAR: ! parsing-regexp ; parsing
-: R" CHAR: " parsing-regexp ; parsing
-: R# CHAR: # parsing-regexp ; parsing
-: R' CHAR: ' parsing-regexp ; parsing
-: R( CHAR: ) parsing-regexp ; parsing
-: R/ CHAR: / parsing-regexp ; parsing
-: R@ CHAR: @ parsing-regexp ; parsing
-: R[ CHAR: ] parsing-regexp ; parsing
-: R` CHAR: ` parsing-regexp ; parsing
-: R{ CHAR: } parsing-regexp ; parsing
-: R| CHAR: | parsing-regexp ; parsing
-
-M: regexp pprint*
-    [
-        [
-            [ raw>> dup find-regexp-syntax swap % swap % % ]
-            [ options>> options>string % ] bi
-        ] "" make
-    ] keep present-text ;
-
+SYNTAX: R! CHAR: ! parsing-regexp ;
+SYNTAX: R" CHAR: " parsing-regexp ;
+SYNTAX: R# CHAR: # parsing-regexp ;
+SYNTAX: R' CHAR: ' parsing-regexp ;
+SYNTAX: R( CHAR: ) parsing-regexp ;
+SYNTAX: R/ CHAR: / parsing-regexp ;
+SYNTAX: R@ CHAR: @ parsing-regexp ;
+SYNTAX: R[ CHAR: ] parsing-regexp ;
+SYNTAX: R` CHAR: ` parsing-regexp ;
+SYNTAX: R{ CHAR: } parsing-regexp ;
+SYNTAX: R| CHAR: | parsing-regexp ;
+
+USING: vocabs vocabs.loader ;
+
+"prettyprint" vocab [
+    "regexp.prettyprint" require
+] when
\ No newline at end of file
index 3c33ae88466da489ce2a91df898d6e33c87a0a15..f452e3d24a4e46c25523a904332647d725c9ea74 100644 (file)
@@ -11,12 +11,7 @@ TUPLE: transition-table transitions start-state final-states ;
         H{ } clone >>transitions
         H{ } clone >>final-states ;
 
-: maybe-initialize-key ( key hashtable -- )
-    ! Why do we have to do this?
-    2dup key? [ 2drop ] [ [ H{ } clone ] 2dip set-at ] if ;
-
 :: (set-transition) ( from to obj hash -- )
-    to condition? [ to hash maybe-initialize-key ] unless
     from hash at
     [ [ to obj ] dip set-at ]
     [ to obj associate from hash set-at ] if* ;
@@ -25,7 +20,6 @@ TUPLE: transition-table transitions start-state final-states ;
     transitions>> (set-transition) ;
 
 :: (add-transition) ( from to obj hash -- )
-    to hash maybe-initialize-key
     from hash at
     [ [ to obj ] dip push-at ]
     [ to 1vector obj associate from hash set-at ] if* ;
index 4a8197f0647df2a1bcaeb26a68c79c5c198e3f5b..bef0ab90fceb2e072a1614d713bf08e9e0014280 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax kernel math ;
+USING: help.markup help.syntax kernel math strings ;
 IN: roman
 
 HELP: >roman
@@ -39,7 +39,7 @@ HELP: roman>
 { >roman >ROMAN roman> } related-words
 
 HELP: roman+
-{ $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
+{ $values { "string" string } { "string" string } { "string" string } }
 { $description "Adds two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -49,7 +49,7 @@ HELP: roman+
 } ;
 
 HELP: roman-
-{ $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
+{ $values { "string" string } { "string" string } { "string" string } }
 { $description "Subtracts two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -61,7 +61,7 @@ HELP: roman-
 { roman+ roman- } related-words
 
 HELP: roman*
-{ $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
+{ $values { "string" string } { "string" string } { "string" string } }
 { $description "Multiplies two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -71,7 +71,7 @@ HELP: roman*
 } ;
 
 HELP: roman/i
-{ $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } }
+{ $values { "string" string } { "string" string } { "string" string } }
 { $description "Computes the integer division of two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -81,7 +81,7 @@ HELP: roman/i
 } ;
 
 HELP: roman/mod
-{ $values { "str1" "a string" } { "str2" "a string" } { "str3" "a string" } { "str4" "a string" } }
+{ $values { "string" string } { "string" string } { "string" string } { "string" string } }
 { $description "Computes the quotient and remainder of two Roman numerals." }
 { $examples 
     { $example "USING: kernel io roman ;"
index 82084e0b1fa64833f60a793806a4253321824f94..a510514e2344cbcd5e6c6f37eb8eb7c204301c7a 100644 (file)
@@ -38,3 +38,9 @@ USING: arrays kernel math roman roman.private sequences tools.test ;
 [ "iii" "iii"  roman- ] must-fail
 
 [ 30 ] [ ROMAN: xxx ] unit-test
+
+[ roman+ ] must-infer
+[ roman- ] must-infer
+[ roman* ] must-infer
+[ roman/i ] must-infer
+[ roman/mod ] must-infer
index 24713545b136a92064b058569f5719cae4c05716..92202da8caab2535e55062d13aabe0140cfe31aa 100644 (file)
@@ -1,29 +1,33 @@
 ! Copyright (C) 2007 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays assocs kernel math math.order math.vectors
-namespaces make quotations sequences splitting.monotonic
-sequences.private strings unicode.case lexer parser
-grouping ;
+USING: accessors arrays assocs fry generalizations grouping
+kernel lexer macros make math math.order math.vectors
+namespaces parser quotations sequences sequences.private
+splitting.monotonic stack-checker strings unicode.case
+words effects ;
 IN: roman
 
 <PRIVATE
 
-: roman-digits ( -- seq )
-    { "m" "cm" "d" "cd" "c" "xc" "l" "xl" "x" "ix" "v" "iv" "i" } ;
+CONSTANT: roman-digits
+    { "m" "cm" "d" "cd" "c" "xc" "l" "xl" "x" "ix" "v" "iv" "i" }
 
-: roman-values ( -- seq )
-    { 1000 900 500 400 100 90 50 40 10 9 5 4 1 } ;
+CONSTANT: roman-values
+    { 1000 900 500 400 100 90 50 40 10 9 5 4 1 }
 
 ERROR: roman-range-error n ;
 
 : roman-range-check ( n -- )
     dup 1 3999 between? [ drop ] [ roman-range-error ] if ;
 
+: roman-digit-index ( ch -- n )
+    1string roman-digits index ; inline
+
 : roman<= ( ch1 ch2 -- ? )
-    [ 1string roman-digits index ] bi@ >= ;
+    [ roman-digit-index ] bi@ >= ;
 
 : roman>n ( ch -- n )
-    1string roman-digits index roman-values nth ;
+    roman-digit-index roman-values nth ;
 
 : (>roman) ( n -- )
     roman-values roman-digits [
@@ -31,47 +35,39 @@ ERROR: roman-range-error n ;
     ] 2each drop ;
 
 : (roman>) ( seq -- n )
-    [ [ roman>n ] map ] [ all-eq? ] bi [
-        sum
-    ] [
-        first2 swap -
-    ] if ;
+    [ [ roman>n ] map ] [ all-eq? ] bi
+    [ sum ] [ first2 swap - ] if ;
 
 PRIVATE>
 
 : >roman ( n -- str )
-    dup roman-range-check
-    [ (>roman) ] "" make ;
+    dup roman-range-check [ (>roman) ] "" make ;
 
 : >ROMAN ( n -- str ) >roman >upper ;
 
 : roman> ( str -- n )
-    >lower [ roman<= ] monotonic-split
-    [ (roman>) ] sigma ;
+    >lower [ roman<= ] monotonic-split [ (roman>) ] sigma ;
 
 <PRIVATE
 
-: 2roman> ( str1 str2 -- m n )
-    [ roman> ] bi@ ;
-
-: binary-roman-op ( str1 str2 quot -- str3 )
-    [ 2roman> ] dip call >roman ; inline
+MACRO: binary-roman-op ( quot -- quot' )
+    [ infer in>> ] [ ] [ infer out>> ] tri
+    '[ [ roman> ] _ napply @ [ >roman ] _ napply ] ;
 
 PRIVATE>
 
-: roman+ ( str1 str2 -- str3 )
-    [ + ] binary-roman-op ;
-
-: roman- ( str1 str2 -- str3 )
-    [ - ] binary-roman-op ;
-
-: roman* ( str1 str2 -- str3 )
-    [ * ] binary-roman-op ;
-
-: roman/i ( str1 str2 -- str3 )
-    [ /i ] binary-roman-op ;
-
-: roman/mod ( str1 str2 -- str3 str4 )
-    [ /mod ] binary-roman-op [ >roman ] dip ;
-
-: ROMAN: scan roman> parsed ; parsing
+<<
+SYNTAX: ROMAN-OP:
+    scan-word [ name>> "roman" prepend create-in ] keep
+    1quotation '[ _ binary-roman-op ]
+    dup infer [ in>> ] [ out>> ] bi
+    [ "string" <repetition> ] bi@ <effect> define-declared ;
+>>
+
+ROMAN-OP: +
+ROMAN-OP: -
+ROMAN-OP: *
+ROMAN-OP: /i
+ROMAN-OP: /mod
+
+SYNTAX: ROMAN: scan roman> parsed ;
index 755d4ac9bc647307346b07e7416bc0fb167d8800..b2e99843c7ca230e641f456a2e745699382d01a7 100644 (file)
@@ -13,7 +13,12 @@ HELP: synopsis*
 
 HELP: see
 { $values { "defspec" "a definition specifier" } }
-{ $contract "Prettyprints a definition." } ;
+{ $contract "Prettyprints a definition." }
+{ $examples
+  "A word:" { $code "\\ append see" }
+  "A method:" { $code "USE: arrays" "M\\ array length see" }
+  "A help article:" { $code "USE: help.topics" "\"help\" >link see" }
+} ;
 
 HELP: see-methods
 { $values { "word" "a " { $link generic } " or a " { $link class } } }
@@ -25,7 +30,7 @@ HELP: definer
 { $examples
     { $example "USING: definitions prettyprint ;"
                "IN: scratchpad"
-               ": foo ; \\ foo definer . ."
+               ": foo ( -- ) ; \\ foo definer . ."
                ";\nPOSTPONE: :"
     }
     { $example "USING: definitions prettyprint ;"
@@ -50,6 +55,9 @@ $nl
 "Printing a definition:"
 { $subsection see }
 "Printing the methods defined on a generic word or class (see " { $link "objects" } "):"
-{ $subsection see-methods } ;
+{ $subsection see-methods }
+"Definition specifiers implementing the " { $link "definition-protocol" } " should also implement the " { $emphasis "see protocol" } ":"
+{ $subsection see* }
+{ $subsection synopsis* } ;
 
 ABOUT: "see"
\ No newline at end of file
diff --git a/basis/see/see-tests.factor b/basis/see/see-tests.factor
new file mode 100644 (file)
index 0000000..3f11ec9
--- /dev/null
@@ -0,0 +1,11 @@
+IN: see.tests
+USING: see tools.test io.streams.string math ;
+
+CONSTANT: test-const 10
+[ "IN: see.tests\nCONSTANT: test-const 10 inline\n" ]
+[ [ \ test-const see ] with-string-writer ] unit-test
+
+ALIAS: test-alias +
+
+[ "USING: math ;\nIN: see.tests\nALIAS: test-alias + inline\n" ]
+[ [ \ test-alias see ] with-string-writer ] unit-test
index ab9fa2006f16288e020a2ba69f8d774c4b139d05..2494c72fa4134b6e12cc8f884e69b19f2ab7dd38 100644 (file)
@@ -7,9 +7,11 @@ definitions effects generic generic.standard io io.pathnames
 io.streams.string io.styles kernel make namespaces prettyprint
 prettyprint.backend prettyprint.config prettyprint.custom
 prettyprint.sections sequences sets sorting strings summary
-words words.symbol ;
+words words.symbol words.constant words.alias ;
 IN: see
 
+GENERIC: synopsis* ( defspec -- )
+
 GENERIC: see* ( defspec -- )
 
 : see ( defspec -- ) see* nl ;
@@ -27,8 +29,16 @@ GENERIC: see* ( defspec -- )
 : comment. ( text -- )
     H{ { font-style italic } } styled-text ;
 
+GENERIC: print-stack-effect? ( word -- ? )
+
+M: parsing-word print-stack-effect? drop f ;
+M: symbol print-stack-effect? drop f ;
+M: constant print-stack-effect? drop f ;
+M: alias print-stack-effect? drop f ;
+M: word print-stack-effect? drop t ;
+
 : stack-effect. ( word -- )
-    [ [ parsing-word? ] [ symbol? ] bi or not ] [ stack-effect ] bi and
+    [ print-stack-effect? ] [ stack-effect ] bi and
     [ effect>string comment. ] when* ;
 
 <PRIVATE
@@ -66,9 +76,6 @@ M: hook-generic synopsis*
         [ stack-effect. ]
     } cleave ;
 
-M: method-spec synopsis*
-    first2 method synopsis* ;
-
 M: method-body synopsis*
     [ definer. ]
     [ "method-class" word-prop pprint-word ]
@@ -93,7 +100,6 @@ M: object declarations. drop ;
 
 M: word declarations.
     {
-        POSTPONE: parsing
         POSTPONE: delimiter
         POSTPONE: inline
         POSTPONE: recursive
@@ -113,9 +119,6 @@ M: object see*
         block>
     ] with-use ;
 
-M: method-spec see*
-    first2 method see* ;
-
 GENERIC: see-class* ( word -- )
 
 M: union-class see-class*
index 99c6d0e255f7afa586f2cae27d67d0d8853ec7b0..d23c8be84b928aef2aa3ed69c719918dd0e98711 100644 (file)
@@ -7,7 +7,7 @@ sequences math prettyprint parser classes math.constants
 io.encodings.binary random assocs serialize.private ;
 IN: serialize.tests
 
-: test-serialize-cell
+: test-serialize-cell ( a -- ? )
     2^ random dup
     binary [ serialize-cell ] with-byte-writer
     binary [ deserialize-cell ] with-byte-reader = ;
@@ -27,7 +27,7 @@ TUPLE: serialize-test a b ;
 
 C: <serialize-test> serialize-test
 
-: objects
+CONSTANT: objects
     {
         f
         t
@@ -52,7 +52,7 @@ C: <serialize-test> serialize-test
         << 1 [ 2 ] curry parsed >>
         { { "a" "bc" } { "de" "fg" } }
         H{ { "a" "bc" } { "de" "fg" } }
-    } ;
+    }
 
 : check-serialize-1 ( obj -- ? )
     "=====" print
index 6cae048d2764290f7ca9371725068f0fd894f95e..d6a4ba8bbbfad58715825ca05269955eaeabad45 100644 (file)
@@ -19,8 +19,8 @@ MACRO: shuffle-effect ( effect -- )
         [ [ at \ swap \ nth [ ] 3sequence ] curry map , \ cleave , ] 2bi
     ] [ ] make ;
 
-: shuffle(
-    ")" parse-effect parsed \ shuffle-effect parsed ; parsing
+SYNTAX: shuffle(
+    ")" parse-effect parsed \ shuffle-effect parsed ;
 
 : 2swap ( x y z t -- z t x y ) 2 2 mnswap ; inline
 
index 9ed5de7d2b3da93614db649879e51930e08b8e93..0223d94af9b0f16301dd145046929ea7355823fb 100644 (file)
@@ -1,8 +1,24 @@
-USING: help.syntax help.markup strings ;
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.syntax help.markup strings biassocs arrays ;
 IN: simple-flat-file
 
 ABOUT: "simple-flat-file"
 
 ARTICLE: "simple-flat-file" "Parsing simple flat files"
-"The " { $vocab-link "simple-flat-file" } " vocabulary provides words for loading and parsing simple flat files in a particular format which is common for encoding tasks."
-{ $subsection flat-file>biassoc } ;
+"The " { $vocab-link "simple-flat-file" } " vocabulary provides words for loading and parsing simple flat files in a particular format which is common for encoding and Unicode tasks."
+{ $subsection flat-file>biassoc }
+{ $subsection load-interval-file }
+{ $subsection data } ;
+
+HELP: load-interval-file
+{ $values { "filename" string } { "table" "an interval map" } }
+{ $description "This loads a file that looks like Script.txt in the Unicode Character Database and converts it into an efficient interval map, where the keys are characters and the values are strings for the properties." } ;
+
+HELP: data
+{ $values { "filename" string } { "data" array } }
+{ $description "This loads a file that's delineated by semicolons and lines, returning an array of lines, where each line is an array split by the semicolons, with whitespace trimmed off." } ;
+
+HELP: flat-file>biassoc
+{ $values { "filename" string } { "biassoc" biassoc } }
+{ $description "This loads a flat file, in the form that many encoding resource files are in, with two columns of numeric data in hex, and returns a biassoc associating them." } ;
index 403fc4d14b82e0a4b8056d0d5120184e867c3dbf..88a64b7746592e0c218c8a7a0d4b6bdefcb5a00c 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences splitting kernel math.parser io.files io.encodings.ascii biassocs ;
+USING: sequences splitting kernel math.parser io.files io.encodings.utf8
+biassocs ascii namespaces arrays make assocs interval-maps sets ;
 IN: simple-flat-file
 
 : drop-comments ( seq -- newseq )
-    [ "#" split1 drop ] map harvest ;
+    [ "#@" split first ] map harvest ;
 
 : split-column ( line -- columns )
     " \t" split harvest 2 short head 2 f pad-tail ;
@@ -22,5 +23,32 @@ IN: simple-flat-file
     drop-comments [ parse-line ] map ; 
 
 : flat-file>biassoc ( filename -- biassoc )
-    ascii file-lines process-codetable-lines >biassoc ;
+    utf8 file-lines process-codetable-lines >biassoc ;
 
+: split-; ( line -- array )
+    ";" split [ [ blank? ] trim ] map ;
+
+: data ( filename -- data )
+    utf8 file-lines drop-comments [ split-; ] map ;
+
+SYMBOL: interned
+
+: range, ( value key -- )
+    swap interned get
+    [ = ] with find nip 2array , ;
+
+: expand-ranges ( assoc -- interval-map )
+    [
+        [
+            swap CHAR: . over member? [
+                ".." split1 [ hex> ] bi@ 2array
+            ] [ hex> ] if range,
+        ] assoc-each
+    ] { } make <interval-map> ;
+
+: process-interval-file ( ranges -- table )
+    dup values prune interned
+    [ expand-ranges ] with-variable ;
+
+: load-interval-file ( filename -- table )
+    data process-interval-file ;
index 8e344116040edd5b11e1d5d4eb97f5483784d221..453f4009e281c61345e9c2dcbf52421af4edce9f 100644 (file)
@@ -73,6 +73,20 @@ HELP: send-email
     }
 } ;
 
+ARTICLE: "smtp-gmail" "Setting up SMTP with gmail"
+"If you plan to send all email from the same address, then setting variables in the global namespace is the best option. The code example below does this approach and is meant to go in your " { $link "factor-boot-rc" } "." $nl
+"Several variables need to be set for sending outgoing mail through gmail. First, we set the login and password to a " { $link <plain-auth> } " tuple with our login. Next, we set the gmail server address with an " { $link <inet> } " object. Finally, we tell the SMTP library to use a secure connection."
+{ $code
+    "USING: smtp namespaces io.sockets ;"
+    ""
+    "\"my.gmail.address@gmail.com\" \"secret-password\" <plain-auth> smtp-auth set-global"
+    ""
+    "\"smtp.gmail.com\" 587 <inet> smtp-server set-global"
+    ""
+    "t smtp-tls? set-global"
+} ;
+
+
 ARTICLE: "smtp" "SMTP client library"
 "The " { $vocab-link "smtp" } " vocabulary sends e-mail via an SMTP server."
 $nl
@@ -89,6 +103,8 @@ $nl
 { $subsection email }
 { $subsection <email> }
 "Sending an email:"
-{ $subsection send-email } ;
+{ $subsection send-email }
+"More topics:"
+{ $subsection "smtp-gmail" } ;
 
 ABOUT: "smtp"
diff --git a/basis/sorting/functor/authors.txt b/basis/sorting/functor/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/sorting/functor/functor.factor b/basis/sorting/functor/functor.factor
new file mode 100644 (file)
index 0000000..7f46af4
--- /dev/null
@@ -0,0 +1,16 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: functors kernel math.order sequences sorting ;
+IN: sorting.functor
+
+FUNCTOR: define-sorting ( NAME QUOT -- )
+
+NAME<=> DEFINES ${NAME}<=>
+NAME>=< DEFINES ${NAME}>=<
+
+WHERE
+
+: NAME<=> ( obj1 obj2 -- <=> ) QUOT bi@ <=> ;
+: NAME>=< ( obj1 obj2 -- >=< ) NAME<=> invert-comparison ;
+
+;FUNCTOR
index 5952b3e3f9fb21d0c1edd205416d99c8aea83904..4bb62b13132eeadd1129d280cfca672c6986754c 100644 (file)
@@ -25,46 +25,11 @@ HELP: human>=<
 }
 { $description "Compares two objects using the " { $link human<=> } " word and inverts the result." } ;
 
-HELP: human-compare
-{ $values
-     { "obj1" object } { "obj2" object } { "quot" quotation }
-     { "<=>" "an ordering specifier" }
-}
-{ $description "Compares the results of applying the quotation to both objects via <=>." } ;
-
-HELP: human-sort
-{ $values
-     { "seq" sequence }
-     { "seq'" sequence }
-}
-{ $description "Sorts a sequence of objects by comparing the magnitude of any integers in the input string using the <=> word." } ;
-
-HELP: human-sort-keys
-{ $values
-     { "seq" "an alist" }
-     { "sortedseq" "a new sorted sequence" }
-}
-{ $description "Sorts the elements comparing first elements of pairs using the " { $link human<=> } " word." } ;
-
-HELP: human-sort-values
-{ $values
-     { "seq" "an alist" }
-     { "sortedseq" "a new sorted sequence" }
-}
-{ $description "Sorts the elements comparing second elements of pairs using the " { $link human<=> } " word." } ;
-
-{ <=> >=< human-compare human-sort human-sort-keys human-sort-values } related-words
-
 ARTICLE: "sorting.human" "Human-friendly sorting"
 "The " { $vocab-link "sorting.human" } " vocabulary sorts by numbers as a human would -- by comparing their magnitudes -- rather than in a lexicographic way. For example, sorting a1, a10, a03, a2 with human sort returns a1, a2, a03, a10, while sorting with natural sort returns a03, a1, a10, a2." $nl
 "Comparing two objects:"
 { $subsection human<=> }
 { $subsection human>=< }
-{ $subsection human-compare }
-"Sort a sequence:"
-{ $subsection human-sort }
-{ $subsection human-sort-keys }
-{ $subsection human-sort-values }
 "Splitting a string into substrings and integers:"
 { $subsection find-numbers } ;
 
index 0e20b54c2f7460f0527454de279bc40f77896aec..20a607188cafc19d6ec06b21e34511706a99286d 100644 (file)
@@ -1,6 +1,4 @@
-USING: sorting.human tools.test ;
+USING: sorting.human tools.test sorting.slots ;
 IN: sorting.human.tests
 
-\ human-sort must-infer
-
-[ { "x1y" "x2" "x10y" } ] [ { "x1y" "x10y" "x2" } human-sort ] unit-test
+[ { "x1y" "x2" "x10y" } ] [ { "x1y" "x10y" "x2" } { human<=> } sort-by ] unit-test
index 1c7392901b3857f394d2bc2da96c0fe2aa7f7978..b3dae45a9b87d26fd94d46ed04e9439be96a1ebd 100644 (file)
@@ -1,22 +1,9 @@
 ! Copyright (C) 2008 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: peg.ebnf math.parser kernel assocs sorting fry
-math.order sequences ascii splitting.monotonic ;
+USING: math.parser peg.ebnf sorting.functor ;
 IN: sorting.human
 
 : find-numbers ( string -- seq )
     [EBNF Result = ([0-9]+ => [[ string>number ]] | (!([0-9]) .)+)* EBNF] ;
 
-: human<=> ( obj1 obj2 -- <=> ) [ find-numbers ] bi@ <=> ;
-
-: human>=< ( obj1 obj2 -- >=< ) human<=> invert-comparison ; inline
-
-: human-compare ( obj1 obj2 quot -- <=> ) bi@ human<=> ;
-
-: human-sort ( seq -- seq' ) [ human<=> ] sort ;
-
-: human-sort-keys ( seq -- sortedseq )
-    [ [ first ] human-compare ] sort ;
-
-: human-sort-values ( seq -- sortedseq )
-    [ [ second ] human-compare ] sort ;
+<< "human" [ find-numbers ] define-sorting >>
index a3bdbf9ac1cbc880ac883eed136c091507484558..cc89d497e78202b7349e121e214dd3ee4e255042 100644 (file)
@@ -14,7 +14,7 @@ HELP: compare-slots
 HELP: sort-by-slots
 { $values
      { "seq" sequence } { "sort-specs" "a sequence of accessors ending with a comparator" }
-     { "seq'" sequence }
+     { "sortedseq" sequence }
 }
 { $description "Sorts a sequence of tuples by the sort-specs in " { $snippet "sort-spec" } ". A sort-spec is a sequence of slot accessors ending in a comparator." }
 { $examples
@@ -39,11 +39,20 @@ HELP: split-by-slots
 }
 { $description "Splits a sequence of tuples into a sequence of slices of tuples that have the same values in all slots in the accessor sequence. This word is only useful for splitting a sorted sequence, but is more efficient than partitioning in such a case." } ;
 
+HELP: sort-by
+{ $values
+    { "seq" sequence } { "sort-seq" "a sequence of comparators" }
+    { "sortedseq" sequence }
+}
+{ $description "Sorts a sequence by comparing elements by comparators, using subsequent comparators when there is a tie." } ;
+
 ARTICLE: "sorting.slots" "Sorting by slots"
 "The " { $vocab-link "sorting.slots" } " vocabulary can sort tuples by slot in ascending or descending order, using subsequent slots as tie-breakers." $nl
 "Comparing two objects by a sequence of slots:"
 { $subsection compare-slots }
-"Sorting a sequence by a sequence of slots:"
-{ $subsection sort-by-slots } ;
+"Sorting a sequence of tuples by a slot/comparator pairs:"
+{ $subsection sort-by-slots }
+"Sorting a sequence by a sequence of comparators:"
+{ $subsection sort-by } ;
 
 ABOUT: "sorting.slots"
index 46824c6fdb17d6738a364ac0070a7a60d810c5cd..83900461c3dfbe0255c209edc71399b981ae3e30 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors math.order sorting.slots tools.test
-sorting.human arrays sequences kernel assocs multiline ;
+sorting.human arrays sequences kernel assocs multiline
+sorting.functor ;
 IN: sorting.literals.tests
 
 TUPLE: sort-test a b c tuple2 ;
@@ -76,6 +77,9 @@ TUPLE: tuple2 d ;
 [ { } ]
 [ { } { { a>> <=> } { b>> >=< } { c>> <=> } } sort-by-slots ] unit-test
 
+[ { } ]
+[ { } { } sort-by-slots ] unit-test
+
 [
     {
         T{ sort-test { a 6 } { tuple2 T{ tuple2 { d 1 } } } }
@@ -143,3 +147,15 @@ TUPLE: tuple2 d ;
         T{ sort-test { a 5 } { tuple2 T{ tuple2 { d 4 } } } }
     } { { tuple2>> d>> } { a>> } } split-by-slots [ >array ] map
 ] unit-test
+
+
+[ { "a" "b" "c" } ] [ { "b" "c" "a" } { <=> <=> } sort-by ] unit-test
+[ { "b" "c" "a" } ] [ { "b" "c" "a" } { } sort-by ] unit-test
+
+<< "length-test" [ length ] define-sorting >>
+
+[ { { 1 } { 1 2 3 } { 1 3 2 } { 3 2 1 } } ]
+[
+    { { 3 2 1 } { 1 2 3 } { 1 3 2 } { 1 } }
+    { length-test<=> <=> } sort-by
+] unit-test
index 56b6a115f07350f505dfb588fc8176512a6ac68c..efec960c2749855d67a2a4ef86bc5b3e4c7b6d8c 100644 (file)
@@ -7,13 +7,16 @@ IN: sorting.slots
 
 <PRIVATE
 
+: short-circuit-comparator ( obj1 obj2 word --  comparator/? )
+    execute dup +eq+ eq? [ drop f ] when ; inline
+
 : slot-comparator ( seq -- quot )
     [
         but-last-slice
         [ '[ [ _ execute ] bi@ ] ] map concat
     ] [
         peek
-        '[ @ _ execute dup +eq+ eq? [ drop f ] when ]
+        '[ @ _ short-circuit-comparator ]
     ] bi ;
 
 PRIVATE>
@@ -22,8 +25,20 @@ MACRO: compare-slots ( sort-specs -- <=> )
     #! sort-spec: { accessors comparator }
     [ slot-comparator ] map '[ _ 2|| +eq+ or ] ;
 
-: sort-by-slots ( seq sort-specs -- seq' )
-    '[ _ compare-slots ] sort ;
+MACRO: sort-by-slots ( sort-specs -- quot )
+    '[ [ _ compare-slots ] sort ] ;
+
+MACRO: compare-seq ( seq -- quot )
+    [ '[ _ short-circuit-comparator ] ] map '[ _ 2|| +eq+ or ] ;
+
+MACRO: sort-by ( sort-seq -- quot )
+    '[ [ _ compare-seq ] sort ] ;
+
+MACRO: sort-keys-by ( sort-seq -- quot )
+    '[ [ first ] bi@ _ compare-seq ] sort ;
+
+MACRO: sort-values-by ( sort-seq -- quot )
+    '[ [ second ] bi@ _ compare-seq ] sort ;
 
 MACRO: split-by-slots ( accessor-seqs -- quot )
     [ [ '[ [ _ execute ] bi@ ] ] map concat [ = ] compose ] map
diff --git a/basis/sorting/title/authors.txt b/basis/sorting/title/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/basis/sorting/title/title-tests.factor b/basis/sorting/title/title-tests.factor
new file mode 100644 (file)
index 0000000..65a58e4
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test sorting.title sorting.slots ;
+IN: sorting.title.tests
+
+: sort-me ( -- seq )
+    {
+        "The Beatles"
+        "A river runs through it"
+        "Another"
+        "la vida loca"
+        "Basketball"
+        "racquetball"
+        "Los Fujis"
+        "los Fujis"
+        "La cucaracha"
+        "a day to remember"
+        "of mice and men"
+        "on belay"
+        "for the horde"
+    } ;
+[
+    {
+        "Another"
+        "Basketball"
+        "The Beatles"
+        "La cucaracha"
+        "a day to remember"
+        "for the horde"
+        "Los Fujis"
+        "los Fujis"
+        "of mice and men"
+        "on belay"
+        "racquetball"
+        "A river runs through it"
+        "la vida loca"
+    }
+] [
+    sort-me { title<=> } sort-by
+] unit-test
diff --git a/basis/sorting/title/title.factor b/basis/sorting/title/title.factor
new file mode 100644 (file)
index 0000000..dbdbf8a
--- /dev/null
@@ -0,0 +1,7 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: sorting.functor regexp kernel accessors sequences
+unicode.case ;
+IN: sorting.title
+
+<< "title" [ >lower dup R/ ^(the|a|an|el|la|los|las|il) / first-match [ to>> tail-slice ] when* ] define-sorting >>
index 09433a3b51c7181ba62475a501acb441c2e50223..c6641463f90fabcf7fa7ee1211633c5d3587bf4a 100644 (file)
@@ -70,7 +70,7 @@ M: A >pprint-sequence ;
 
 M: A pprint* pprint-object ;
 
-: A{ \ } [ >A ] parse-literal ; parsing
+SYNTAX: A{ \ } [ >A ] parse-literal ;
 
 INSTANCE: A sequence
 
index 9d48a9e79e4c85c576bb7af075458064b82dcbd6..412e5b468984a302b4e2705aeb901a5a1f9e04c8 100644 (file)
@@ -39,7 +39,7 @@ M: V >pprint-sequence ;
 
 M: V pprint* pprint-object ;
 
-: V{ \ } [ >V ] parse-literal ; parsing
+SYNTAX: V{ \ } [ >V ] parse-literal ;
 
 INSTANCE: V growable
 
index df077ce18959e9c9f5a8586ff4290b12035a0246..82def17e4471521dff66c5e96e09de18f13a8d59 100644 (file)
@@ -1,5 +1,9 @@
 IN: specialized-vectors.tests
-USING: specialized-vectors.double tools.test kernel sequences ;
+USING: specialized-arrays.float
+specialized-vectors.float
+specialized-vectors.double
+tools.test kernel sequences ;
 
 [ 3 ] [ double-vector{ 1 2 } 3 over push length ] unit-test
 
+[ t ] [ 10 float-array{ } new-resizable float-vector? ] unit-test
\ No newline at end of file
index f52632040d23725697604b0d8186b764fcb0bde0..0b135319fffec3ab72176a54dc0e3605e8e27093 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences accessors combinators math namespaces
-init sets words
+init sets words alien.libraries
 alien alien.c-types
 stack-checker.backend stack-checker.errors stack-checker.visitor ;
 IN: stack-checker.alien
diff --git a/basis/stack-checker/call-effect/authors.txt b/basis/stack-checker/call-effect/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/stack-checker/call-effect/call-effect-tests.factor b/basis/stack-checker/call-effect/call-effect-tests.factor
new file mode 100644 (file)
index 0000000..e5c0f23
--- /dev/null
@@ -0,0 +1,7 @@
+USING: stack-checker.call-effect tools.test math kernel ;
+IN: stack-checker.call-effect.tests
+
+[ t ] [ \ + (( a b -- c )) execute-effect-unsafe? ] unit-test
+[ t ] [ \ + (( a b c -- d e )) execute-effect-unsafe? ] unit-test
+[ f ] [ \ + (( a b c -- d )) execute-effect-unsafe? ] unit-test
+[ f ] [ \ call (( x -- )) execute-effect-unsafe? ] unit-test
\ No newline at end of file
diff --git a/basis/stack-checker/call-effect/call-effect.factor b/basis/stack-checker/call-effect/call-effect.factor
new file mode 100644 (file)
index 0000000..bd1f7c7
--- /dev/null
@@ -0,0 +1,95 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators combinators.private effects fry
+kernel kernel.private make sequences continuations quotations
+stack-checker stack-checker.transforms ;
+IN: stack-checker.call-effect
+
+! call( and execute( have complex expansions.
+
+! call( uses the following strategy:
+! - Inline caching. If the quotation is the same as last time, just call it unsafely
+! - Effect inference. Infer quotation's effect, caching it in the cached-effect slot,
+!   and compare it with declaration. If matches, call it unsafely.
+! - Fallback. If the above doesn't work, call it and compare the datastack before
+!   and after to make sure it didn't mess anything up.
+
+! execute( uses a similar strategy.
+
+TUPLE: inline-cache value ;
+
+: cache-hit? ( word/quot ic -- ? ) value>> eq? ; inline
+
+SYMBOL: +unknown+
+
+GENERIC: cached-effect ( quot -- effect )
+
+M: object cached-effect drop +unknown+ ;
+
+M: quotation cached-effect
+    dup cached-effect>>
+    [ ] [
+        [ [ infer ] [ 2drop +unknown+ ] recover dup ] keep
+        (>>cached-effect)
+    ] ?if ;
+
+: call-effect-unsafe? ( quot effect -- ? )
+    [ cached-effect ] dip
+    over +unknown+ eq?
+    [ 2drop f ] [ effect<= ] if ; inline
+
+: (call-effect-slow>quot) ( in out effect -- quot )
+    [
+        [ [ datastack ] dip dip ] %
+        [ [ , ] bi@ \ check-datastack , ] dip
+        '[ _ wrong-values ] , \ unless ,
+    ] [ ] make ;
+
+: call-effect-slow>quot ( effect -- quot )
+    [ in>> length ] [ out>> length ] [ ] tri
+    [ (call-effect-slow>quot) ] keep add-effect-input
+    [ call-effect-unsafe ] 2curry ;
+
+: call-effect-slow ( quot effect -- ) drop call ;
+
+\ call-effect-slow [ call-effect-slow>quot ] 1 define-transform
+
+: call-effect-fast ( quot effect inline-cache -- )
+    2over call-effect-unsafe?
+    [ [ nip (>>value) ] [ drop call-effect-unsafe ] 3bi ]
+    [ drop call-effect-slow ]
+    if ; inline
+
+\ call-effect [
+    inline-cache new '[
+        _
+        3dup nip cache-hit? [
+            drop call-effect-unsafe
+        ] [
+            call-effect-fast
+        ] if
+    ]
+] 0 define-transform
+
+: execute-effect-slow ( word effect -- )
+    [ '[ _ execute ] ] dip call-effect-slow ; inline
+
+: execute-effect-unsafe? ( word effect -- ? )
+    over optimized>> [ [ stack-effect ] dip effect<= ] [ 2drop f ] if ; inline
+
+: execute-effect-fast ( word effect inline-cache -- )
+    2over execute-effect-unsafe?
+    [ [ nip (>>value) ] [ drop execute-effect-unsafe ] 3bi ]
+    [ drop execute-effect-slow ]
+    if ; inline
+
+: execute-effect-ic ( word effect inline-cache -- )
+    3dup nip cache-hit?
+    [ drop execute-effect-unsafe ]
+    [ execute-effect-fast ]
+    if ; inline
+
+: execute-effect>quot ( effect -- quot )
+    inline-cache new '[ _ _ execute-effect-ic ] ;
+
+\ execute-effect [ execute-effect>quot ] 1 define-transform
index 7f35ece71473fe7fee5ce7c5ee0f819089587da0..07c26ad100f4490a19290245ab6eaadfba248570 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2006, 2008 Slava Pestov.
+! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel generic sequences io words arrays summary effects
-assocs accessors namespaces compiler.errors stack-checker.values
-stack-checker.recursive-state ;
+continuations assocs accessors namespaces compiler.errors
+stack-checker.values stack-checker.recursive-state ;
 IN: stack-checker.errors
 
 : pretty-word ( word -- word' )
@@ -15,7 +15,7 @@ M: inference-error compiler-error-type type>> ;
 : (inference-error) ( ... class type -- * )
     [ boa ] dip
     recursive-state get word>>
-    \ inference-error boa throw ; inline
+    \ inference-error boa rethrow ; inline
 
 : inference-error ( ... class -- * )
     +error+ (inference-error) ; inline
index e366073326e1f5d5ae762127780247f76ce1dde0..c55e69a8a275fcda4af42d749345d63880cfad3d 100644 (file)
@@ -11,7 +11,8 @@ strings.private system threads.private classes.tuple
 classes.tuple.private vectors vectors.private words definitions
 words.private assocs summary compiler.units system.private
 combinators locals locals.backend locals.types words.private
-quotations.private call call.private stack-checker.values
+quotations.private combinators.private stack-checker.values
+alien.libraries
 stack-checker.alien
 stack-checker.state
 stack-checker.errors
@@ -135,17 +136,16 @@ M: object infer-call*
     peek-d literal value>> second 1+ { tuple } <effect>
     apply-word/effect ;
 
-: infer-(throw) ( -- )
-    \ (throw)
-    peek-d literal value>> 2 + { "*" } <effect>
+: infer-effect-unsafe ( word -- )
+    pop-literal nip
+    add-effect-input
     apply-word/effect ;
 
 : infer-execute-effect-unsafe ( -- )
-    \ execute
-    pop-literal nip
-    [ in>> "word" suffix ] [ out>> ] [ terminated?>> ] tri
-    effect boa
-    apply-word/effect ;
+    \ execute infer-effect-unsafe ;
+
+: infer-call-effect-unsafe ( -- )
+    \ call infer-effect-unsafe ;
 
 : infer-exit ( -- )
     \ exit (( n -- * )) apply-word/effect ;
@@ -186,10 +186,10 @@ M: object infer-call*
         { \ execute [ infer-execute ] }
         { \ (execute) [ infer-execute ] }
         { \ execute-effect-unsafe [ infer-execute-effect-unsafe ] }
+        { \ call-effect-unsafe [ infer-call-effect-unsafe ] }
         { \ if [ infer-if ] }
         { \ dispatch [ infer-dispatch ] }
         { \ <tuple-boa> [ infer-<tuple-boa> ] }
-        { \ (throw) [ infer-(throw) ] }
         { \ exit [ infer-exit ] }
         { \ load-local [ 1 infer->r ] }
         { \ load-locals [ infer-load-locals ] }
@@ -212,9 +212,10 @@ M: object infer-call*
 
 {
     declare call (call) slip 2slip 3slip dip 2dip 3dip curry compose
-    execute (execute) execute-effect-unsafe if dispatch <tuple-boa>
-    (throw) exit load-local load-locals get-local drop-locals
-    do-primitive alien-invoke alien-indirect alien-callback
+    execute (execute) call-effect-unsafe execute-effect-unsafe if
+    dispatch <tuple-boa> exit load-local load-locals get-local
+    drop-locals do-primitive alien-invoke alien-indirect
+    alien-callback
 } [ t "special" set-word-prop ] each
 
 { call execute dispatch load-locals get-local drop-locals }
@@ -604,6 +605,8 @@ M: object infer-call*
 
 \ fflush { alien } { } define-primitive
 
+\ fseek { alien integer integer } { } define-primitive
+
 \ fclose { alien } { } define-primitive
 
 \ <wrapper> { object } { wrapper } define-primitive
@@ -627,6 +630,9 @@ M: object infer-call*
 \ datastack { } { array } define-primitive
 \ datastack make-flushable
 
+\ check-datastack { array integer integer } { object } define-primitive
+\ check-datastack make-flushable
+
 \ retainstack { } { array } define-primitive
 \ retainstack make-flushable
 
index 088fab34d0249db028810cf1f0f49c5323bec839..28090918bbc7aec7f5a6db11768226beaba964f5 100644 (file)
@@ -33,9 +33,9 @@ $nl
 "A general rule of thumb is that any word which applies " { $link call } " or " { $link curry } " to one of its inputs must be declared " { $link POSTPONE: inline } "."
 $nl
 "Here is an example where the stack effect cannot be inferred:"
-{ $code ": foo 0 [ + ] ;" "[ foo reduce ] infer." }
+{ $code ": foo ( -- n quot ) 0 [ + ] ;" "[ foo reduce ] infer." }
 "However if " { $snippet "foo" } " was declared " { $link POSTPONE: inline } ", everything would work, since the " { $link reduce } " combinator is also " { $link POSTPONE: inline } ", and the inferencer can see the literal quotation value at the point it is passed to " { $link call } ":"
-{ $example ": foo 0 [ + ] ; inline" "[ foo reduce ] infer." "( object -- object )" }
+{ $example ": foo ( -- n quot ) 0 [ + ] ; inline" "[ foo reduce ] infer." "( object -- object )" }
 "Passing a literal quotation on the data stack through an inlined recursive combinator nullifies its literal status. For example, the following will not infer:"
 { $example
   "[ [ reverse ] swap [ reverse ] map swap call ] infer." "Got a computed value where a literal quotation was expected\n\nType :help for debugging help."
index c881ccee11438e9ed7987f72b770b3a185d7d20d..117b6845b8847e683014a6eec4e2ce1e9965c206 100644 (file)
@@ -7,7 +7,7 @@ sorting assocs definitions prettyprint io inspector
 classes.tuple classes.union classes.predicate debugger
 threads.private io.streams.string io.timeouts io.thread
 sequences.private destructors combinators eval locals.backend
-system ;
+system compiler.units ;
 IN: stack-checker.tests
 
 \ infer. must-infer
@@ -292,7 +292,7 @@ DEFER: bar
 
 [ [ [ m ] m ] infer ] [ inference-error? ] must-fail-with
 
-: m' dup curry call ; inline
+: m' ( quot -- ) dup curry call ; inline
 
 [ [ [ m' ] m' ] infer ] [ inference-error? ] must-fail-with
 
@@ -580,4 +580,11 @@ DEFER: eee'
 
 [ [ ] debugging-curry-folding ] must-infer
 
-[ [ exit ] [ 1 2 3 ] if ] must-infer
\ No newline at end of file
+[ [ exit ] [ 1 2 3 ] if ] must-infer
+
+! Stack effects are required now but FORGET: clears them...
+: forget-test ( -- ) ;
+
+[ forget-test ] must-infer
+[ ] [ [ \ forget-test forget ] with-compilation-unit ] unit-test
+[ forget-test ] must-infer
\ No newline at end of file
index ff283ce9cab53e91b59954b013ec8e9e0b281874..e18a6f08406d49b86b158b750cd92183e77e9c00 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel io effects namespaces sequences quotations vocabs
-generic words stack-checker.backend stack-checker.state
+vocabs.loader generic words stack-checker.backend stack-checker.state
 stack-checker.known-words stack-checker.transforms
 stack-checker.errors stack-checker.inlining
 stack-checker.visitor.dummy ;
@@ -28,3 +28,5 @@ M: callable infer ( quot -- effect )
         dup subwords [ f "inferred-effect" set-word-prop ] each
         f "inferred-effect" set-word-prop
     ] each ;
+
+"stack-checker.call-effect" require
\ No newline at end of file
index 1901f27a24507e2512d93a1f956aaaa0d2f05714..a44f8d7f8d462129605979ca2bec95cc98dc3a48 100644 (file)
@@ -1 +1,2 @@
 Slava Pestov
+Daniel Ehrenberg
index fe580084c06977e77d0d7ec39b988d269eceb6b6..0aa38769079edfbade031f4ba86f425561bf4d5f 100644 (file)
@@ -3,8 +3,8 @@ USING: sequences stack-checker.transforms tools.test math kernel
 quotations stack-checker accessors combinators words arrays
 classes classes.tuple ;
 
-: compose-n-quot ( word -- quot' ) <repetition> >quotation ;
-: compose-n ( quot -- ) compose-n-quot call ;
+: compose-n-quot ( word -- quot' ) <repetition> >quotation ;
+: compose-n ( quot -- ) compose-n-quot call ;
 \ compose-n [ compose-n-quot ] 2 define-transform
 : compose-n-test ( a b c -- x ) 2 \ + compose-n ;
 
@@ -65,4 +65,9 @@ DEFER: curry-folding-test ( quot -- )
 
 { 3 0 } [ [ 1 2 3 ] curry-folding-test ] must-infer-as
 { 3 0 } [ 1 [ 2 3 ] curry curry-folding-test ] must-infer-as
-{ 3 0 } [ [ 1 2 ] 3 [ ] curry compose curry-folding-test ] must-infer-as
\ No newline at end of file
+{ 3 0 } [ [ 1 2 ] 3 [ ] curry compose curry-folding-test ] must-infer-as
+
+: member?-test ( a -- ? ) { 1 2 3 10 7 58 } member? ;
+
+[ f ] [ 1.0 member?-test ] unit-test
+[ t ] [ \ member?-test def>> first [ member?-test ] all? ] unit-test
\ No newline at end of file
index 791e0e65c113d51317e31c560f2271217775c835..c2b348f5f1228ede105a61b80ee5d62b24e05982 100755 (executable)
@@ -1,19 +1,21 @@
-! Copyright (C) 2007, 2009 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: fry accessors arrays kernel words sequences generic math
-namespaces make quotations assocs combinators classes.tuple
-classes.tuple.private effects summary hashtables classes generic
-sets definitions generic.standard slots.private continuations locals
+USING: fry accessors arrays kernel kernel.private combinators.private
+words sequences generic math math.order namespaces make quotations assocs
+combinators combinators.short-circuit classes.tuple
+classes.tuple.private effects summary hashtables classes generic sets
+definitions generic.standard slots.private continuations locals
 generalizations stack-checker.backend stack-checker.state
 stack-checker.visitor stack-checker.errors stack-checker.values
 stack-checker.recursive-state ;
 IN: stack-checker.transforms
 
 : give-up-transform ( word -- )
-    dup recursive-word?
-    [ call-recursive-word ]
-    [ dup infer-word apply-word/effect ]
-    if ;
+    {
+        { [ dup "inferred-effect" word-prop ] [ cached-infer ] }
+        { [ dup recursive-word? ] [ call-recursive-word ] }
+        [ dup infer-word apply-word/effect ]
+    } cond ;
 
 :: ((apply-transform)) ( word quot values stack rstate -- )
     rstate recursive-state
@@ -105,43 +107,39 @@ IN: stack-checker.transforms
 ] 1 define-transform
 
 ! Membership testing
-CONSTANT: bit-member-n 256
+CONSTANT: bit-member-max 256
 
 : bit-member? ( seq -- ? )
     #! Can we use a fast byte array test here?
     {
-        { [ dup length 8 < ] [ f ] }
-        { [ dup [ integer? not ] any? ] [ f ] }
-        { [ dup [ 0 < ] any? ] [ f ] }
-        { [ dup [ bit-member-n >= ] any? ] [ f ] }
-        [ t ]
-    } cond nip ;
+        [ length 4 > ]
+        [ [ integer? ] all? ]
+        [ [ 0 bit-member-max between? ] any? ]
+    } 1&& ;
 
 : bit-member-seq ( seq -- flags )
-    bit-member-n swap [ member? 1 0 ? ] curry B{ } map-as ;
-
-: exact-float? ( f -- ? )
-    dup float? [ dup >integer >float = ] [ drop f ] if ; inline
+    [ supremum 1+ ] keep '[ _ member? 1 0 ? ] B{ } map-as ;
 
 : bit-member-quot ( seq -- newquot )
-    [
-        bit-member-seq ,
-        [
-            {
-                { [ over fixnum? ] [ ?nth 1 eq? ] }
-                { [ over bignum? ] [ ?nth 1 eq? ] }
-                { [ over exact-float? ] [ ?nth 1 eq? ] }
-                [ 2drop f ]
-            } cond
-        ] %
-    ] [ ] make ;
+    bit-member-seq
+    '[
+        _ {
+            { [ over fixnum? ] [ ?nth 1 eq? ] }
+            { [ over bignum? ] [ ?nth 1 eq? ] }
+            [ 2drop f ]
+        } cond
+    ] ;
 
 : member-quot ( seq -- newquot )
     dup bit-member? [
         bit-member-quot
     ] [
-        [ literalize [ t ] ] { } map>assoc
-        [ drop f ] suffix [ case ] curry
+        dup length 4 <= [
+            [ drop f ] swap
+            [ literalize [ t ] ] { } map>assoc linear-case-quot
+        ] [
+            unique [ key? ] curry
+        ] if
     ] if ;
 
 \ member? [
@@ -156,6 +154,15 @@ CONSTANT: bit-member-n 256
     dup sequence? [ memq-quot ] [ drop f ] if
 ] 1 define-transform
 
+! Index search
+\ index [
+    dup sequence? [
+        dup length 4 >= [
+            dup length zip >hashtable '[ _ at ]
+        ] [ drop f ] if
+    ] [ drop f ] if
+] 1 define-transform
+
 ! Shuffling
 : nths-quot ( indices -- quot )
     [ [ '[ _ swap nth ] ] map ] [ length ] bi
index fa68cc0a8e0a1f63bb3be31d1f4e134ee650cdec..f4bd56348130f88a8b2a3c74ca7d13ef9892075d 100755 (executable)
@@ -32,7 +32,7 @@ PRIVATE>
 : >suffix-array ( seq -- array )
     [ suffixes ] map concat natural-sort ;
 
-: SA{ \ } [ >suffix-array ] parse-literal ; parsing
+SYNTAX: SA{ \ } [ >suffix-array ] parse-literal ;
 
 : query ( begin suffix-array -- matches )
     2dup find-index dup
index 5604a94dbdca787c27719e1b3dcb95dfdeab6158..bc9612f55ccc388b6f78e0d0849a5bcbcd639bb3 100644 (file)
@@ -35,9 +35,9 @@ HELP: download-feed
 { $values { "url" url } { "feed" feed } }
 { $description "Downloads a feed from a URL using the " { $link "http.client" } "." } ;
 
-HELP: string>feed
-{ $values { "string" string } { "feed" feed } }
-{ $description "Parses a feed in string form." } ;
+HELP: parse-feed
+{ $values { "seq" "a string or a byte array" } { "feed" feed } }
+{ $description "Parses a feed." } ;
 
 HELP: xml>feed
 { $values { "xml" xml } { "feed" feed } }
@@ -58,7 +58,7 @@ $nl
 { $subsection <entry> }
 "Reading feeds:"
 { $subsection download-feed }
-{ $subsection string>feed }
+{ $subsection parse-feed }
 { $subsection xml>feed }
 "Writing feeds:"
 { $subsection feed>xml }
index 616ce2723a6a2d23767730a90a15de805da7cd3d..3ea037352c6b711300740185b993ee18530f9ddc 100644 (file)
@@ -1,4 +1,4 @@
-USING: syndication io kernel io.files tools.test io.encodings.utf8
+USING: syndication io kernel io.files tools.test io.encodings.binary
 calendar urls xml.writer ;
 IN: syndication.tests
 
@@ -8,7 +8,7 @@ IN: syndication.tests
 : load-news-file ( filename -- feed )
     #! Load an news syndication file and process it, returning
     #! it as an feed tuple.
-    utf8 file-contents string>feed ;
+    binary file-contents parse-feed ;
 
 [ T{
     feed
index 9901fd4ce4a7b86044e36a1029899568e197d1c5..e30cd6826c7f0dd29df44ae50d5ecbba6fcee05d 100755 (executable)
@@ -1,11 +1,11 @@
 ! Copyright (C) 2006 Chris Double, Daniel Ehrenberg.
-! Portions copyright (C) 2008 Slava Pestov.
+! Portions copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: xml.traversal kernel assocs math.order
-    strings sequences xml.data xml.writer
-    io.streams.string combinators xml xml.entities.html io.files io
-    http.client namespaces make xml.syntax hashtables
-    calendar.format accessors continuations urls present ;
+USING: xml.traversal kernel assocs math.order strings sequences
+xml.data xml.writer io.streams.string combinators xml
+xml.entities.html io.files io http.client namespaces make
+xml.syntax hashtables calendar.format accessors continuations
+urls present byte-arrays ;
 IN: syndication
 
 : any-tag-named ( tag names -- tag-inside )
@@ -106,12 +106,15 @@ TUPLE: entry title url description date ;
         { "feed" [ atom1.0 ] }
     } case ;
 
-: string>feed ( string -- feed )
-    [ string>xml xml>feed ] with-html-entities ;
+GENERIC: parse-feed ( seq -- feed )
+
+M: string parse-feed [ string>xml xml>feed ] with-html-entities ;
+
+M: byte-array parse-feed [ bytes>xml xml>feed ] with-html-entities ;
 
 : download-feed ( url -- feed )
     #! Retrieve an news syndication file, return as a feed tuple.
-    http-get nip string>feed ;
+    http-get nip parse-feed ;
 
 ! Atom generation
 
index 3f4267df15e7771614719d259e390d36a1ec737c..cacc628e2a5a6c7dff401bbc2cbf51b0f056de62 100644 (file)
@@ -1,10 +1,10 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! Copyright (C) 2005 Mackenzie Straight.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays hashtables heaps kernel kernel.private math
 namespaces sequences vectors continuations continuations.private
-dlists assocs system combinators init boxes accessors
-math.order deques strings quotations fry ;
+dlists assocs system combinators combinators.private init boxes
+accessors math.order deques strings quotations fry ;
 IN: threads
 
 SYMBOL: initial-thread
@@ -126,7 +126,7 @@ DEFER: stop
         { } set-retainstack
         { } set-datastack
         self quot>> [ call stop ] call-clear
-    ] 2 (throw) ;
+    ] (( namestack thread -- * )) call-effect-unsafe ;
 
 DEFER: next
 
@@ -160,7 +160,7 @@ DEFER: next
 PRIVATE>
 
 : stop ( -- )
-    self [ exit-handler>> call ] [ unregister-thread ] bi next ;
+    self [ exit-handler>> call( -- ) ] [ unregister-thread ] bi next ;
 
 : suspend ( quot state -- obj )
     [
index 7e377aedd90abe4390ddebc3b9ddfa8d64a52337..9fa9d1e2aa1b317c401dbf762fe285eff76e91e2 100644 (file)
@@ -2,7 +2,7 @@ USING: tools.test tools.annotations tools.time math parser eval
 io.streams.string kernel strings ;
 IN: tools.annotations.tests
 
-: foo ;
+: foo ( -- ) ;
 \ foo watch
 
 [ ] [ foo ] unit-test
@@ -43,6 +43,6 @@ GENERIC: blah-generic ( a -- b )
 
 M: string blah-generic ;
 
-{ string blah-generic } watch
+[ ] [ M\ string blah-generic watch ] unit-test
 
 [ "hi" ] [ "hi" blah-generic ] unit-test
index 293a22d2bb95ea8e23a8f3eff39eb85d8b42f0b9..64e6508ab62e34f45022872dbd1e638514b65667 100644 (file)
@@ -20,9 +20,6 @@ M: word reset
         f "unannotated-def" set-word-prop
     ] [ drop ] if ;
 
-M: method-spec reset
-    first2 method reset ;
-
 ERROR: cannot-annotate-twice word ;
 
 <PRIVATE
@@ -32,20 +29,17 @@ ERROR: cannot-annotate-twice word ;
         cannot-annotate-twice
     ] when ;
 
-: method-spec>word ( obj -- word )
-    dup method-spec? [ first2 method ] when ;
-
 : save-unannotated-def ( word -- )
     dup def>> "unannotated-def" set-word-prop ;
 
 : (annotate) ( word quot -- )
-    [ dup def>> ] dip call define ; inline
+    [ dup def>> ] dip call( old -- new ) define ;
 
 PRIVATE>
 
 : annotate ( word quot -- )
-    [ method-spec>word check-annotate-twice ] dip
-    [ over save-unannotated-def (annotate) ] with-compilation-unit ; inline
+    [ check-annotate-twice ] dip
+    [ over save-unannotated-def (annotate) ] with-compilation-unit ;
 
 <PRIVATE
 
@@ -103,9 +97,6 @@ M: generic annotate-methods
 M: word annotate-methods
     annotate ;
 
-M: method-spec annotate-methods
-    annotate ;
-
 : breakpoint ( word -- )
     [ add-breakpoint ] annotate-methods ;
 
diff --git a/basis/tools/apropos/apropos-docs.factor b/basis/tools/apropos/apropos-docs.factor
deleted file mode 100644 (file)
index b50b51b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-IN: tools.apropos
-USING: help.markup help.syntax strings ;
-
-HELP: apropos
-{ $values { "str" string } }
-{ $description "Lists all words, vocabularies and help articles whose name contains a subsequence equal to " { $snippet "str" } ". Results are ranked using a simple distance algorithm." } ;
diff --git a/basis/tools/apropos/apropos-tests.factor b/basis/tools/apropos/apropos-tests.factor
deleted file mode 100644 (file)
index 96ce9d3..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-IN: tools.apropos.tests
-USING: tools.apropos tools.test ;
-
-[ ] [ "swp" apropos ] unit-test
diff --git a/basis/tools/apropos/apropos.factor b/basis/tools/apropos/apropos.factor
deleted file mode 100644 (file)
index c7126c1..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-! Copyright (C) 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs fry help.markup help.topics io
-kernel make math math.parser namespaces sequences sorting
-summary tools.completion tools.vocabs tools.vocabs.browser
-vocabs words unicode.case help ;
-IN: tools.apropos
-
-: $completions ( seq -- )
-    dup [ word? ] all? [ words-table ] [
-        dup [ vocab-spec? ] all? [
-            $vocabs
-        ] [
-            [ <$pretty-link> 1array ] map $table
-        ] if
-    ] if ;
-
-TUPLE: more-completions seq ;
-
-CONSTANT: max-completions 5
-
-M: more-completions article-title
-    seq>> length number>string " results" append ;
-
-M: more-completions article-name
-    seq>> length max-completions - number>string " more results" append ;
-
-M: more-completions article-content
-    seq>> sort-values keys \ $completions prefix ;
-
-: (apropos) ( str candidates title -- element )
-    [
-        [ completions ] dip '[
-            _ 1array \ $heading prefix ,
-            [ max-completions short head keys \ $completions prefix , ]
-            [ dup length max-completions > [ more-completions boa <$link> , ] [ drop ] if ]
-            bi
-        ] unless-empty
-    ] { } make ;
-
-: word-candidates ( words -- candidates )
-    [ dup name>> >lower ] { } map>assoc ;
-
-: vocab-candidates ( -- candidates )
-    all-vocabs-seq [ dup vocab-name >lower ] { } map>assoc ;
-
-: help-candidates ( seq -- candidates )
-    [ [ >link ] [ article-title >lower ] bi ] { } map>assoc
-    sort-values ;
-
-: $apropos ( str -- )
-    first
-    [ all-words word-candidates "Words" (apropos) ]
-    [ vocab-candidates "Vocabularies" (apropos) ]
-    [ articles get keys help-candidates "Help articles" (apropos) ]
-    tri 3array print-element ;
-
-TUPLE: apropos search ;
-
-C: <apropos> apropos
-
-M: apropos article-title
-    search>> "Search results for “" "”" surround ;
-
-M: apropos article-name article-title ;
-
-M: apropos article-content
-    search>> 1array \ $apropos prefix ;
-
-: apropos ( str -- )
-    <apropos> print-topic ;
index d4f2fea2e5c97229f1cf1198ab71c55e46243f90..d08a17fd020eb1157e7980770347ae6e0a751902 100755 (executable)
@@ -3,7 +3,7 @@ tools.crossref tools.test parser namespaces source-files generic
 definitions ;
 IN: tools.crossref.tests
 
-GENERIC: foo
+GENERIC: foo ( a b -- c )
 
 M: integer foo + ;
 
index 28a32790dcae934258d70b92e52b08ce9debfe7c..6ca54ca36b6ca1b7b3c8a4d42ed154ace4b751c5 100755 (executable)
@@ -8,7 +8,7 @@ debugger io.streams.c io.files io.files.temp io.pathnames
 io.directories io.directories.hierarchy io.backend quotations
 io.launcher words.private tools.deploy.config
 tools.deploy.config.editor bootstrap.image io.encodings.utf8
-destructors accessors ;
+destructors accessors hashtables ;
 IN: tools.deploy.backend
 
 : copy-vm ( executable bundle-name -- vm )
@@ -88,7 +88,7 @@ DEFER: ?make-staging-image
     [ drop ] [ make-staging-image ] if ;
 
 : make-deploy-config ( vocab -- file )
-    [ deploy-config unparse-use ]
+    [ deploy-config vocab-roots get vocab-roots associate assoc-union unparse-use ]
     [ "deploy-config-" prepend temp-file ] bi
     [ utf8 set-file-contents ] keep ;
 
index 00e747cf0076aaf298890f16ad09d26228d8519f..4c03047eb86960ea856790387553076ac1acb339 100644 (file)
@@ -1,5 +1,5 @@
 USING: help.markup help.syntax words alien.c-types assocs
-kernel ;
+kernel combinators combinators.private tools.deploy.config ;
 IN: tools.deploy
 
 ARTICLE: "prepare-deploy" "Preparing to deploy an application"
@@ -7,25 +7,43 @@ ARTICLE: "prepare-deploy" "Preparing to deploy an application"
 { $subsection "deploy-config" }
 { $subsection "deploy-flags" } ;
 
-ARTICLE: "tools.deploy" "Application deployment"
-"The stand-alone application deployment tool compiles a vocabulary down to a native executable which runs the vocabulary's " { $link POSTPONE: MAIN: } " hook. Deployed executables do not depend on Factor being installed, and do not expose any source code, and thus are suitable for delivering commercial end-user applications."
-$nl
-"For example, we can deploy the " { $vocab-link "hello-world" } " demo which comes with Factor:"
+ARTICLE: "tools.deploy.usage" "Deploy tool usage"
+"Once the necessary deployment flags have been set, the application can be deployed:"
+{ $subsection deploy }
+"For example, you can deploy the " { $vocab-link "hello-ui" } " demo which comes with Factor. Note that this demo already has a deployment configuration, so nothing needs to be configured:"
 { $code "\"hello-ui\" deploy" }
 { $list
    { "On Mac OS X, this yields a program named " { $snippet "Hello world.app" } "." }
    { "On Windows, it yields a directory named " { $snippet "Hello world" } " containing a program named " { $snippet "hello-ui.exe" } "." }
    { "On Unix-like systems (Linux, BSD, Solaris, etc), it yields a directory named " { $snippet "Hello world" } " containing a program named " { $snippet "hello-ui" } "." }
 }
-"In all cases, running the program displays a window with a message."
-$nl
+"On all platforms, running the program will display a window with a message." ;
+
+ARTICLE: "tools.deploy.impl" "Deploy tool implementation"
 "The deployment tool works by bootstrapping a fresh image, loading the vocabulary into this image, then applying various heuristics to strip the image down to minimal size."
 $nl
+"The deploy tool generates " { $emphasis "staging images" } " containing major subsystems, and uses the staging images to derive the final application image. The first time an application is deployed using a major subsystem, such as the UI, a new staging image is made, which can take a few minutes. Subsequent deployments of applications using this subsystem will be much faster." ;
+
+ARTICLE: "tools.deploy.caveats" "Deploy tool caveats"
+{ $heading "Behavior of " { $link boa } }
+"In deployed applications, the " { $link boa } " word does not verify that the parameters on the stack satisfy the tuple's slot declarations, if any. This reduces deploy image size but can make bugs harder to track down. Make sure your program is fully debugged before deployment."
+{ $heading "Behavior of " { $link POSTPONE: execute( } }
+"Similarly, the " { $link POSTPONE: execute( } " word does not check word stack effects in deployed applications, since stack effects are stripped out, and so it behaves exactly like " { $link POSTPONE: execute-effect-unsafe } "."
+{ $heading "Error reporting" }
+"If the " { $link deploy-reflection } " level in the configuration is low enough, the debugger is stripped out, and error messages can be rather cryptic. Increase the reflection level to get readable error messages."
+{ $heading "Choosing the right deploy flags" }
+"Finding the correct deploy flags is a trial and error process; you must find a tradeoff between deployed image size and correctness. If your program uses dynamic language features, you may need to elect to strip out fewer subsystems in order to have full functionality." ;
+
+ARTICLE: "tools.deploy" "Application deployment"
+"The stand-alone application deployment tool, implemented in the " { $vocab-link "tools.deploy" } " vocablary, compiles a vocabulary down to a native executable which runs the vocabulary's " { $link POSTPONE: MAIN: } " hook. Deployed executables do not depend on Factor being installed, and do not expose any source code, and thus are suitable for delivering commercial end-user applications."
+$nl
+"Most of the time, the words in the " { $vocab-link "tools.deploy" } " vocabulary should not be used directly; instead, use " { $link "ui.tools.deploy" } "."
+$nl
 "You must explicitly specify major subsystems which are required, as well as the level of reflection support needed. This is done by modifying the deployment configuration prior to deployment."
 { $subsection "prepare-deploy" }
-"Once the necessary deployment flags have been set, the application can be deployed:"
-{ $subsection deploy }
-{ $see-also "ui.tools.deploy" } ;
+{ $subsection "tools.deploy.usage" }
+{ $subsection "tools.deploy.impl" }
+{ $subsection "tools.deploy.caveats" } ;
 
 ABOUT: "tools.deploy"
 
index 0dea093081d499607201b24d1dfd13e233f9b5b0..3bebf7236d6074c1db7ecbc62fb4af785febfebf 100644 (file)
@@ -1,10 +1,9 @@
 IN: tools.deploy.tests\r
 USING: tools.test system io.pathnames io.files io.files.info\r
-io.files.temp kernel tools.deploy.config\r
-tools.deploy.config.editor tools.deploy.backend math sequences\r
-io.launcher arrays namespaces continuations layouts accessors\r
-io.encodings.ascii urls math.parser io.directories\r
-tools.deploy.test ;\r
+io.files.temp kernel tools.deploy.config tools.deploy.config.editor\r
+tools.deploy.backend math sequences io.launcher arrays namespaces\r
+continuations layouts accessors io.encodings.ascii urls math.parser\r
+io.directories tools.deploy.test ;\r
 \r
 [ t ] [ "hello-world" shake-and-bake 500000 small-enough? ] unit-test\r
 \r
@@ -27,6 +26,8 @@ os macosx? [
     [ t ] [ "webkit-demo" shake-and-bake 500000 small-enough? ] unit-test\r
 ] when\r
 \r
+[ t ] [ "benchmark.regex-dna" shake-and-bake 900000 small-enough? ] unit-test\r
+\r
 {\r
     "tools.deploy.test.1"\r
     "tools.deploy.test.2"\r
@@ -80,32 +81,17 @@ M: quit-responder call-responder*
 \r
 [ ] [ "http://localhost/quit" add-port http-get 2drop ] unit-test\r
 \r
-[ ] [\r
-    "tools.deploy.test.6" shake-and-bake\r
-    run-temp-image\r
-] unit-test\r
-\r
-[ ] [\r
-    "tools.deploy.test.7" shake-and-bake\r
-    run-temp-image\r
-] unit-test\r
-\r
-[ ] [\r
-    "tools.deploy.test.8" shake-and-bake\r
-    run-temp-image\r
-] unit-test\r
-\r
-[ ] [\r
-    "tools.deploy.test.9" shake-and-bake\r
-    run-temp-image\r
-] unit-test\r
-\r
-[ ] [\r
-    "tools.deploy.test.10" shake-and-bake\r
-    run-temp-image\r
-] unit-test\r
-\r
-[ ] [\r
-    "tools.deploy.test.11" shake-and-bake\r
-    run-temp-image\r
-] unit-test
\ No newline at end of file
+{\r
+    "tools.deploy.test.6"\r
+    "tools.deploy.test.7"\r
+    "tools.deploy.test.8"\r
+    "tools.deploy.test.9"\r
+    "tools.deploy.test.10"\r
+    "tools.deploy.test.11"\r
+    "tools.deploy.test.12"\r
+} [\r
+    [ ] swap [\r
+        shake-and-bake\r
+        run-temp-image\r
+    ] curry unit-test\r
+] each
\ No newline at end of file
index 11e2b8957b8ce96e2ae40b806a31c34e24a404ab..f753e38fb2bf8c3a1e3355d37670d684d085278c 100755 (executable)
@@ -42,11 +42,12 @@ IN: tools.deploy.macosx
 
 : create-app-dir ( vocab bundle-name -- vm )
     [
-        nip
-        [ copy-dll ]
-        [ copy-nib ]
-        [ "Contents/Resources" append-path make-directories ]
-        tri
+        nip {
+            [ copy-dll ]
+            [ copy-nib ]
+            [ "Contents/Resources" append-path make-directories ]
+            [ "Contents/Resources" copy-theme ]
+        } cleave
     ]
     [ create-app-plist ]
     [ "Contents/MacOS/" append-path copy-vm ] 2tri
index 961d0ff26d12af0d9687ae52e864db76c756a517..7c9a38796b5de053f56b9a0a3ba4c4f8c1bd64ff 100755 (executable)
@@ -53,6 +53,10 @@ IN: tools.deploy.shaker
         run-file
     ] when ;
 
+: strip-call ( -- )
+    "Stripping stack effect checking from call( and execute(" show
+    "vocab:tools/deploy/shaker/strip-call.factor" run-file ;
+
 : strip-cocoa ( -- )
     "cocoa" vocab [
         "Stripping unused Cocoa methods" show
@@ -115,6 +119,7 @@ IN: tools.deploy.shaker
                 "inline"
                 "inlined-block"
                 "input-classes"
+                "instances"
                 "interval"
                 "intrinsics"
                 "lambda"
@@ -152,6 +157,8 @@ IN: tools.deploy.shaker
                 "specializer"
                 "step-into"
                 "step-into?"
+                ! UI needs this
+                ! "superclass"
                 "transform-n"
                 "transform-quot"
                 "tuple-dispatch-generic"
@@ -163,8 +170,6 @@ IN: tools.deploy.shaker
         
         strip-prettyprint? [
             {
-                "break-before"
-                "break-after"
                 "delimiter"
                 "flushable"
                 "foldable"
@@ -199,7 +204,8 @@ IN: tools.deploy.shaker
     ] when ;
 
 : strip-vocab-globals ( except names -- words )
-    [ child-vocabs [ words ] map concat ] map concat swap diff ;
+    [ child-vocabs [ words ] map concat ] map concat
+    swap [ first2 lookup ] map sift diff ;
 
 : stripped-globals ( -- seq )
     [
@@ -240,7 +246,8 @@ IN: tools.deploy.shaker
         strip-dictionary? [
             "libraries" "alien" lookup ,
 
-            { } { "cpu" "compiler" } strip-vocab-globals %
+            { { "yield-hook" "compiler.utilities" } }
+            { "cpu" "compiler" } strip-vocab-globals %
 
             {
                 gensym
@@ -256,9 +263,7 @@ IN: tools.deploy.shaker
                 command-line:main-vocab-hook
                 compiled-crossref
                 compiled-generic-crossref
-                recompile-hook
-                update-tuples-hook
-                remake-generics-hook
+                compiler-impl
                 definition-observers
                 definitions:crossref
                 interactive-vocabs
@@ -270,7 +275,6 @@ IN: tools.deploy.shaker
                 lexer-factory
                 print-use-hook
                 root-cache
-                vocab-roots
                 vocabs:dictionary
                 vocabs:load-vocab-hook
                 word
@@ -339,7 +343,8 @@ IN: tools.deploy.shaker
     ] 2each ;
 
 : compress-quotations ( -- )
-    [ quotation? ] [ remain-compiled ] "quotations" compress ;
+    [ quotation? ] [ remain-compiled ] "quotations" compress
+    [ quotation? ] instances [ f >>cached-effect f >>cache-counter drop ] each ;
 
 : compress-strings ( -- )
     [ string? ] [ ] "strings" compress ;
@@ -399,6 +404,7 @@ SYMBOL: deploy-vocab
     init-stripper
     strip-default-methods
     strip-libc
+    strip-call
     strip-cocoa
     strip-debugger
     compute-next-methods
diff --git a/basis/tools/deploy/shaker/strip-call.factor b/basis/tools/deploy/shaker/strip-call.factor
new file mode 100644 (file)
index 0000000..d0593b6
--- /dev/null
@@ -0,0 +1,10 @@
+! Copyright (C) 2009 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+IN: tools.deploy.shaker.call
+
+IN: combinators
+USE: combinators.private
+
+: call-effect ( word effect -- ) call-effect-unsafe ; inline
+
+: execute-effect ( word effect -- ) execute-effect-unsafe ; inline
\ No newline at end of file
diff --git a/basis/tools/deploy/test/12/12.factor b/basis/tools/deploy/test/12/12.factor
new file mode 100644 (file)
index 0000000..3bc2af3
--- /dev/null
@@ -0,0 +1,12 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: math.parser io math ;
+IN: tools.deploy.test.12
+
+: execute-test ( a b w -- c ) execute( a b -- c ) ;
+
+: call-test ( a b q -- c ) call( a b -- c ) ;
+
+: foo ( -- ) 1 2 \ + execute-test 4 [ * ] call-test number>string print ;
+
+MAIN: foo
\ No newline at end of file
diff --git a/basis/tools/deploy/test/12/authors.txt b/basis/tools/deploy/test/12/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/tools/deploy/test/12/deploy.factor b/basis/tools/deploy/test/12/deploy.factor
new file mode 100644 (file)
index 0000000..638e1ca
--- /dev/null
@@ -0,0 +1,15 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-c-types? f }
+    { deploy-reflection 1 }
+    { "stop-after-last-window?" t }
+    { deploy-word-props? f }
+    { deploy-math? f }
+    { deploy-unicode? f }
+    { deploy-io 2 }
+    { deploy-ui? f }
+    { deploy-name "tools.deploy.test.12" }
+    { deploy-compiler? f }
+    { deploy-word-defs? f }
+    { deploy-threads? f }
+}
diff --git a/basis/tools/deploy/test/13/13.factor b/basis/tools/deploy/test/13/13.factor
new file mode 100644 (file)
index 0000000..af7cb4e
--- /dev/null
@@ -0,0 +1,10 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: regexp kernel io ;
+IN: tools.deploy.test.13
+
+: regexp-test ( a -- b ) <regexp> "xyz" swap matches? ;
+
+: main ( -- ) "x.z" regexp-test "X" "Y" ? print ;
+
+MAIN: main
\ No newline at end of file
diff --git a/basis/tools/deploy/test/13/authors.txt b/basis/tools/deploy/test/13/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/tools/deploy/test/13/deploy.factor b/basis/tools/deploy/test/13/deploy.factor
new file mode 100644 (file)
index 0000000..9513192
--- /dev/null
@@ -0,0 +1,15 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-threads? t }
+    { deploy-compiler? t }
+    { deploy-math? t }
+    { deploy-io 2 }
+    { "stop-after-last-window?" t }
+    { deploy-c-types? f }
+    { deploy-name "tools.deploy.test.13" }
+    { deploy-word-props? f }
+    { deploy-unicode? f }
+    { deploy-word-defs? f }
+    { deploy-reflection 4 }
+    { deploy-ui? f }
+}
index bfa096ad2fb674ace677073a420d75b4f53a3ae0..f21f4ac363a83c3efc9a25f4a332e872ee8b2ab7 100755 (executable)
@@ -9,11 +9,6 @@ IN: tools.deploy.windows
 : copy-dll ( bundle-name -- )
     "resource:factor.dll" swap copy-file-into ;
 
-: copy-pango ( bundle-name -- )
-    "resource:build-support/dlls.txt" ascii file-lines
-    [ "resource:" prepend-path ] map
-    swap copy-files-into ;
-
 :: copy-vm ( executable bundle-name extension -- vm )
     vm "." split1-last drop extension append
     bundle-name executable ".exe" append append-path
@@ -22,9 +17,7 @@ IN: tools.deploy.windows
 : create-exe-dir ( vocab bundle-name -- vm )
     dup copy-dll
     deploy-ui? get [
-        [ copy-pango ]
-        [ "" copy-theme ]
-        [ ".exe" copy-vm ] tri
+        [ "" copy-theme ] [ ".exe" copy-vm ] bi
     ] [ ".com" copy-vm ] if ;
 
 M: winnt deploy*
index 96f5a043788c83f6113bfeddbb347c513aabf709..49cfb054a13e03b44240c9379edc0939025f64e7 100644 (file)
@@ -3,4 +3,4 @@ USING: math classes.tuple prettyprint.custom
 tools.disassembler tools.test strings ;\r
 \r
 [ ] [ \ + disassemble ] unit-test\r
-[ ] [ { string pprint* } disassemble ] unit-test\r
+[ ] [ M\ string pprint* disassemble ] unit-test\r
old mode 100644 (file)
new mode 100755 (executable)
index 2a717c0..744318a
@@ -16,9 +16,7 @@ M: pair disassemble first2 disassemble* [ tabs>spaces print ] each ;
 
 M: word disassemble word-xt 2array disassemble ;
 
-M: method-spec disassemble first2 method disassemble ;
-
-cpu x86? os unix? and
+cpu x86?
 "tools.disassembler.udis"
 "tools.disassembler.gdb" ?
 require
old mode 100644 (file)
new mode 100755 (executable)
index 8f99e4f..51e399c
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: tools.disassembler namespaces combinators
 alien alien.syntax alien.c-types lexer parser kernel
-sequences layouts math math.order
+sequences layouts math math.order alien.libraries
 math.parser system make fry arrays ;
 IN: tools.disassembler.udis
 
@@ -30,9 +30,9 @@ CONSTANT: UD_VENDOR_AMD   0
 CONSTANT: UD_VENDOR_INTEL 1
 
 FUNCTION: void ud_init ( ud* u ) ;
-FUNCTION: void ud_set_mode ( ud* u, uint8_t mode ) ;
+FUNCTION: void ud_set_mode ( ud* u, uchar mode ) ;
 FUNCTION: void ud_set_pc ( ud* u, ulonglong pc ) ;
-FUNCTION: void ud_set_input_buffer ( ud* u, uint8_t* offset, size_t size ) ;
+FUNCTION: void ud_set_input_buffer ( ud* u, uchar* offset, size_t size ) ;
 FUNCTION: void ud_set_vendor ( ud* u, uint vendor ) ;
 FUNCTION: void ud_set_syntax ( ud* u, void* syntax ) ;
 FUNCTION: void ud_input_skip ( ud* u, size_t size ) ;
index 63b55729fbd0454698431af4a43c9ec362c19d32..666e05108811a08b74d720339bb6d398c099e63c 100644 (file)
@@ -16,10 +16,11 @@ IN: tools.hexdump
     16 * >hex 8 CHAR: 0 pad-head write "h: " write ;
 
 : >hex-digit ( digit -- str )
-    >hex 2 CHAR: 0 pad-head " " append ;
+    >hex 2 CHAR: 0 pad-head ;
 
 : >hex-digits ( bytes -- str )
-    [ >hex-digit ] { } map-as concat 48 CHAR: \s pad-tail ;
+    [ >hex-digit " " append ] { } map-as concat
+    48 CHAR: \s pad-tail ;
 
 : >ascii ( bytes -- str )
     [ [ printable? ] keep CHAR: . ? ] "" map-as ;
index 3924cc7b8351c7e0e9adffdf9037e01416914f7d..0bd366372998d76a414663ee9d120137c6a2a4cc 100644 (file)
@@ -25,7 +25,7 @@ words ;
 
 : indirect-test ( callback -- ) "void" { } "cdecl" alien-indirect ;
 
-: foobar ;
+: foobar ( -- ) ;
 
 [
     [ ] [ callback-test indirect-test ] unit-test
@@ -34,9 +34,9 @@ words ;
 
 [ 1 ] [ \ foobar counter>> ] unit-test
 
-: fooblah { } [ ] each ;
+: fooblah ( -- ) { } [ ] like call ;
 
-: foobaz fooblah fooblah ;
+: foobaz ( -- ) fooblah fooblah ;
 
 [ foobaz ] profile
 
index 4d1240ad3851044c6d3da7db05577cb79709f197..621933bfa8210953190498bc6c2d540a4f0d4ce3 100644 (file)
@@ -26,7 +26,7 @@ HELP: scaffold-undocumented
 HELP: scaffold-vocab
 { $values
      { "vocab-root" "a vocabulary root string" } { "string" string } }
-{ $description "Creates a directory in the given root for a new vocabulary and adds a main .factor file, a tests file, and an authors.txt file." } ;
+{ $description "Creates a directory in the given root for a new vocabulary and adds a main .factor file and an authors.txt file." } ;
 
 HELP: scaffold-emacs
 { $description "Touches the .emacs file in your home directory and provides a clickable link to open it in an editor." } ;
diff --git a/basis/tools/scaffold/scaffold-tests.factor b/basis/tools/scaffold/scaffold-tests.factor
new file mode 100644 (file)
index 0000000..4c8698c
--- /dev/null
@@ -0,0 +1,21 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test tools.scaffold unicode.case kernel
+multiline tools.scaffold.private io.streams.string ;
+IN: tools.scaffold.tests
+
+: undocumented-word ( obj1 obj2 -- obj3 obj4 )
+    [ >lower ] [ >upper ] bi* ;
+
+[
+<" HELP: undocumented-word
+{ $values
+    { "obj1" object } { "obj2" object }
+    { "obj3" object } { "obj4" object }
+}
+{ $description "" } ;
+">
+]
+[
+    [ \ undocumented-word (help.) ] with-string-writer
+] unit-test
index 16729394bfc9416fb457148ba07300979901f929..73e896d5ffbc2c63eea12ddd23f9770bb19f6952 100755 (executable)
@@ -5,7 +5,7 @@ io.encodings.utf8 hashtables kernel namespaces sequences
 vocabs.loader io combinators calendar accessors math.parser
 io.streams.string ui.tools.operations quotations strings arrays
 prettyprint words vocabs sorting sets classes math alien urls
-splitting ascii combinators.short-circuit ;
+splitting ascii combinators.short-circuit alarms words.symbol ;
 IN: tools.scaffold
 
 SYMBOL: developer-name
@@ -116,6 +116,7 @@ ERROR: no-vocab vocab ;
         { "ch" "a character" }
         { "word" word }
         { "array" array }
+        { "alarm" alarm }
         { "duration" duration }
         { "path" "a pathname string" }
         { "vocab" "a vocabulary specifier" }
@@ -133,8 +134,8 @@ ERROR: no-vocab vocab ;
     vocabulary>> using get [ conjoin ] [ drop ] if* ;
 
 : ($values.) ( array -- )
-    [
-        " { " write
+    [ bl ] [
+        "{ " write
         dup array? [ first ] when
         dup lookup-type [
             [ unparse write bl ]
@@ -144,7 +145,7 @@ ERROR: no-vocab vocab ;
             null add-using
         ] if
         " }" write
-    ] each ;
+    ] interleave ;
 
 : 4bl ( -- )
     "    " write ; inline
@@ -162,15 +163,26 @@ ERROR: no-vocab vocab ;
         ] if
     ] when* ;
 
+: symbol-description. ( word -- )
+    drop
+    "{ $var-description \"\" } ;" print ;
+
 : $description. ( word -- )
     drop
     "{ $description \"\" } ;" print ;
 
+: docs-body. ( word/symbol -- )
+    dup symbol? [
+        symbol-description.
+    ] [
+        [ $values. ] [ $description. ] bi
+    ] if ;
+
 : docs-header. ( word -- )
     "HELP: " write name>> print ;
 
 : (help.) ( word -- )
-    [ docs-header. ] [ $values. ] [ $description. ] tri ;
+    [ docs-header. ] [ docs-body. ] bi ;
 
 : interesting-words ( vocab -- array )
     words
index 704a7f1bd5430d828ff504b1228f48ad382bf259..c6dea08d181556e9051b3dd3a310daa763b6b681 100644 (file)
@@ -23,7 +23,7 @@ SYMBOL: this-test
         [ this-test get failure ] recover
     ] [
         call
-    ] if ;
+    ] if ; inline
 
 : unit-test ( output input -- )
     [ 2array ] 2keep '[
diff --git a/basis/tools/test/ui/authors.txt b/basis/tools/test/ui/authors.txt
deleted file mode 100755 (executable)
index 1901f27..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Slava Pestov
diff --git a/basis/tools/test/ui/ui.factor b/basis/tools/test/ui/ui.factor
deleted file mode 100644 (file)
index c37e779..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-USING: dlists ui.gadgets ui.gadgets.private
-kernel ui namespaces io.streams.string io ;
-IN: tools.test.ui
-
-! We can't print to output-stream here because that might be a pane
-! stream, and our graft-queue rebinding here would be captured
-! by code adding children to the pane...
-: with-grafted-gadget ( gadget quot -- )
-    [
-        <dlist> \ graft-queue [
-            over
-            graft notify-queued
-            dip
-            ungraft notify-queued
-        ] with-variable
-    ] with-string-writer print ;
diff --git a/basis/tools/vocabs/browser/authors.txt b/basis/tools/vocabs/browser/authors.txt
deleted file mode 100755 (executable)
index e1907c6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Slava Pestov
-Eduardo Cavazos
diff --git a/basis/tools/vocabs/browser/browser-docs.factor b/basis/tools/vocabs/browser/browser-docs.factor
deleted file mode 100644 (file)
index 723c4ac..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-USING: help.markup help.syntax io strings ;
-IN: tools.vocabs.browser
-
-ARTICLE: "vocab-tags" "Vocabulary tags"
-{ $all-tags } ;
-
-ARTICLE: "vocab-authors" "Vocabulary authors"
-{ $all-authors } ;
-
-ARTICLE: "vocab-index" "Vocabulary index"
-{ $subsection "vocab-tags" }
-{ $subsection "vocab-authors" }
-{ $vocab "" } ;
-
-HELP: words.
-{ $values { "vocab" "a vocabulary name" } }
-{ $description "Printings a listing of all the words in a vocabulary, categorized by type." } ;
diff --git a/basis/tools/vocabs/browser/browser-tests.factor b/basis/tools/vocabs/browser/browser-tests.factor
deleted file mode 100644 (file)
index 385d1b2..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-IN: tools.vocabs.browser.tests
-USING: tools.vocabs.browser tools.test help.markup help vocabs ;
-
-[ ] [ { $vocab "scratchpad" } print-content ] unit-test
-[ ] [ "classes" vocab print-topic ] unit-test
\ No newline at end of file
diff --git a/basis/tools/vocabs/browser/browser.factor b/basis/tools/vocabs/browser/browser.factor
deleted file mode 100644 (file)
index 70588d5..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs classes classes.builtin
-classes.intersection classes.mixin classes.predicate
-classes.singleton classes.tuple classes.union combinators
-definitions effects fry generic help help.markup help.stylesheet
-help.topics io io.files io.pathnames io.styles kernel macros
-make namespaces prettyprint sequences sets sorting summary
-tools.vocabs vocabs vocabs.loader words words.symbol
-combinators.smart definitions.icons ;
-IN: tools.vocabs.browser
-
-: <$pretty-link> ( definition -- element )
-    [
-        [ definition-icon 1array \ $image prefix ]
-        [ drop " " ]
-        [ 1array \ $definition-link prefix ]
-        tri
-    ] output>array ;
-
-: vocab-row ( vocab -- row )
-    [ <$pretty-link> ] [ vocab-summary ] bi 2array ;
-
-: vocab-headings ( -- headings )
-    {
-        { $strong "Vocabulary" }
-        { $strong "Summary" }
-    } ;
-
-: root-heading ( root -- )
-    [ "Children from " prepend ] [ "Children" ] if*
-    $heading ;
-
-: $vocabs ( seq -- )
-    [ vocab-row ] map vocab-headings prefix $table ;
-
-: $vocab-roots ( assoc -- )
-    [
-        [ drop ] [ [ root-heading ] [ $vocabs ] bi* ] if-empty
-    ] assoc-each ;
-
-TUPLE: vocab-tag name ;
-
-INSTANCE: vocab-tag topic
-
-C: <vocab-tag> vocab-tag
-
-: $tags ( seq -- ) [ <vocab-tag> ] map $links ;
-
-TUPLE: vocab-author name ;
-
-INSTANCE: vocab-author topic
-
-C: <vocab-author> vocab-author
-
-: $authors ( seq -- ) [ <vocab-author> ] map $links ;
-
-: describe-help ( vocab -- )
-    [
-        dup vocab-help
-        [ "Documentation" $heading ($link) ]
-        [ "Summary" $heading vocab-summary print-element ]
-        ?if
-    ] unless-empty ;
-
-: describe-children ( vocab -- )
-    vocab-name all-child-vocabs $vocab-roots ;
-
-: files. ( seq -- )
-    snippet-style get [
-        code-style get [
-            [ nl ] [ [ string>> ] keep write-object ] interleave
-        ] with-nesting
-    ] with-style ;
-
-: describe-files ( vocab -- )
-    vocab-files [ <pathname> ] map [
-        "Files" $heading
-        [
-            files.
-        ] ($block)
-    ] unless-empty ;
-
-: describe-tuple-classes ( classes -- )
-    [
-        "Tuple classes" $subheading
-        [
-            [ <$pretty-link> ]
-            [ superclass <$pretty-link> ]
-            [ "slots" word-prop [ name>> ] map " " join <$snippet> ]
-            tri 3array
-        ] map
-        { { $strong "Class" } { $strong "Superclass" } { $strong "Slots" } } prefix
-        $table
-    ] unless-empty ;
-
-: describe-predicate-classes ( classes -- )
-    [
-        "Predicate classes" $subheading
-        [
-            [ <$pretty-link> ]
-            [ superclass <$pretty-link> ]
-            bi 2array
-        ] map
-        { { $strong "Class" } { $strong "Superclass" } } prefix
-        $table
-    ] unless-empty ;
-
-: (describe-classes) ( classes heading -- )
-    '[
-        _ $subheading
-        [ <$pretty-link> 1array ] map $table
-    ] unless-empty ;
-
-: describe-builtin-classes ( classes -- )
-    "Builtin classes" (describe-classes) ;
-
-: describe-singleton-classes ( classes -- )
-    "Singleton classes" (describe-classes) ;
-
-: describe-mixin-classes ( classes -- )
-    "Mixin classes" (describe-classes) ;
-
-: describe-union-classes ( classes -- )
-    "Union classes" (describe-classes) ;
-
-: describe-intersection-classes ( classes -- )
-    "Intersection classes" (describe-classes) ;
-
-: describe-classes ( classes -- )
-    [ builtin-class? ] partition
-    [ tuple-class? ] partition
-    [ singleton-class? ] partition
-    [ predicate-class? ] partition
-    [ mixin-class? ] partition
-    [ union-class? ] partition
-    [ intersection-class? ] filter
-    {
-        [ describe-builtin-classes ]
-        [ describe-tuple-classes ]
-        [ describe-singleton-classes ]
-        [ describe-predicate-classes ]
-        [ describe-mixin-classes ]
-        [ describe-union-classes ]
-        [ describe-intersection-classes ]
-    } spread ;
-
-: word-syntax ( word -- string/f )
-    \ $syntax swap word-help elements dup length 1 =
-    [ first second ] [ drop f ] if ;
-
-: describe-parsing ( words -- )
-    [
-        "Parsing words" $subheading
-        [
-            [ <$pretty-link> ]
-            [ word-syntax dup [ <$snippet> ] when ]
-            bi 2array
-        ] map
-        { { $strong "Word" } { $strong "Syntax" } } prefix
-        $table
-    ] unless-empty ;
-
-: word-row ( word -- element )
-    [ <$pretty-link> ]
-    [ stack-effect dup [ effect>string <$snippet> ] when ]
-    bi 2array ;
-
-: word-headings ( -- element )
-    { { $strong "Word" } { $strong "Stack effect" } } ;
-
-: words-table ( words -- )
-    [ word-row ] map word-headings prefix $table ;
-
-: (describe-words) ( words heading -- )
-    '[ _ $subheading words-table ] unless-empty ;
-
-: describe-generics ( words -- )
-    "Generic words" (describe-words) ;
-
-: describe-macros ( words -- )
-    "Macro words" (describe-words) ;
-
-: describe-primitives ( words -- )
-    "Primitives" (describe-words) ;
-
-: describe-compounds ( words -- )
-    "Ordinary words" (describe-words) ;
-
-: describe-predicates ( words -- )
-    "Class predicate words" (describe-words) ;
-
-: describe-symbols ( words -- )
-    [
-        "Symbol words" $subheading
-        [ <$pretty-link> 1array ] map $table
-    ] unless-empty ;
-
-: $words ( words -- )
-    [
-        "Words" $heading
-
-        natural-sort
-        [ [ class? ] filter describe-classes ]
-        [
-            [ [ class? ] [ symbol? ] bi and not ] filter
-            [ parsing-word? ] partition
-            [ generic? ] partition
-            [ macro? ] partition
-            [ symbol? ] partition
-            [ primitive? ] partition
-            [ predicate? ] partition swap
-            {
-                [ describe-parsing ]
-                [ describe-generics ]
-                [ describe-macros ]
-                [ describe-symbols ]
-                [ describe-primitives ]
-                [ describe-compounds ]
-                [ describe-predicates ]
-            } spread
-        ] bi
-    ] unless-empty ;
-
-: words. ( vocab -- )
-    last-element off
-    [ require ] [ words $words ] bi ;
-
-: describe-metadata ( vocab -- )
-    [
-        [ vocab-tags [ "Tags:" swap \ $tags prefix 2array , ] unless-empty ]
-        [ vocab-authors [ "Authors:" swap \ $authors prefix 2array , ] unless-empty ]
-        bi
-    ] { } make
-    [ "Meta-data" $heading $table ] unless-empty ;
-
-: $vocab ( element -- )
-    first {
-        [ describe-help ]
-        [ describe-metadata ]
-        [ words $words ]
-        [ describe-files ]
-        [ describe-children ]
-    } cleave ;
-
-: keyed-vocabs ( str quot -- seq )
-    all-vocabs [
-        swap [
-            [ [ 2dup ] dip swap call member? ] filter
-        ] dip swap
-    ] assoc-map 2nip ; inline
-
-: tagged ( tag -- assoc )
-    [ vocab-tags ] keyed-vocabs ;
-
-: authored ( author -- assoc )
-    [ vocab-authors ] keyed-vocabs ;
-
-: $tagged-vocabs ( element -- )
-    first tagged $vocab-roots ;
-
-: $authored-vocabs ( element -- )
-    first authored $vocab-roots ;
-
-: $all-tags ( element -- )
-    drop "Tags" $heading all-tags $tags ;
-
-: $all-authors ( element -- )
-    drop "Authors" $heading all-authors $authors ;
-
-INSTANCE: vocab topic
-
-INSTANCE: vocab-link topic
-
-M: vocab-spec article-title vocab-name " vocabulary" append ;
-
-M: vocab-spec article-name vocab-name ;
-
-M: vocab-spec article-content
-    vocab-name \ $vocab swap 2array ;
-
-M: vocab-spec article-parent drop "vocab-index" ;
-
-M: vocab-tag >link ;
-
-M: vocab-tag article-title
-    name>> "Vocabularies tagged “" "”" surround ;
-
-M: vocab-tag article-name name>> ;
-
-M: vocab-tag article-content
-    \ $tagged-vocabs swap name>> 2array ;
-
-M: vocab-tag article-parent drop "vocab-tags" ;
-
-M: vocab-tag summary article-title ;
-
-M: vocab-author >link ;
-
-M: vocab-author article-title
-    name>> "Vocabularies by " prepend ;
-
-M: vocab-author article-name name>> ;
-
-M: vocab-author article-content
-    \ $authored-vocabs swap name>> 2array ;
-
-M: vocab-author article-parent drop "vocab-authors" ;
-
-M: vocab-author summary article-title ;
diff --git a/basis/tools/vocabs/browser/summary.txt b/basis/tools/vocabs/browser/summary.txt
deleted file mode 100644 (file)
index 28b4850..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Browsing vocabularies
diff --git a/basis/tools/vocabs/browser/tags.txt b/basis/tools/vocabs/browser/tags.txt
deleted file mode 100644 (file)
index ef1aab0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tools
index f8026765830160e95a7d10b151bac86c2d4e6da2..3a5877c2861c5095f91cec26ff457612a4e2afef 100644 (file)
@@ -36,7 +36,7 @@ IN: tools.walker.tests
     [ 2 2 fixnum+ ] test-walker
 ] unit-test
 
-: foo 2 2 fixnum+ ;
+: foo ( -- x ) 2 2 fixnum+ ;
 
 [ { 8 } ] [
     [ foo 4 fixnum+ ] test-walker
index f0d9a084b13677494a1df9859cbf6c5f9f5eb0df..b4ace6b770aef27a1eea84532c21c05121a0977c 100644 (file)
@@ -139,7 +139,6 @@ SYMBOL: +stopped+
     { dip [ (step-into-dip) ] }
     { 2dip [ (step-into-2dip) ] }
     { 3dip [ (step-into-3dip) ] }
-    { (throw) [ drop (step-into-quot) ] }
     { execute [ (step-into-execute) ] }
     { if [ (step-into-if) ] }
     { dispatch [ (step-into-dispatch) ] }
index ce535f335aa9e1eeb1b2b4ab67c6a9e67e3248f3..daac3c96c75035122abb8f9cb0b291f873c08484 100644 (file)
@@ -17,7 +17,8 @@ M: bad-tr summary
     [ [ ascii? ] all? ] both? [ bad-tr ] unless ;
 
 : compute-tr ( quot from to -- mapping )
-    zip [ 128 ] 2dip '[ [ @ _ at ] keep or ] B{ } map-as ; inline
+    [ 128 ] 3dip zip
+    '[ [ _ call( x -- y ) _ at ] keep or ] B{ } map-as ; inline
 
 : tr-hints ( word -- )
     { { byte-array } { string } } "specializer" set-word-prop ;
@@ -39,10 +40,9 @@ M: bad-tr summary
 
 PRIVATE>
 
-: TR:
+SYNTAX: TR:
     scan parse-definition
     unclip-last [ unclip-last ] dip compute-tr
     [ check-tr ]
     [ [ create-tr ] dip define-tr ]
     [ [ "-fast" append create-tr ] dip define-fast-tr ] 2tri ;
-    parsing
index 76fbc7286b0e4c62081162797edcb909285bfda4..9c844d366386873b725857a14bcb5734b363af58 100755 (executable)
@@ -1,6 +1,6 @@
-! Copyright (C) 2006, 2007 Slava Pestov.
+! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces opengl opengl.gl ;
+USING: kernel namespaces opengl opengl.gl fry ;
 IN: ui.backend
 
 SYMBOL: ui-backend
@@ -28,7 +28,7 @@ GENERIC: flush-gl-context ( handle -- )
 HOOK: offscreen-pixels ui-backend ( world -- alien w h )
 
 : with-gl-context ( handle quot -- )
-    swap [ select-gl-context call ] keep
-    glFlush flush-gl-context gl-error ; inline
+    '[ select-gl-context @ ]
+    [ flush-gl-context gl-error ] bi ; inline
 
 HOOK: (with-ui) ui-backend ( quot -- )
\ No newline at end of file
index 9888fc4e77de08467813b2a05a8bb77f8270748c..362305c8f70a4a32cdcf793babfaadd934bfe883 100755 (executable)
@@ -39,13 +39,16 @@ M: pasteboard set-clipboard-contents
     [ 0 0 ] dip dim>> first2 <CGRect> ;
 
 : auto-position ( window loc -- )
+    #! Note: if this is the initial window, the length of the windows
+    #! vector should be 1, since (open-window) calls auto-position
+    #! after register-window.
     dup { 0 0 } = [
         drop
-        windows get [ -> center ] [
-            peek second window-loc>>
+        windows get length 1 <= [ -> center ] [
+            windows get peek second window-loc>>
             dupd first2 <CGPoint> -> cascadeTopLeftFromPoint:
             -> setFrameTopLeftPoint:
-        ] if-empty
+        ] if
     ] [ first2 <CGPoint> -> setFrameTopLeftPoint: ] if ;
 
 M: cocoa-ui-backend set-title ( string world -- )
@@ -70,8 +73,8 @@ M:: cocoa-ui-backend (open-window) ( world -- )
     world dim>> <FactorView> :> view
     view world world>NSRect <ViewWindow> :> window
     view -> release
-    window world window-loc>> auto-position
     world view register-window
+    window world window-loc>> auto-position
     world window save-position
     window install-window-delegate
     view window <window-handle> world (>>handle)
@@ -152,7 +155,7 @@ M: cocoa-ui-backend (with-ui)
     "UI" assert.app [
         [
             init-clipboard
-            cocoa-init-hook get call
+            cocoa-init-hook get call( -- )
             start-ui
             f io-thread-running? set-global
             init-thread-timer
index b59848260da9f172ab461e73c91addb96d94ef40..602c9bec73c188e2a6d0656870dcd11c8534ac4c 100644 (file)
@@ -336,7 +336,7 @@ CLASS: {
 
 ! Initialization
 { "updateFactorGadgetSize:" "void" { "id" "SEL" "id" }
-    [ 2drop dup view-dim swap window (>>dim) yield ]
+    [ 2drop [ window ] [ view-dim ] bi >>dim drop yield ]
 }
 
 { "doCommandBySelector:" "void" { "id" "SEL" "SEL" }
index 54d9ed456a1d082128580b0152de9f974eb796de..e405efb540d16f21ee39849e804d2c7c2a6690d8 100755 (executable)
@@ -1,16 +1,16 @@
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! Portions copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types alien.strings arrays assocs ui
-ui.private ui.gadgets ui.gadgets.private ui.backend
-ui.clipboards ui.gadgets.worlds ui.gestures ui.event-loop io
-kernel math math.vectors namespaces make sequences strings
-vectors words windows.kernel32 windows.gdi32 windows.user32
-windows.opengl32 windows.messages windows.types windows.nt
-windows threads libc combinators fry combinators.short-circuit
-continuations command-line shuffle opengl ui.render ascii
-math.bitwise locals accessors math.rectangles math.order ascii
-calendar io.encodings.utf16n ;
+USING: alien alien.c-types alien.strings arrays assocs ui ui.private
+ui.gadgets ui.gadgets.private ui.backend ui.clipboards
+ui.gadgets.worlds ui.gestures ui.event-loop io kernel math
+math.vectors namespaces make sequences strings vectors words
+windows.kernel32 windows.gdi32 windows.user32 windows.opengl32
+windows.messages windows.types windows.offscreen windows.nt windows
+threads libc combinators fry combinators.short-circuit continuations
+command-line shuffle opengl ui.render ascii math.bitwise locals
+accessors math.rectangles math.order ascii calendar
+io.encodings.utf16n ;
 IN: ui.backend.windows
 
 SINGLETON: windows-ui-backend
@@ -354,7 +354,7 @@ H{ } clone wm-handlers set-global
 
 : add-wm-handler ( quot wm -- )
     dup array?
-    [ [ execute add-wm-handler ] with each ]
+    [ [ execute( -- wm ) add-wm-handler ] with each ]
     [ wm-handlers get-global set-at ] if ;
 
 [ handle-wm-close 0                  ] WM_CLOSE add-wm-handler
@@ -433,12 +433,7 @@ M: windows-ui-backend do-events
     style 0 ex-style AdjustWindowRectEx win32-error=0/f ;
 
 : make-RECT ( world -- RECT )
-    [ window-loc>> dup ] [ dim>> ] bi v+
-    "RECT" <c-object>
-    over first over set-RECT-right
-    swap second over set-RECT-bottom
-    over first over set-RECT-left
-    swap second over set-RECT-top ;
+    [ window-loc>> ] [ dim>> ] bi <RECT> ;
 
 : default-position-RECT ( RECT -- )
     dup get-RECT-dimensions [ 2drop ] 2dip
@@ -501,35 +496,12 @@ M: windows-ui-backend (open-window) ( world -- )
     hWnd>> show-window ;
 
 M: win-base select-gl-context ( handle -- )
-    [ hDC>> ] keep hRC>> wglMakeCurrent win32-error=0/f
+    [ hDC>> ] [ hRC>> ] bi wglMakeCurrent win32-error=0/f
     GdiFlush drop ;
 
 M: win-base flush-gl-context ( handle -- )
     hDC>> SwapBuffers win32-error=0/f ;
 
-: (bitmap-info) ( dim -- BITMAPINFO )
-    "BITMAPINFO" <c-object> [
-        BITMAPINFO-bmiHeader {
-            [ nip "BITMAPINFOHEADER" heap-size swap set-BITMAPINFOHEADER-biSize ]
-            [ [ first ] dip set-BITMAPINFOHEADER-biWidth ]
-            [ [ second ] dip set-BITMAPINFOHEADER-biHeight ]
-            [ nip 1 swap set-BITMAPINFOHEADER-biPlanes ]
-            [ nip 32 swap set-BITMAPINFOHEADER-biBitCount ]
-            [ nip BI_RGB swap set-BITMAPINFOHEADER-biCompression ]
-            [ [ first2 * 4 * ] dip set-BITMAPINFOHEADER-biSizeImage ]
-            [ nip 72 swap set-BITMAPINFOHEADER-biXPelsPerMeter ]
-            [ nip 72 swap set-BITMAPINFOHEADER-biYPelsPerMeter ]
-            [ nip 0 swap set-BITMAPINFOHEADER-biClrUsed ]
-            [ nip 0 swap set-BITMAPINFOHEADER-biClrImportant ]
-        } 2cleave
-    ] keep ;
-
-: make-offscreen-dc-and-bitmap ( dim -- hDC hBitmap bits )
-    f CreateCompatibleDC
-    dup rot (bitmap-info) DIB_RGB_COLORS f <void*>
-    [ f 0 CreateDIBSection ] keep *void*
-    [ 2dup SelectObject drop ] dip ;
-
 : setup-offscreen-gl ( dim -- hDC hRC hBitmap bits )
     make-offscreen-dc-and-bitmap [
         [ dup offscreen-pfd-dwFlags setup-pixel-format ]
@@ -548,13 +520,12 @@ M: windows-ui-backend (close-offscreen-buffer) ( handle -- )
 ! each pixel; it's left as zero
 
 : (make-opaque) ( byte-array -- byte-array' )
-    [ length 4 / ]
+    [ length 4 /i ]
     [ '[ 255 swap 4 * 3 + _ set-nth ] each ]
     [ ] tri ;
 
 : (opaque-pixels) ( world -- pixels )
-    [ handle>> bits>> ] [ dim>> first2 * 4 * ] bi
-    memory>byte-array (make-opaque) ;
+    [ handle>> bits>> ] [ dim>> ] bi bitmap>byte-array (make-opaque) ;
 
 M: windows-ui-backend offscreen-pixels ( world -- alien w h )
     [ (opaque-pixels) ] [ dim>> first2 ] bi ;
index 422efbd188c66236757173f0227c5abedaf202bb..5a2a8974e7b2a3b76217ecb2ccec762b55fe1590 100755 (executable)
@@ -224,6 +224,10 @@ M: x-clipboard paste-clipboard
     [ XA_NET_WM_NAME XA_UTF8_STRING 8 PropModeReplace ] dip
     utf8 encode dup length XChangeProperty drop ;
 
+: set-class ( dpy window -- )
+    XA_WM_CLASS XA_STRING 8 PropModeReplace "Factor"
+    utf8 encode dup length XChangeProperty drop ;
+
 M: x11-ui-backend set-title ( string world -- )
     handle>> window>> swap
     [ dpy get ] 2dip [ set-title-old ] [ set-title-new ] 3bi ;
@@ -242,11 +246,15 @@ M: x11-ui-backend set-fullscreen* ( ? world -- )
 
 M: x11-ui-backend (open-window) ( world -- )
     dup gadget-window
-    handle>> window>> dup set-closable map-window ;
+    handle>> window>>
+    [ set-closable ] [ dpy get swap set-class ] [ map-window ] tri ;
 
 M: x11-ui-backend raise-window* ( world -- )
     handle>> [
-        dpy get swap window>> XRaiseWindow drop
+        dpy get swap window>>
+        [ RevertToPointerRoot CurrentTime XSetInputFocus drop ]
+        [ XRaiseWindow drop ]
+        2bi
     ] when* ;
 
 M: x11-handle select-gl-context ( handle -- )
index 81a4096aab82ee4c08a2eaa4c72e7ff22bc4353b..b576f173b6fc1e5c1f785d46498d4a3c35acc770 100644 (file)
@@ -54,7 +54,7 @@ HELP: command-name
     { $example
         "USING: io ui.commands ;"
         "IN: scratchpad"
-        ": com-my-command ;"
+        ": com-my-command ( -- ) ;"
         "\\ com-my-command command-name write"
         "My Command"
     }
index d6c7c7905be1aa9b9f3191561ca455a233c767a1..28529b013bf9ca19e7da6ea57d0fea955a8d471b 100644 (file)
@@ -2,8 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions kernel sequences strings
 math assocs words generic namespaces make assocs quotations
-splitting ui.gestures unicode.case unicode.categories tr fry
-call ;
+splitting ui.gestures unicode.case unicode.categories tr fry ;
 IN: ui.commands
 
 SYMBOL: +nullary+
index 6042a398865827bfa205731702bd89d044fbb12d..a28a6aef84162b017cc9be515cd04a3c6bc57904 100644 (file)
@@ -26,7 +26,7 @@ HELP: <repeat-button>
 { $description "Creates a new " { $link button } " derived from a " { $link <border-button> } " which calls the quotation every 100 milliseconds as long as the mouse button is held down." } ;
 
 HELP: button-pen
-{ $class-description "A class implementing the " { $link draw-boundary } " and " { $link draw-interior } " gneeric words by delegating to an object in one of four slots which depend on the state of the button being drawn:"
+{ $class-description "A class implementing the " { $link draw-boundary } " and " { $link draw-interior } " generic words by delegating to an object in one of four slots which depend on the state of the button being drawn:"
     { $list
         { { $snippet "plain"    } " - the button is inactive" }
         { { $snippet "rollover" } " - the button is under the mouse" }
index 6d1706ee748fdc4552bf4455ba5f15a182ef1404..0aa12f72793dff3816c27ba9d54792144f3ae0c3 100644 (file)
@@ -5,9 +5,9 @@ IN: ui.gadgets.buttons.tests
 
 TUPLE: foo-gadget ;
 
-: com-foo-a ;
+: com-foo-a ( -- ) ;
 
-: com-foo-b ;
+: com-foo-b ( -- ) ;
 
 \ foo-gadget "toolbar" f {
     { f com-foo-a }
index ebac290f4bdfc4fc4152d29bbdc912d9bfe1ded7..0504231972e655c3b1010ee50aef53156b922042 100644 (file)
@@ -6,7 +6,7 @@ classes.tuple opengl opengl.gl math.vectors ui.commands ui.gadgets
 ui.gadgets.borders ui.gadgets.labels ui.gadgets.tracks
 ui.gadgets.packs ui.gadgets.worlds ui.gestures ui.pens ui.pens.solid
 ui.pens.image ui.pens.tile math.rectangles locals fry
-combinators.smart call ;
+combinators.smart ;
 IN: ui.gadgets.buttons
 
 TUPLE: button < border pressed? selected? quot ;
diff --git a/basis/ui/gadgets/corners/authors.txt b/basis/ui/gadgets/corners/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/ui/gadgets/corners/corners.factor b/basis/ui/gadgets/corners/corners.factor
new file mode 100644 (file)
index 0000000..7f558fc
--- /dev/null
@@ -0,0 +1,43 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel sequences namespaces ui.gadgets.frames
+ui.pens.image ui.gadgets.icons ui.gadgets.grids ;
+IN: ui.gadgets.corners
+
+CONSTANT: @center { 1 1 }
+CONSTANT: @left { 0 1 }
+CONSTANT: @right { 2 1 }
+CONSTANT: @top { 1 0 }
+CONSTANT: @bottom { 1 2 }
+
+CONSTANT: @top-left { 0 0 }
+CONSTANT: @top-right { 2 0 }
+CONSTANT: @bottom-left { 0 2 }
+CONSTANT: @bottom-right { 2 2 }
+
+SYMBOL: name
+
+: corner-image ( name -- image )
+    [ name get "-" ] dip 3append theme-image ;
+
+: corner-icon ( name -- icon )
+    corner-image <icon> ;
+
+: /-----\ ( corner -- corner )
+    "top-left" corner-icon @top-left grid-add
+    "top-middle" corner-icon @top grid-add
+    "top-right" corner-icon @top-right grid-add ;
+
+: |-----| ( gadget corner -- corner )
+    "left-edge" corner-icon @left grid-add
+    swap @center grid-add
+    "right-edge" corner-icon @right grid-add ;
+
+: \-----/ ( corner -- corner )
+    "bottom-left" corner-icon @bottom-left grid-add
+    "bottom-middle" corner-icon @bottom grid-add
+    "bottom-right" corner-icon @bottom-right grid-add ;
+
+: make-corners ( class name quot -- corners )
+    [ [ [ 3 3 ] dip new-frame { 1 1 } >>filled-cell ] dip name ] dip
+    with-variable ; inline
\ No newline at end of file
index 076c772f9754a714f0f08cc17eb3e369e8eee3da..786a97f6890bc4684f71966bba6cdde68cc6ab2a 100644 (file)
@@ -2,9 +2,23 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays colors.constants combinators kernel
 opengl sequences ui ui.baseline-alignment ui.gadgets
-ui.gadgets.buttons ui.gadgets.labels ui.pens ui.render ui.text ;
+ui.gadgets.buttons ui.gadgets.labels ui.pens ui.render ui.text
+ui.gadgets.private dlists namespaces io.streams.string io ;
 IN: ui.gadgets.debug
 
+! We can't print to output-stream here because that might be a pane
+! stream, and our graft-queue rebinding here would be captured
+! by code adding children to the pane...
+: with-grafted-gadget ( gadget quot -- )
+    [
+        <dlist> \ graft-queue set
+        <dlist> \ layout-queue set
+        over
+        graft notify-queued
+        dip
+        ungraft notify-queued
+    ] with-string-writer print ; inline
+
 TUPLE: baseline-gadget < gadget baseline cap-height ;
 
 M: baseline-gadget baseline baseline>> ;
@@ -44,7 +58,7 @@ M: metrics-paint draw-boundary
     COLOR: red gl-color
     [ dim>> ] [ >label< line-metrics ] bi
     [ [ first ] [ ascent>> ] bi* [ nip 0 swap 2array ] [ 2array ] 2bi gl-line ]
-    [ drop gl-rect ]
+    [ drop { 0 0 } swap gl-rect ]
     2bi ;
 
 : <metrics-gadget> ( text font -- gadget )
index 244e36d640753103be747f9491dfe1443708a288..0ad37cb10f8b0bfeb6ad80b90805b33c88637daf 100644 (file)
@@ -1,6 +1,6 @@
 USING: documents help.markup help.syntax ui.gadgets
 ui.gadgets.scrollers models strings ui.commands
-ui.text colors fonts ;
+ui.text colors fonts help.tips ;
 IN: ui.gadgets.editors
 
 HELP: editor
@@ -109,4 +109,8 @@ ARTICLE: "ui.gadgets.editors" "Editor gadgets"
 "Editors edit " { $emphasis "documents" } ":"
 { $subsection "documents" } ;
 
+TIP: "Editor gadgets support undo and redo; press " { $command editor "editing" com-undo } " and " { $command editor "editing" com-redo } "." ;
+
+TIP: "Learn the keyboard shortcuts used in " { $link "ui.gadgets.editors" } "." ;
+
 ABOUT: "ui.gadgets.editors"
index f8dc5b91c9f12802da50936c798f0bdad90f9f8e..bd610ba53b57d6cf0d2a829bbe35cf1d8a9c96f8 100644 (file)
@@ -1,6 +1,6 @@
 USING: accessors ui.gadgets.editors tools.test kernel io
 io.streams.plain definitions namespaces ui.gadgets
-ui.gadgets.grids prettyprint documents ui.gestures tools.test.ui
+ui.gadgets.grids prettyprint documents ui.gestures ui.gadgets.debug
 models documents.elements ui.gadgets.scrollers ui.gadgets.line-support
 sequences ;
 IN: ui.gadgets.editors.tests
index 9adb33a164dcb5d3e9f926f22149ff572b33408a..9461b2348f5f877052431b3c95d13b12d2015edd 100755 (executable)
@@ -8,7 +8,8 @@ continuations ui.clipboards ui.commands ui.gadgets ui.gadgets.borders
 ui.gadgets.buttons ui.gadgets.labels ui.gadgets.scrollers
 ui.gadgets.menus ui.gadgets.wrappers ui.render ui.pens.solid
 ui.gadgets.line-support ui.text ui.gestures ui.baseline-alignment
-math.rectangles splitting unicode.categories fonts grouping ;
+math.rectangles splitting unicode.categories grouping ;
+EXCLUDE: fonts => selection ;
 IN: ui.gadgets.editors
 
 TUPLE: editor < line-gadget
@@ -140,7 +141,7 @@ M: editor ungraft*
 : scroll>caret ( editor -- )
     dup graft-state>> second [
         [
-            [ caret-loc ] [ caret-dim { 1 0 } v+ ] bi <rect>
+            [ caret-loc ] [ caret-dim { 2 1 } v+ ] bi <rect>
         ] keep scroll>rect
     ] [ drop ] if ;
 
@@ -171,11 +172,10 @@ TUPLE: selected-line start end first? last? ;
 
 :: draw-selection ( line pair editor -- )
     pair [ editor font>> line offset>x ] map :> pair
-    pair first 0 2array [
-        editor selection-color>> gl-color
-        pair second pair first - round 1 max
-        editor line-height 2array gl-fill-rect
-    ] with-translation ;
+    editor selection-color>> gl-color
+    pair first 0 2array
+    pair second pair first - round 1 max editor line-height 2array
+    gl-fill-rect ;
 
 : draw-unselected-line ( line editor -- )
     font>> swap draw-text ;
@@ -413,8 +413,7 @@ editor "caret-motion" f {
 } define-command-map
 
 : clear-editor ( editor -- )
-    #! The with-datastack is a kludge to make it infer. Stupid.
-    model>> 1array [ clear-doc ] with-datastack drop ;
+    model>> clear-doc ;
 
 : select-all ( editor -- ) doc-elt select-elt ;
 
@@ -453,6 +452,7 @@ editor "caret-motion" f {
 
 editor "selection" f {
     { T{ button-down f { S+ } 1 } extend-selection }
+    { T{ button-up f { S+ } 1 } com-copy-selection }
     { T{ drag } drag-selection }
     { gain-focus focus-editor }
     { lose-focus unfocus-editor }
@@ -619,7 +619,7 @@ TUPLE: action-field < field quot ;
     [ editor>> editor-string ]
     [ editor>> clear-editor ]
     [ quot>> ]
-    tri call ;
+    tri call( string -- ) ;
 
 action-field H{
     { T{ key-down f f "RET" } [ invoke-action-field ] }
index baeb320447ec129ddbca4986f26b4a685ca571ea..03219c66fdf5ecc11e53b187e5eeafe049f5c283 100644 (file)
@@ -119,14 +119,14 @@ M: mock-gadget ungraft*
         [ { f f } ] [ "g" get graft-state>> ] unit-test
     ] with-variable
 
-    : add-some-children
+    : add-some-children ( gadget -- gadget )
         3 [
             <mock-gadget> over <model> >>model
             "g" get over add-gadget drop
             swap 1+ number>string set
         ] each ;
 
-    : status-flags
+    : status-flags ( -- seq )
         { "g" "1" "2" "3" } [ get graft-state>> ] map prune ;
 
     : notify-combo ( ? ? -- )
index e38f56c7f18cd2e13a45f17fbf9fb829ec784889..bc07006d623d8c5efffb4a531b41c105b23cdd0f 100644 (file)
@@ -11,6 +11,7 @@ CONSTANT: horizontal { 1 0 }
 CONSTANT: vertical { 0 1 }
 
 TUPLE: gadget < rect
+id
 pref-dim
 parent
 children
@@ -28,7 +29,7 @@ model ;
 
 M: gadget equal? 2drop f ;
 
-M: gadget hashcode* drop gadget hashcode* ;
+M: gadget hashcode* nip [ [ \ gadget counter ] unless* ] change-id id>> ;
 
 M: gadget model-changed 2drop ;
 
@@ -214,7 +215,8 @@ M: gadget ungraft* drop ;
 
 <PRIVATE
 
-: graft-queue ( -- dlist ) \ graft-queue get ;
+: graft-queue ( -- dlist )
+    \ graft-queue get [ "UI not running" throw ] unless* ;
 
 : unqueue-graft ( gadget -- )
     [ graft-node>> graft-queue delete-node ]
index af169235b405a94d5c184d2979ff760e0ffe567e..945e16150dbfe74d0eab8c80cce347c4f1163e5e 100644 (file)
@@ -63,7 +63,8 @@ TUPLE: popup < wrapper owner ;
         swap >>owner ; inline
 
 M: popup hide-glass-hook
-    owner>> f >>popup request-focus ;
+    dup owner>> 2dup popup>> eq?
+    [ f >>popup request-focus drop ] [ 2drop ] if ;
 
 PRIVATE>
 
@@ -75,7 +76,5 @@ popup H{
     popup>> focusable-child resend-gesture ;
 
 : show-popup ( owner popup visible-rect -- )
-    [ <popup> ] dip
-    [ drop dup owner>> (>>popup) ]
-    [ [ [ owner>> ] keep ] dip show-glass ]
-    2bi ;
\ No newline at end of file
+    [ [ dup dup popup>> [ hide-glass ] when* ] dip <popup> ] dip
+    [ drop >>popup drop ] [ show-glass ] 3bi ;
\ No newline at end of file
index fb92cd2ac65aaa7ddc3db1596d09760cec082a91..b83f1a700300d0b85962a185f8fc1b3644d670af 100644 (file)
@@ -3,9 +3,6 @@ namespaces math.rectangles accessors ui.gadgets.grids.private
 ui.gadgets.debug sequences ;
 IN: ui.gadgets.grids.tests
 
-[ { { { 1 "a" } { 1 "b" } } { { 2 "a" } { 2 "b" } } } ]
-[ { 1 2 } { "a" "b" } cross-zip ] unit-test
-
 [ { 0 0 } ] [ { } <grid> pref-dim ] unit-test
 
 : 100x100 ( -- gadget ) <gadget> { 100 100 } >>dim ;
index 4ab080464b748421521f9a5c1172602772d9bf84..ddcfa1465d93f169cefce8256ab5276437634a8a 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math math.order namespaces make sequences words io
+USING: arrays kernel math math.order math.matrices namespaces make sequences words io
 math.vectors ui.gadgets ui.baseline-alignment columns accessors strings.tables
 math.rectangles fry ;
 IN: ui.gadgets.grids
@@ -33,9 +33,6 @@ PRIVATE>
 
 <PRIVATE
 
-: cross-zip ( seq1 seq2 -- seq1xseq2 )
-    [ [ 2array ] with map ] curry map ;
-
 TUPLE: cell pref-dim baseline cap-height ;
 
 : <cell> ( gadget -- cell )
@@ -116,7 +113,7 @@ M: grid layout* [ grid>> ] [ <grid-layout> ] bi grid-layout ;
 
 M: grid children-on ( rect gadget -- seq )
     dup children>> empty? [ 2drop f ] [
-        { 0 1 } swap grid>>
+        [ { 0 1 } ] dip grid>>
         [ 0 <column> fast-children-on ] keep
         <slice> concat
     ] if ;
diff --git a/basis/ui/gadgets/labeled/labeled-tests.factor b/basis/ui/gadgets/labeled/labeled-tests.factor
new file mode 100644 (file)
index 0000000..ec232c3
--- /dev/null
@@ -0,0 +1,4 @@
+IN: ui.gadgets.labeled.tests
+USING: ui.gadgets ui.gadgets.labeled accessors tools.test ;
+
+[ t ] [ <gadget> "Hey" <labeled-gadget> content>> gadget? ] unit-test
\ No newline at end of file
index 319fd8cf70da5f8c62de4004ff6e23a944479ef1..97d029fe81023e382023f4d6ebee2e6b8b7a5526 100644 (file)
@@ -2,67 +2,33 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel sequences colors fonts ui.gadgets
 ui.gadgets.frames ui.gadgets.grids ui.gadgets.icons ui.gadgets.labels
-ui.gadgets.borders ui.pens.image ;
+ui.gadgets.borders ui.pens.image ui.gadgets.corners ui.render ;
 IN: ui.gadgets.labeled
 
 TUPLE: labeled-gadget < frame content ;
 
 <PRIVATE
 
-CONSTANT: @center { 1 1 }
-CONSTANT: @left { 0 1 }
-CONSTANT: @right { 2 1 }
-CONSTANT: @top { 1 0 }
-CONSTANT: @bottom { 1 2 }
-
-CONSTANT: @top-left { 0 0 }
-CONSTANT: @top-right { 2 0 }
-CONSTANT: @bottom-left { 0 2 }
-CONSTANT: @bottom-right { 2 2 }
-
-: labeled-image ( name -- image )
-    "labeled-block-" prepend theme-image ;
-
-: labeled-icon ( name -- icon )
-    labeled-image <icon> ;
-
-CONSTANT: labeled-title-background
-    T{ rgba f
-        0.7843137254901961
-        0.7686274509803922
-        0.7176470588235294
-        1.0
-    }
-
 : <labeled-title> ( gadget -- label )
     >label
-    [ labeled-title-background font-with-background ] change-font
+    [ panel-background-color font-with-background ] change-font
     { 0 2 } <border>
-    "title-middle" labeled-image
+    "title-middle" corner-image
     <image-pen> t >>fill? >>interior ;
 
 : /-FOO-\ ( title labeled -- labeled )
-    "title-left" labeled-icon @top-left grid-add
+    "title-left" corner-icon @top-left grid-add
     swap <labeled-title> @top grid-add
-    "title-right" labeled-icon @top-right grid-add ;
-
-: |-----| ( gadget labeled -- labeled )
-    "left-edge" labeled-icon @left grid-add
-    swap [ >>content ] [ @center grid-add ] bi
-    "right-edge" labeled-icon @right grid-add ;
-
-: \-----/ ( labeled -- labeled )
-    "bottom-left" labeled-icon @bottom-left grid-add
-    "bottom-middle" labeled-icon @bottom grid-add
-    "bottom-right" labeled-icon @bottom-right grid-add ;
+    "title-right" corner-icon @top-right grid-add ;
 
 M: labeled-gadget focusable-child* content>> ;
 
 PRIVATE>
 
 : <labeled-gadget> ( gadget title -- newgadget )
-    3 3 labeled-gadget new-frame
-        { 1 1 } >>filled-cell
+    labeled-gadget "labeled-block" [
+        pick >>content
         /-FOO-\
         |-----|
-        \-----/ ;
+        \-----/
+    ] make-corners ;
index 80feb31ad2215f83d177491c59a77c2c0b80d839..b9fe10c530b83e71ce1265a1f8edb8a255d57732 100644 (file)
@@ -30,6 +30,9 @@ M: line-gadget line-height font>> font-metrics height>> ceiling ;
 : validate-line ( m gadget -- n )
     control-value [ drop f ] [ length 1- min 0 max ] if-empty ;
 
+: valid-line? ( n gadget -- ? )
+    control-value length 1- 0 swap between? ;
+
 : visible-line ( gadget quot -- n )
     '[
         [ clip get @ origin get [ second ] bi@ - ] dip
index a0038b55e5e5bd493f619d78e60ccf7b3a850500..734190e7e79151b4daccb1df72978fdf9129c1e9 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: colors.constants kernel locals math.rectangles
-namespaces sequences ui.commands ui.gadgets ui.gadgets.borders
-ui.gadgets.buttons ui.gadgets.glass ui.gadgets.packs
-ui.gadgets.worlds ui.gestures ui.operations ui.pens ui.pens.solid
-opengl math.vectors words accessors math math.order sorting ;
+USING: colors.constants kernel locals math.rectangles namespaces
+sequences ui.commands ui.gadgets ui.gadgets.borders ui.gadgets.buttons
+ui.gadgets.glass ui.gadgets.packs ui.gadgets.frames ui.gadgets.worlds
+ui.gadgets.frames ui.gadgets.corners ui.gestures ui.operations
+ui.render ui.pens ui.pens.solid opengl math.vectors words accessors
+math math.order sorting ;
 IN: ui.gadgets.menus
 
 : show-menu ( owner menu -- )
@@ -30,6 +31,10 @@ M: separator-pen draw-interior
     dim>> [ { 0 0.5 } v* ] [ { 1 0.5 } v* ] bi
     [ [ >integer ] map ] bi@ gl-line ;
 
+: <menu-items> ( items -- gadget )
+    [ <filled-pile> ] dip add-gadgets
+    panel-background-color <solid> >>interior ;
+
 PRIVATE>
 
 SINGLETON: ----
@@ -43,10 +48,16 @@ M: ---- <menu-item>
 : menu-theme ( gadget -- gadget )
     COLOR: light-gray <solid> >>interior ;
 
+: <menu> ( gadgets -- menu )
+    <menu-items>
+    frame "menu-background" [
+        /-----\
+        |-----|
+        \-----/
+    ] make-corners ;
+
 : <commands-menu> ( target hook commands -- menu )
-    [ <filled-pile> ] 3dip
-    [ <menu-item> add-gadget ] with with each
-    { 5 5 } <border> menu-theme ;
+    [ <menu-item> ] with with map <menu> ;
 
 : show-commands-menu ( target commands -- )
     [ dup [ ] ] dip <commands-menu> show-menu ;
index 2947ce242d14f451cc9517052482319762ca80e3..0529437a76663c1d6edbb7c5877d4fcc3d39e615 100644 (file)
@@ -1,11 +1,11 @@
 USING: alien ui.gadgets.panes ui.gadgets namespaces
 kernel sequences io io.styles io.streams.string tools.test
 prettyprint definitions help help.syntax help.markup
-help.stylesheet splitting tools.test.ui models math summary
+help.stylesheet splitting ui.gadgets.debug models math summary
 inspector accessors help.topics see ;
 IN: ui.gadgets.panes.tests
 
-: #children "pane" get children>> length ;
+: #children ( -- n ) "pane" get children>> length ;
 
 [ ] [ <pane> "pane" set ] unit-test
 
index 28dc7e3ead8228938c552ec5b285a5b7cff93df0..6f6e7ee95f52da0029c088c6712b5d62c77e00d4 100644 (file)
@@ -10,7 +10,7 @@ ui.gadgets.paragraphs ui.gadgets.incremental ui.gadgets.packs
 ui.gadgets.menus ui.clipboards ui.gestures ui.traverse ui.render
 ui.text ui.gadgets.presentations ui.gadgets.grids ui.gadgets.tracks
 ui.gadgets.icons ui.gadgets.grid-lines ui.baseline-alignment
-colors call io.styles ;
+colors io.styles ;
 IN: ui.gadgets.panes
 
 TUPLE: pane < track
@@ -21,6 +21,8 @@ TUPLE: pane-stream pane ;
 
 C: <pane-stream> pane-stream
 
+M: pane-stream stream-element-type drop +character+ ;
+
 <PRIVATE
 
 : clear-selection ( pane -- pane )
@@ -47,13 +49,13 @@ C: <pane-stream> pane-stream
 : pane-caret&mark ( pane -- caret mark )
     [ caret>> ] [ mark>> ] bi ; inline
 
-: selected-children ( pane -- seq )
+: selected-subtree ( pane -- seq )
     [ pane-caret&mark sort-pair ] keep gadget-subtree ;
 
 M: pane gadget-selection? pane-caret&mark and ;
 
 M: pane gadget-selection ( pane -- string/f )
-    selected-children gadget-text ;
+    selected-subtree gadget-text ;
 
 : init-prototype ( pane -- pane )
     <shelf> +baseline+ >>align >>prototype ; inline
@@ -70,33 +72,12 @@ M: pane gadget-selection ( pane -- string/f )
     [ >>last-line ] [ 1 track-add ] bi
     dup prepare-last-line ; inline
 
-GENERIC: draw-selection ( loc obj -- )
-
-: if-fits ( rect quot -- )
-    [ clip get over contains-rect? ] dip [ drop ] if ; inline
-
-M: gadget draw-selection ( loc gadget -- )
-    swap offset-rect [
-        dup loc>> [
-            dim>> gl-fill-rect
-        ] with-translation
-    ] if-fits ;
-
-M: node draw-selection ( loc node -- )
-    2dup value>> swap offset-rect [
-        drop 2dup
-        [ value>> loc>> v+ ] keep
-        children>> [ draw-selection ] with each
-    ] if-fits 2drop ;
-
-M: pane draw-gadget*
+M: pane selected-children
     dup gadget-selection? [
-        [ selection-color>> gl-color ]
-        [
-            [ loc>> vneg ] keep selected-children
-            [ draw-selection ] with each
-        ] bi
-    ] [ drop ] if ;
+        [ selected-subtree leaves ]
+        [ selection-color>> ]
+        bi
+    ] [ drop f f ] if ;
 
 : scroll-pane ( pane -- )
     dup scrolls?>> [ scroll>bottom ] [ drop ] if ;
index 8e0131ec3182d32e3eee98bcadb224c86b9c47aa..011afa5c97d25f2f7b268bc1c7ec315f30b77496 100644 (file)
@@ -11,11 +11,11 @@ HELP: find-scroller
 { $values { "gadget" gadget } { "scroller/f" { $maybe scroller } } }
 { $description "Finds the first parent of " { $snippet "gadget" } " which is a " { $link scroller } ". Outputs " { $link f } " if the gadget is not contained in a " { $link scroller } "." } ;
 
-HELP: scroller-value
+HELP: scroll-position
 { $values { "scroller" scroller } { "loc" "a pair of integers" } }
 { $description "Outputs the offset of the top-left corner of the scroller's " { $link viewport } "'s child." } ;
 
-{ scroller-value scroll scroll>bottom scroll>top scroll>rect } related-words
+{ scroll-position set-scroll-position scroll>bottom scroll>top scroll>rect } related-words
 
 HELP: <scroller>
 { $values { "gadget" gadget } { "scroller" "a new " { $link scroller } } }
@@ -23,7 +23,7 @@ HELP: <scroller>
 
 { <viewport> <scroller> } related-words
 
-HELP: scroll
+HELP: set-scroll-position
 { $values { "scroller" scroller } { "value" "a pair of integers" } }
 { $description "Sets the offset of the top-left corner of the scroller's " { $link viewport } "'s child." } ;
 
@@ -48,8 +48,8 @@ ARTICLE: "ui.gadgets.scrollers" "Scroller gadgets"
 { $subsection scroller }
 { $subsection <scroller> }
 "Getting and setting the scroll position:"
-{ $subsection scroller-value }
-{ $subsection scroll }
+{ $subsection scroll-position }
+{ $subsection set-scroll-position }
 "Writing scrolling-aware gadgets:"
 { $subsection scroll>bottom }
 { $subsection scroll>top }
index 4e61c9b1ed8e20a83c02799b80312c149b586d17..22df1f328ba373e58f1740bf2c8b4cf5ff1a4665 100644 (file)
@@ -1,7 +1,7 @@
 USING: ui.gadgets ui.gadgets.scrollers namespaces tools.test
 kernel models models.product models.range ui.gadgets.viewports
 ui.gadgets.labels ui.gadgets.grids ui.gadgets.sliders math
-math.vectors arrays sequences tools.test.ui math.rectangles
+math.vectors arrays sequences ui.gadgets.debug math.rectangles
 accessors ui.gadgets.buttons ui.gadgets.packs
 ui.gadgets.scrollers.private ;
 IN: ui.gadgets.scrollers.tests
@@ -45,13 +45,13 @@ IN: ui.gadgets.scrollers.tests
 
     [ { 100 100 } ] [ "s" get viewport>> gadget-child pref-dim ] unit-test
 
-    [ ] [ { 0 0 } "s" get scroll ] unit-test
+    [ ] [ { 0 0 } "s" get set-scroll-position ] unit-test
 
     [ { 0 0 } ] [ "s" get model>> range-min-value ] unit-test
 
     [ { 100 100 } ] [ "s" get model>> range-max-value ] unit-test
 
-    [ ] [ { 10 20 } "s" get scroll ] unit-test
+    [ ] [ { 10 20 } "s" get set-scroll-position ] unit-test
 
     [ { 10 20 } ] [ "s" get model>> range-value ] unit-test
 
@@ -74,7 +74,7 @@ dup layout
         drop
         "g2" get scroll>gadget
         "s" get layout
-        "s" get scroller-value
+        "s" get scroll-position
     ] map [ { 0 0 } = ] all?
 ] unit-test
 
index 64e035c81bb505858741b5d73b4c5414f75a5008..0852a6fe5ddb3c3de21497a9bfe4e332be9e60f1 100644 (file)
@@ -29,6 +29,13 @@ M: gadget viewport-column-header drop f ;
 
 : scroll-down-line ( scroller -- ) y>> 1 swap slide-by-line ;
 
+: set-scroll-position ( value scroller -- )
+    [
+        viewport>> [ dim>> { 0 0 } ] [ gadget-child pref-dim ] bi
+        4array flip
+    ] keep
+    2dup control-value = [ 2drop ] [ set-control-value ] if ;
+
 <PRIVATE
 
 : do-mouse-scroll ( scroller -- )
@@ -46,21 +53,14 @@ scroller H{
 
 M: viewport pref-dim* gadget-child pref-viewport-dim ;
 
-: scroll ( value scroller -- )
-    [
-        viewport>> [ dim>> { 0 0 } ] [ gadget-child pref-dim ] bi
-        4array flip
-    ] keep
-    2dup control-value = [ 2drop ] [ set-control-value ] if ;
-
 : (scroll>rect) ( rect scroller -- )
-    [ [ loc>> ] [ dim>> { 1 1 } v+ ] bi <rect> ] dip
     {
-        [ scroller-value vneg offset-rect ]
+        [ scroll-position vneg offset-rect ]
         [ viewport>> dim>> rect-min ]
+        [ viewport>> loc>> offset-rect ]
         [ viewport>> [ v- { 0 0 } vmin ] [ v- { 0 0 } vmax ] with-rect-extents v+ ]
-        [ scroller-value v+ ]
-        [ scroll ]
+        [ scroll-position v+ ]
+        [ set-scroll-position ]
     } cleave ;
 
 : relative-scroll-rect ( rect gadget scroller -- newrect )
@@ -72,7 +72,7 @@ M: viewport pref-dim* gadget-child pref-viewport-dim ;
     2&& ;
 
 : (update-scroller) ( scroller -- )
-    [ scroller-value ] keep scroll ;
+    [ scroll-position ] keep set-scroll-position ;
 
 : (scroll>gadget) ( gadget scroller -- )
     2dup swap child? [
@@ -82,7 +82,8 @@ M: viewport pref-dim* gadget-child pref-viewport-dim ;
     ] [ f >>follows (update-scroller) drop ] if ;
 
 : (scroll>bottom) ( scroller -- )
-    [ viewport>> gadget-child pref-dim { 0 1 } v* ] keep scroll ;
+    [ viewport>> gadget-child pref-dim { 0 1 } v* ] keep
+    set-scroll-position ;
 
 GENERIC: update-scroller ( scroller follows -- )
 
diff --git a/basis/ui/gadgets/search-tables/search-tables-tests.factor b/basis/ui/gadgets/search-tables/search-tables-tests.factor
new file mode 100644 (file)
index 0000000..5a62728
--- /dev/null
@@ -0,0 +1,3 @@
+IN: ui.gadgets.search-tables.tests
+USING: ui.gadgets.search-tables sequences tools.test ;
+[ [ second ] <search-table> ] must-infer
index 4a2983bfe09627da18ae6d84f7d4a41e937a09d2..17570a8714a805903c79f213533e0afa7a6da4be 100644 (file)
@@ -28,6 +28,7 @@ TUPLE: search-field < track field ;
 
 : <search-field> ( model -- gadget )
     horizontal search-field new-track
+        0 >>fill
         { 5 5 } >>gap
         +baseline+ >>align
         swap <model-field> 10 >>min-cols >>field
index 7b1befc5397a1d143bc2367e284d73f662ec1be8..77249149aee11e97986ee9b95d05e5791c765d40 100644 (file)
@@ -121,16 +121,15 @@ M: table layout*
     [ [ line-height ] dip * 0 swap 2array ]
     [ drop [ dim>> first ] [ line-height ] bi 2array ] 2bi <rect> ;
 
-: highlight-row ( table row color quot -- )
-    [ [ row-rect rect-bounds ] dip gl-color ] dip
-    '[ _ @ ] with-translation ; inline
+: row-bounds ( table row -- loc dim )
+    row-rect rect-bounds ; inline
 
 : draw-selected-row ( table -- )
     {
         { [ dup selected-index>> not ] [ drop ] }
         [
-            [ ] [ selected-index>> ] [ selection-color>> ] tri
-            [ gl-fill-rect ] highlight-row
+            [ ] [ selected-index>> ] [ selection-color>> gl-color ] tri
+            row-bounds gl-fill-rect
         ]
     } cond ;
 
@@ -139,14 +138,15 @@ M: table layout*
         { [ dup focused?>> not ] [ drop ] }
         { [ dup selected-index>> not ] [ drop ] }
         [
-            [ ] [ selected-index>> ] [ focus-border-color>> ] tri
-            [ gl-rect ] highlight-row
+            [ ] [ selected-index>> ] [ focus-border-color>> gl-color ] tri
+            row-bounds gl-rect
         ]
     } cond ;
 
 : draw-moused-row ( table -- )
     dup mouse-index>> dup [
-        over mouse-color>> [ gl-rect ] highlight-row
+        over mouse-color>> gl-color
+        row-bounds gl-rect
     ] [ 2drop ] if ;
 
 : column-line-offsets ( table -- xs )
@@ -268,26 +268,30 @@ M: table model-changed
 : mouse-row ( table -- n )
     [ hand-rel second ] keep y>line ;
 
+: if-mouse-row ( table true: ( table mouse-index -- ) false: ( table -- ) -- )
+    [ [ mouse-row ] keep 2dup valid-line? ]
+    [ ] [ '[ nip @ ] ] tri* if ; inline
+
 : table-button-down ( table -- )
     dup takes-focus?>> [ dup request-focus ] when
-    dup control-value empty? [ drop ] [
-        dup [ mouse-row ] keep validate-line
-        [ >>mouse-index ] [ (select-row) ] bi
-    ] if ;
+    [ swap [ >>mouse-index ] [ (select-row) ] bi ] [ drop ] if-mouse-row ;
 
 PRIVATE>
 
 : row-action ( table -- )
     dup selected-row
-    [ swap [ action>> call ] [ dup hook>> call ] bi ]
+    [ swap [ action>> call( value -- ) ] [ dup hook>> call( table -- ) ] bi ]
     [ 2drop ]
     if ;
 
+: row-action? ( table -- ? )
+    [ [ mouse-row ] keep valid-line? ]
+    [ single-click?>> hand-click# get 2 = or ] bi and ;
+
 <PRIVATE
 
 : table-button-up ( table -- )
-    dup single-click?>> hand-click# get 2 = or
-    [ row-action ] [ update-selected-value ] if ;
+    dup row-action? [ row-action ] [ update-selected-value ] if ;
 
 : select-row ( table n -- )
     over validate-line
@@ -320,13 +324,6 @@ PRIVATE>
 : next-page ( table -- )
     1 prev/next-page ;
 
-: valid-row? ( row table -- ? )
-    control-value length 1- 0 swap between? ;
-
-: if-mouse-row ( table true false -- )
-    [ [ mouse-row ] keep 2dup valid-row? ]
-    [ ] [ '[ nip @ ] ] tri* if ; inline
-
 : show-mouse-help ( table -- )
     [
         swap
diff --git a/basis/ui/gadgets/theme/menu-background-bottom-left.tiff b/basis/ui/gadgets/theme/menu-background-bottom-left.tiff
new file mode 100644 (file)
index 0000000..7052039
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-bottom-left.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-bottom-middle.tiff b/basis/ui/gadgets/theme/menu-background-bottom-middle.tiff
new file mode 100644 (file)
index 0000000..a004654
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-bottom-middle.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-bottom-right.tiff b/basis/ui/gadgets/theme/menu-background-bottom-right.tiff
new file mode 100644 (file)
index 0000000..07658be
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-bottom-right.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-left-edge.tiff b/basis/ui/gadgets/theme/menu-background-left-edge.tiff
new file mode 100644 (file)
index 0000000..81d5820
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-left-edge.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-right-edge.tiff b/basis/ui/gadgets/theme/menu-background-right-edge.tiff
new file mode 100644 (file)
index 0000000..61a70be
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-right-edge.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-top-left.tiff b/basis/ui/gadgets/theme/menu-background-top-left.tiff
new file mode 100644 (file)
index 0000000..78ead4d
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-top-left.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-top-middle.tiff b/basis/ui/gadgets/theme/menu-background-top-middle.tiff
new file mode 100644 (file)
index 0000000..ba5fffe
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-top-middle.tiff differ
diff --git a/basis/ui/gadgets/theme/menu-background-top-right.tiff b/basis/ui/gadgets/theme/menu-background-top-right.tiff
new file mode 100644 (file)
index 0000000..1831a32
Binary files /dev/null and b/basis/ui/gadgets/theme/menu-background-top-right.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-bottom-left.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-bottom-left.tiff
new file mode 100644 (file)
index 0000000..eca211b
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-bottom-left.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-bottom-middle.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-bottom-middle.tiff
new file mode 100644 (file)
index 0000000..b666be1
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-bottom-middle.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-bottom-right.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-bottom-right.tiff
new file mode 100644 (file)
index 0000000..788781b
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-bottom-right.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-left-edge.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-left-edge.tiff
new file mode 100644 (file)
index 0000000..61371da
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-left-edge.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-right-edge.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-right-edge.tiff
new file mode 100644 (file)
index 0000000..51bda47
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-right-edge.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-top-left.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-top-left.tiff
new file mode 100644 (file)
index 0000000..f86aafb
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-top-left.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-top-middle.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-top-middle.tiff
new file mode 100644 (file)
index 0000000..8beab3c
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-top-middle.tiff differ
diff --git a/basis/ui/gadgets/theme/selected-menu-item-background-top-right.tiff b/basis/ui/gadgets/theme/selected-menu-item-background-top-right.tiff
new file mode 100644 (file)
index 0000000..dacb50d
Binary files /dev/null and b/basis/ui/gadgets/theme/selected-menu-item-background-top-right.tiff differ
index c14c7f01fb1ea83ac5f89ca3b74de4b9125df95c..b154ef2322f4925d06eb14b06190c9e092ec303e 100644 (file)
@@ -23,7 +23,7 @@ M: viewport layout*
 M: viewport focusable-child*
     gadget-child ;
 
-: scroller-value ( scroller -- loc )
+: scroll-position ( scroller -- loc )
     model>> range-value [ >integer ] map ;
 
 M: viewport model-changed
@@ -31,7 +31,7 @@ M: viewport model-changed
     [ relayout-1 ]
     [
         [ gadget-child ]
-        [ scroller-value vneg ]
+        [ scroll-position vneg ]
         [ constraint>> ]
         tri v* >>loc drop
     ] bi ;
index ccfa83334b202079c81c1500535c27135a7fb13c..a186de76709cbe4197514c2f26f243665de07083 100644 (file)
@@ -1,10 +1,10 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs continuations kernel math models
-call namespaces opengl sequences io combinators
+namespaces opengl opengl.textures sequences io combinators
 combinators.short-circuit fry math.vectors math.rectangles cache
-ui.gadgets ui.gestures ui.render ui.text ui.text.private
-ui.backend ui.gadgets.tracks ui.commands ;
+ui.gadgets ui.gestures ui.render ui.backend ui.gadgets.tracks
+ui.commands ;
 IN: ui.gadgets.worlds
 
 TUPLE: world < track
@@ -53,7 +53,6 @@ M: world request-focus-on ( child gadget -- )
         swap >>status
         swap >>title
         swap 1 track-add
-    dup init-text-rendering
     dup request-focus ;
 
 : <world> ( gadget title status -- world )
@@ -74,15 +73,21 @@ M: world remove-gadget
     2dup layers>> memq?
     [ layers>> delq ] [ call-next-method ] if ;
 
+SYMBOL: flush-layout-cache-hook
+
+flush-layout-cache-hook [ [ ] ] initialize
+
 : (draw-world) ( world -- )
     dup handle>> [
+        check-extensions
         {
             [ init-gl ]
             [ draw-gadget ]
-            [ finish-text-rendering ]
+            [ text-handle>> [ purge-cache ] when* ]
             [ images>> [ purge-cache ] when* ]
         } cleave
-    ] with-gl-context ;
+    ] with-gl-context
+    flush-layout-cache-hook get call( -- ) ;
 
 : draw-world? ( world -- ? )
     #! We don't draw deactivated worlds, or those with 0 size.
index 2e52a2fe1e54460a6d772924f6528b46e0f88067..c7db0839d7b08c0f8f139ffd5c25ccffe4a65b49 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors arrays assocs kernel math math.order models
 namespaces make sequences words strings system hashtables math.parser
 math.vectors classes.tuple classes boxes calendar alarms combinators
 sets columns fry deques ui.gadgets ui.gadgets.private unicode.case
-unicode.categories combinators.short-circuit call ;
+unicode.categories combinators.short-circuit ;
 IN: ui.gestures
 
 GENERIC: handle-gesture ( gesture gadget -- ? )
old mode 100644 (file)
new mode 100755 (executable)
index fe7a8b52c5b31674c3c84ae75b25d0220d00bf83..4612ea79b0a1cfe13b783ce9ed2dd5885fb440fa 100644 (file)
@@ -3,7 +3,7 @@ USING: ui.operations ui.commands prettyprint kernel namespaces
 tools.test ui.gadgets ui.gadgets.editors parser io
 io.streams.string math help help.markup accessors ;
 
-: my-pprint pprint ;
+: my-pprint ( obj -- ) pprint ;
 
 [ drop t ] \ my-pprint [ ] f operation boa "op" set
 
index 2f9cfba961adf3795f1de6eeba25b25c2f8aac85..db6048061e47997dc2291e8a85337475a9bbb399 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions kernel ui.commands
 ui.gestures sequences strings math words generic namespaces
-hashtables help.markup quotations assocs fry call linked-assocs ;
+hashtables help.markup quotations assocs fry linked-assocs ;
 IN: ui.operations
 
 SYMBOL: +keyboard+
index 950035e7730dc5ff28e81a6b58fd3eb1c953af0d..fe44a8f3418bf2bb7aed70ded5c25e91ec1718fe 100644 (file)
@@ -9,8 +9,8 @@ TUPLE: solid < caching-pen color interior-vertices boundary-vertices ;
 
 M: solid recompute-pen
     swap dim>>
-    [ (fill-rect-vertices) >>interior-vertices ]
-    [ (rect-vertices) >>boundary-vertices ]
+    [ [ { 0 0 } ] dip (fill-rect-vertices) >>interior-vertices ]
+    [ [ { 0 0 } ] dip (rect-vertices) >>boundary-vertices ]
     bi drop ;
 
 <PRIVATE
index d083b70908a3bf38c0816b91eb8e7651fc94d9ad..c4e6f5688639d1b21a125a237e6895070495f45f 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: math.rectangles math.vectors namespaces kernel accessors
-combinators sequences opengl opengl.gl opengl.glu colors
+assocs combinators sequences opengl opengl.gl colors
 colors.constants ui.gadgets ui.pens ;
 IN: ui.render
 
@@ -22,7 +22,7 @@ SYMBOL: viewport-translation
         dim>>
         [ { 0 1 } v* viewport-translation set ]
         [ [ { 0 0 } ] dip gl-viewport ]
-        [ [ 0 ] dip first2 0 gluOrtho2D ] tri
+        [ [ 0 ] dip first2 0 1 -1 glOrtho ] tri
     ]
     [ clip set ] bi
     do-clip ;
@@ -38,7 +38,7 @@ SYMBOL: viewport-translation
     ! white gl-clear is broken w.r.t window resizing
     ! Linux/PPC Radeon 9200
     COLOR: white gl-color
-    clip get dim>> gl-fill-rect ;
+    { 0 0 } clip get dim>> gl-fill-rect ;
 
 GENERIC: draw-gadget* ( gadget -- )
 
@@ -55,21 +55,57 @@ SYMBOL: origin
 
 GENERIC: draw-children ( gadget -- )
 
+! For gadget selection
+SYMBOL: selected-gadgets
+
+SYMBOL: selection-background
+
+GENERIC: selected-children ( gadget -- assoc/f selection-background )
+
+M: gadget selected-children drop f f ;
+
+! For text rendering
+SYMBOL: background
+
+SYMBOL: foreground
+
+GENERIC: gadget-background ( gadget -- color )
+
+M: gadget gadget-background dup interior>> pen-background ;
+
+GENERIC: gadget-foreground ( gadget -- color )
+
+M: gadget gadget-foreground dup interior>> pen-foreground ;
+
+<PRIVATE
+
+: draw-selection-background ( gadget -- )
+    selection-background get background set
+    selection-background get gl-color
+    [ { 0 0 } ] dip dim>> gl-fill-rect ;
+
+: draw-standard-background ( object -- )
+    dup interior>> dup [ draw-interior ] [ 2drop ] if ;
+
+: draw-background ( gadget -- )
+    origin get [
+        [
+            dup selected-gadgets get key?
+            [ draw-selection-background ]
+            [ draw-standard-background ] if
+        ] [ draw-gadget* ] bi
+    ] with-translation ;
+
+: draw-border ( object -- )
+    dup boundary>> dup [
+        origin get [ draw-boundary ] with-translation
+    ] [ 2drop ] if ;
+
+PRIVATE>
+
 : (draw-gadget) ( gadget -- )
     dup loc>> origin get v+ origin [
-        [
-            origin get [
-                [ dup interior>> dup [ draw-interior ] [ 2drop ] if ]
-                [ draw-gadget* ]
-                bi
-            ] with-translation
-        ]
-        [ draw-children ]
-        [
-            dup boundary>> dup [
-                origin get [ draw-boundary ] with-translation
-            ] [ 2drop ] if
-        ] tri
+        [ draw-background ] [ draw-children ] [ draw-border ] tri
     ] with-variable ;
 
 : >absolute ( rect -- rect )
@@ -88,28 +124,33 @@ GENERIC: draw-children ( gadget -- )
         [ [ (draw-gadget) ] with-clipping ]
     } cond ;
 
-! For text rendering
-SYMBOL: background
-
-SYMBOL: foreground
-
-GENERIC: gadget-background ( gadget -- color )
-
-M: gadget gadget-background dup interior>> pen-background ;
-
-GENERIC: gadget-foreground ( gadget -- color )
-
-M: gadget gadget-foreground dup interior>> pen-foreground ;
-
 M: gadget draw-children
-    [ visible-children ]
-    [ gadget-background ]
-    [ gadget-foreground ] tri [
-        [ foreground set ] when*
-        [ background set ] when*
-        [ draw-gadget ] each
-    ] with-scope ;
+    dup children>> [
+        {
+            [ visible-children ]
+            [ selected-children ]
+            [ gadget-background ]
+            [ gadget-foreground ]
+        } cleave [
+            
+            {
+                [ [ selected-gadgets set ] when* ]
+                [ [ selection-background set ] when* ]
+                [ [ background set ] when* ]
+                [ [ foreground set ] when* ]
+            } spread
+            [ draw-gadget ] each
+        ] with-scope
+    ] [ drop ] if ;
 
 CONSTANT: selection-color T{ rgba f 0.8 0.8 1.0 1.0 }
 
+CONSTANT: panel-background-color
+    T{ rgba f
+        0.7843137254901961
+        0.7686274509803922
+        0.7176470588235294
+        1.0
+    }
+
 CONSTANT: focus-border-color COLOR: dark-gray
old mode 100644 (file)
new mode 100755 (executable)
index 785a936..0d720ac
@@ -10,22 +10,18 @@ IN: ui.text.core-text
 
 SINGLETON: core-text-renderer
 
-M: core-text-renderer init-text-rendering
-    <cache-assoc> >>text-handle drop ;
-
 M: core-text-renderer string-dim
     [ " " string-dim { 0 1 } v* ]
     [ cached-line dim>> ]
     if-empty ;
 
-M: core-text-renderer finish-text-rendering
-    text-handle>> purge-cache
+M: core-text-renderer flush-layout-cache
     cached-lines get purge-cache ;
 
 : rendered-line ( font string -- texture )
-    world get text-handle>>
-    [ cached-line [ image>> ] [ loc>> ] bi <texture> ]
-    2cache ;
+    world get world-text-handle [
+        cached-line [ image>> ] [ loc>> ] bi <texture>
+    2cache ;
 
 M: core-text-renderer draw-string ( font string -- )
     rendered-line draw-texture ;
index 8b644be469ef1cfd04a365a287b8ad510cf3fd53..92c4fe5c75f245206c66e776ee5ce6c7e0dceca3 100755 (executable)
@@ -7,21 +7,17 @@ IN: ui.text.pango
 
 SINGLETON: pango-renderer
 
-M: pango-renderer init-text-rendering
-    <cache-assoc> >>text-handle drop ;
-
 M: pango-renderer string-dim
     [ " " string-dim { 0 1 } v* ]
     [ cached-layout logical-rect>> dim>> [ >integer ] map ] if-empty ;
 
-M: pango-renderer finish-text-rendering
-    text-handle>> purge-cache
+M: pango-renderer flush-layout-cache
     cached-layouts get purge-cache ;
 
 : rendered-layout ( font string -- texture )
-    world get text-handle>>
-    [ cached-layout [ image>> ] [ text-position vneg ] bi <texture> ]
-    2cache ;
+    world get world-text-handle [
+        cached-layout [ image>> ] [ text-position vneg ] bi <texture>
+    2cache ;
 
 M: pango-renderer draw-string ( font string -- )
     rendered-layout draw-texture ;
diff --git a/basis/ui/text/pango/summary.txt b/basis/ui/text/pango/summary.txt
new file mode 100755 (executable)
index 0000000..0e2e18c
--- /dev/null
@@ -0,0 +1 @@
+UI text rendering implementation using cross-platform Pango library\r
old mode 100644 (file)
new mode 100755 (executable)
index 939e262..7ee901d
@@ -1,6 +1,22 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test ui.text fonts ;
+USING: tools.test ui.text fonts math accessors kernel sequences ;
 IN: ui.text.tests
 
-[ 0.0 ] [ 0 sans-serif-font "aaa" offset>x ] unit-test
+[ t ] [ 0 sans-serif-font "aaa" offset>x zero? ] unit-test
+[ t ] [ 1 sans-serif-font "aaa" offset>x 0.0 > ] unit-test
+[ t ] [ 3 sans-serif-font "aaa" offset>x 0.0 > ] unit-test
+[ t ] [ 1 monospace-font "a" offset>x 0.0 > ] unit-test
+[ 0 ] [ 0 sans-serif-font "aaa" x>offset ] unit-test
+[ 3 ] [ 100 sans-serif-font "aaa" x>offset ] unit-test
+[ 0 ] [ 0 sans-serif-font "" x>offset ] unit-test
+
+[ t ] [
+    sans-serif-font "aaa" line-metrics
+    [ [ ascent>> ] [ descent>> ] bi + ] [ height>> ] bi =
+] unit-test
+
+[ f ] [ sans-serif-font "\0a" text-dim first zero? ] unit-test
+[ t ] [ sans-serif-font "" text-dim first zero? ] unit-test
+
+[ f ] [ sans-serif-font font-metrics height>> zero? ] unit-test
old mode 100644 (file)
new mode 100755 (executable)
index d0766e9..2edb20f
@@ -1,18 +1,21 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel arrays sequences math math.order opengl opengl.gl
-strings fonts colors accessors ;
+USING: kernel arrays sequences math math.order cache opengl
+opengl.gl strings fonts colors accessors namespaces
+ui.gadgets.worlds ;
 IN: ui.text
 
 <PRIVATE
 
 SYMBOL: font-renderer
 
-HOOK: init-text-rendering font-renderer ( world -- )
+: world-text-handle ( world -- handle )
+    dup text-handle>> [ <cache-assoc> >>text-handle ] unless
+    text-handle>> ;
 
-HOOK: finish-text-rendering font-renderer ( world -- )
+HOOK: flush-layout-cache font-renderer ( -- )
 
-M: object finish-text-rendering drop ;
+[ flush-layout-cache ] flush-layout-cache-hook set-global
 
 HOOK: string-dim font-renderer ( font string -- dim )
 
@@ -63,9 +66,19 @@ M: string draw-text draw-string ;
 M: selection draw-text draw-string ;
 
 M: array draw-text
-    GL_MODELVIEW [
+    [
         [
             [ draw-string ]
             [ [ 0.0 ] 2dip string-height 0.0 glTranslated ] 2bi
         ] with each
-    ] do-matrix ;
\ No newline at end of file
+    ] do-matrix ;
+
+USING: vocabs.loader namespaces system combinators ;
+
+"ui-backend" get [
+    {
+        { [ os macosx? ] [ "core-text" ] }
+        { [ os windows? ] [ "uniscribe" ] }
+        { [ os unix? ] [ "pango" ] }
+    } cond
+] unless* "ui.text." prepend require
\ No newline at end of file
diff --git a/basis/ui/text/uniscribe/authors.txt b/basis/ui/text/uniscribe/authors.txt
new file mode 100755 (executable)
index 0000000..56f4654
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov\r
diff --git a/basis/ui/text/uniscribe/summary.txt b/basis/ui/text/uniscribe/summary.txt
new file mode 100755 (executable)
index 0000000..6fe24d9
--- /dev/null
@@ -0,0 +1 @@
+UI text rendering implementation using the MS Windows Uniscribe library\r
diff --git a/basis/ui/text/uniscribe/tags.txt b/basis/ui/text/uniscribe/tags.txt
new file mode 100755 (executable)
index 0000000..6abe115
--- /dev/null
@@ -0,0 +1 @@
+unportable\r
diff --git a/basis/ui/text/uniscribe/uniscribe.factor b/basis/ui/text/uniscribe/uniscribe.factor
new file mode 100755 (executable)
index 0000000..d56da86
--- /dev/null
@@ -0,0 +1,42 @@
+! Copyright (C) 2009 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: accessors assocs cache kernel math math.vectors sequences fonts\r
+namespaces opengl.textures ui.text ui.text.private ui.gadgets.worlds \r
+windows.uniscribe ;\r
+IN: ui.text.uniscribe\r
+\r
+SINGLETON: uniscribe-renderer\r
+\r
+M: uniscribe-renderer string-dim\r
+    [ " " string-dim { 0 1 } v* ]\r
+    [ cached-script-string size>> ] if-empty ;\r
+\r
+M: uniscribe-renderer flush-layout-cache\r
+    cached-script-strings get purge-cache ;\r
+\r
+: rendered-script-string ( font string -- texture )\r
+    world get world-text-handle\r
+    [ cached-script-string image>> { 0 0 } <texture> ]\r
+    2cache ;\r
+\r
+M: uniscribe-renderer draw-string ( font string -- )\r
+    dup dup selection? [ string>> ] when empty?\r
+    [ 2drop ] [ rendered-script-string draw-texture ] if ;\r
+\r
+M: uniscribe-renderer x>offset ( x font string -- n )\r
+    [ 2drop 0 ] [\r
+        cached-script-string x>line-offset 0 = [ 1+ ] unless\r
+    ] if-empty ;\r
+\r
+M: uniscribe-renderer offset>x ( n font string -- x )\r
+    [ 2drop 0 ] [ cached-script-string line-offset>x ] if-empty ;\r
+\r
+M: uniscribe-renderer font-metrics ( font -- metrics )\r
+    " " cached-script-string metrics>> clone f >>width ;\r
+\r
+M: uniscribe-renderer line-metrics ( font string -- metrics )\r
+    [ " " line-metrics clone 0 >>width ]\r
+    [ cached-script-string metrics>> 50 >>width 10 >>cap-height 10 >>x-height ]\r
+    if-empty ;\r
+\r
+uniscribe-renderer font-renderer set-global\r
index 03a5218e4566b4c7a02a510746d6b6d47efe6c16..b07e72dbce239e5431a92f7bc0e33341b4631be5 100644 (file)
@@ -2,7 +2,7 @@ USING: help.markup help.syntax ui.commands ;
 IN: ui.tools.browser
 
 ARTICLE: "ui-browser" "UI browser"
-"The browser is used to display Factor code, documentation, and vocabularies. The browser is opened when a word or articlelink presentation is clicked. It can also be opened using words:"
+"The browser is used to display Factor code, documentation, and vocabularies. The browser is opened when a word or article link presentation is clicked. It can also be opened using words:"
 { $subsection com-browse }
 { $subsection browser-window }
 { $command-map browser-gadget "toolbar" }
index 7477edbe6a713499bc603588c352ead84926abe1..3757f392c4b8961bf2234603014bde4ebdc37ae1 100644 (file)
@@ -1,5 +1,5 @@
 IN: ui.tools.browser.tests
-USING: tools.test tools.test.ui ui.tools.browser math ;
+USING: tools.test ui.gadgets.debug ui.tools.browser math ;
 
 \ <browser-gadget> must-infer
 [ ] [ \ + <browser-gadget> [ ] with-grafted-gadget ] unit-test
index 078ece6546ecc6d82b31f7fe1b696ba865a90ac8..0c6e1fe05a5b34f111bd4d4bd13c2c8492f69433 100644 (file)
@@ -1,22 +1,33 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: debugger help help.topics help.crossref kernel models compiler.units
-assocs words vocabs accessors fry combinators.short-circuit
-sequences models models.history tools.apropos combinators
-ui.commands ui.gadgets ui.gadgets.panes ui.gadgets.scrollers
-ui.gadgets.tracks ui.gestures ui.gadgets.buttons ui.gadgets.packs
-ui.gadgets.editors ui.gadgets.labels ui.gadgets.status-bar
-ui.gadgets.glass ui.gadgets.borders ui.tools.common
-ui.tools.browser.popups ui ;
+USING: debugger help help.topics help.crossref help.home kernel models
+compiler.units assocs words vocabs accessors fry arrays
+combinators.short-circuit namespaces sequences models help.apropos
+combinators ui ui.commands ui.gadgets ui.gadgets.panes
+ui.gadgets.scrollers ui.gadgets.tracks ui.gestures ui.gadgets.buttons
+ui.gadgets.packs ui.gadgets.editors ui.gadgets.labels
+ui.gadgets.status-bar ui.gadgets.glass ui.gadgets.borders ui.gadgets.viewports
+ui.tools.common ui.tools.browser.popups ui.tools.browser.history ;
 IN: ui.tools.browser
 
-TUPLE: browser-gadget < tool pane scroller search-field popup ;
+TUPLE: browser-gadget < tool history pane scroller search-field popup ;
 
 { 650 400 } browser-gadget set-tool-dim
 
+M: browser-gadget history-value
+    [ control-value ] [ scroller>> scroll-position ]
+    bi 2array ;
+
+M: browser-gadget set-history-value
+    [ first2 ] dip
+    [ set-control-value ] [ scroller>> set-scroll-position ]
+    bi-curry bi* ;
+
 : show-help ( link browser-gadget -- )
-    model>> dup add-history
-    [ >link ] dip set-model ;
+    [ >link ] dip
+    [ [ add-recent ] [ history>> add-history ] bi* ]
+    [ model>> set-model ]
+    2bi ;
 
 : <help-pane> ( browser-gadget -- gadget )
     model>> [ '[ _ print-topic ] try ] <pane-control> ;
@@ -40,7 +51,8 @@ TUPLE: browser-gadget < tool pane scroller search-field popup ;
 : <browser-gadget> ( link -- gadget )
     vertical browser-gadget new-track
         1 >>fill
-        swap >link <history> >>model
+        swap >link <model> >>model
+        dup <history> >>history
         dup <search-field> >>search-field
         dup <browser-toolbar> { 3 3 } <border> { 1 0 } >>fill f track-add
         dup <help-pane> >>pane
@@ -77,7 +89,7 @@ M: browser-gadget focusable-child* search-field>> ;
     <browser-gadget> "Browser" open-status-window ;
 
 : browser-window ( -- )
-    "handbook" (browser-window) ;
+    "help.home" (browser-window) ;
 
 \ browser-window H{ { +nullary+ t } } define-command
 
@@ -88,15 +100,15 @@ M: browser-gadget focusable-child* search-field>> ;
 
 : show-browser ( -- )
     [ browser-gadget? ] find-window
-    [ raise-window ] [ browser-window ] if* ;
+    [ [ raise-window ] [ request-focus ] bi ] [ browser-window ] if* ;
 
 \ show-browser H{ { +nullary+ t } } define-command
 
-: com-back ( browser -- ) model>> go-back ;
+: com-back ( browser -- ) history>> go-back ;
 
-: com-forward ( browser -- ) model>> go-forward ;
+: com-forward ( browser -- ) history>> go-forward ;
 
-: com-documentation ( browser -- ) "handbook" swap show-help ;
+: com-home ( browser -- ) "help.home" swap show-help ;
 
 : browser-help ( -- ) "ui-browser" com-browse ;
 
@@ -105,7 +117,7 @@ M: browser-gadget focusable-child* search-field>> ;
 browser-gadget "toolbar" f {
     { T{ key-down f { A+ } "LEFT" } com-back }
     { T{ key-down f { A+ } "RIGHT" } com-forward }
-    { f com-documentation }
+    { T{ key-down f { A+ } "H" } com-home }
     { T{ key-down f f "F1" } browser-help }
 } define-command-map
 
@@ -113,7 +125,7 @@ browser-gadget "toolbar" f {
     over [ show-help ] [ 2drop ] if ;
 
 : navigate ( browser quot -- )
-    '[ control-value @ ] keep ?show-help ;
+    '[ control-value @ ] keep ?show-help ; inline
 
 : com-up ( browser -- ) [ article-parent ] navigate ;
 
diff --git a/basis/ui/tools/browser/history/authors.txt b/basis/ui/tools/browser/history/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/ui/tools/browser/history/history-tests.factor b/basis/ui/tools/browser/history/history-tests.factor
new file mode 100644 (file)
index 0000000..454e470
--- /dev/null
@@ -0,0 +1,42 @@
+USING: namespaces ui.tools.browser.history sequences tools.test
+accessors kernel ;
+IN: ui.tools.browser.history.tests
+
+TUPLE: dummy obj ;
+
+M: dummy history-value obj>> ;
+M: dummy set-history-value (>>obj) ;
+
+dummy new <history> "history" set
+
+"history" get add-history
+
+[ t ] [ "history" get back>> empty? ] unit-test
+[ t ] [ "history" get forward>> empty? ] unit-test
+
+"history" get add-history
+3 "history" get owner>> set-history-value
+
+[ t ] [ "history" get back>> empty? ] unit-test
+[ t ] [ "history" get forward>> empty? ] unit-test
+
+"history" get add-history
+4 "history" get owner>> set-history-value
+
+[ f ] [ "history" get back>> empty? ] unit-test
+[ t ] [ "history" get forward>> empty? ] unit-test
+
+"history" get go-back
+
+[ 3 ] [ "history" get owner>> history-value ] unit-test
+
+[ t ] [ "history" get back>> empty? ] unit-test
+[ f ] [ "history" get forward>> empty? ] unit-test
+
+"history" get go-forward
+
+[ 4 ] [ "history" get owner>> history-value ] unit-test
+
+[ f ] [ "history" get back>> empty? ] unit-test
+[ t ] [ "history" get forward>> empty? ] unit-test
+
diff --git a/basis/ui/tools/browser/history/history.factor b/basis/ui/tools/browser/history/history.factor
new file mode 100644 (file)
index 0000000..f80189c
--- /dev/null
@@ -0,0 +1,32 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors sequences locals ;
+IN: ui.tools.browser.history
+
+TUPLE: history owner back forward ;
+
+: <history> ( owner -- history )
+    V{ } clone V{ } clone history boa ;
+
+GENERIC: history-value ( object -- value )
+
+GENERIC: set-history-value ( value object -- )
+
+: (add-history) ( history to -- )
+    swap owner>> history-value dup [ swap push ] [ 2drop ] if ;
+
+:: go-back/forward ( history to from -- )
+    from empty? [
+        history to (add-history)
+        from pop history owner>> set-history-value
+    ] unless ;
+
+: go-back ( history -- )
+    dup [ forward>> ] [ back>> ] bi go-back/forward ;
+
+: go-forward ( history -- )
+    dup [ back>> ] [ forward>> ] bi go-back/forward ;
+
+: add-history ( history -- )
+    dup forward>> delete-all
+    dup back>> (add-history) ;
\ No newline at end of file
index e625d26c60fd6d7107572492fdafd1b48d5df7ad..b0a2fb6cf96eeba9cc6a9922616d8c88df71dbfa 100644 (file)
@@ -1,4 +1,4 @@
-USING: help.markup help.syntax ;
+USING: help.markup help.syntax help.tips ;
 IN: ui.tools.deploy
 
 HELP: deploy-tool
@@ -14,4 +14,6 @@ $nl
 "Alternatively, right-click on a vocabulary presentation in the UI and choose " { $strong "Deploy tool" } " from the resulting popup menu."
 { $see-also "tools.deploy" } ;
 
+TIP: "Generate stand-alone applications from vocabularies with the " { $link "ui.tools.deploy" } "." ;
+
 ABOUT: "ui.tools.deploy"
index 0f357cb0afb0c94c32aa299a62a1ffe1dbec5706..ba66121bc223cad84682107ce3e0c10a62527b36 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors arrays assocs calendar colors colors.constants
 documents documents.elements fry kernel words sets splitting math
 math.vectors models.delay models.arrow combinators.short-circuit
-parser present sequences tools.completion tools.vocabs.browser generic
+parser present sequences tools.completion help.vocabs generic
 generic.standard.engines.tuple fonts definitions.icons ui.images
 ui.commands ui.operations ui.gadgets ui.gadgets.editors
 ui.gadgets.glass ui.gadgets.scrollers ui.gadgets.tables
@@ -141,6 +141,7 @@ GENERIC# accept-completion-hook 1 ( item popup -- )
         t >>selection-required?
         t >>single-click?
         30 >>min-cols
+        10 >>min-rows
         10 >>max-rows
         dup '[ _ accept-completion ] >>action ;
 
index caff45e40ed3c22e992e48ffe74dbd2b278e2062..afe890b9c5264cc997792c243e8a39bca9d3a206 100644 (file)
@@ -1,5 +1,7 @@
 USING: help.markup help.syntax ui.commands ui.operations
-ui.gadgets.editors ui.gadgets.panes listener io words ;
+ui.gadgets.editors ui.gadgets.panes listener io words
+ui.tools.listener.completion ui.tools.common help.tips
+tools.vocabs vocabs ;
 IN: ui.tools.listener
 
 HELP: interactor
@@ -21,11 +23,27 @@ ARTICLE: "ui-listener" "UI listener"
 { $operations \ word }
 { $heading "Vocabulary commands" }
 "These words operate on the vocabulary at the cursor."
-{ $operations \ word }
+{ $operations T{ vocab-link f "kernel" } }
 { $command-map interactor "quotation" }
 { $heading "Editing commands" }
 "The text editing commands are standard; see " { $link "gadgets-editors-commands" } "."
 { $heading "Implementation" }
 "Listeners are instances of " { $link listener-gadget } ". The listener consists of an output area (instance of " { $link pane } ") and an input area (instance of " { $link interactor } "). Clickable presentations can also be printed to the listener; see " { $link "ui-presentations" } "." ;
 
+TIP: "You can read documentation by pressing F1." ;
+
+TIP: "The listener tool remembers previous lines of input. Press " { $command interactor "completion" recall-previous } " and " { $command interactor "completion" recall-next } " to cycle through them." ;
+
+TIP: "When you mouse over certain objects, a block border will appear. Left-clicking on such an object will perform the default operation. Right-clicking will show a menu with all operations." ;
+
+TIP: "The status bar displays stack effects of recognized words as they are being typed in." ;
+
+TIP: "Press " { $command interactor "completion" code-completion-popup } " to complete word, vocabulary and Unicode character names. The latter two features become available if the cursor is after a " { $link POSTPONE: USE: } ", " { $link POSTPONE: USING: } " or " { $link POSTPONE: CHAR: } "." ;
+
+TIP: "If a word's vocabulary is loaded, but not in the search path, you can use restarts to add the vocabulary to the search path. Auto-use mode (" { $command listener-gadget "toolbar" com-auto-use } ") invokes restarts automatically if there is only one restart." ;
+
+TIP: "Scroll the listener from the keyboard by pressing " { $command listener-gadget "scrolling" com-page-up } " and " { $command listener-gadget "scrolling" com-page-down } "." ;
+
+TIP: "Press " { $command tool "common" refresh-all } " or run " { $link refresh-all } " to reload changed source files from disk. " ;
+
 ABOUT: "ui-listener"
\ No newline at end of file
index cd56dd876e6812f8c06a3d84a696980864a4bb88..986e1270ebbb34be2c397034f4600520b84aad57 100644 (file)
@@ -1,7 +1,7 @@
 USING: continuations documents
 ui.tools.listener hashtables kernel namespaces parser sequences
 tools.test ui.commands ui.gadgets ui.gadgets.editors
-ui.gadgets.panes vocabs words tools.test.ui slots.private
+ui.gadgets.panes vocabs words ui.gadgets.debug slots.private
 threads arrays generic threads accessors listener math
 calendar concurrency.promises io ui.tools.common ;
 IN: ui.tools.listener.tests
@@ -68,7 +68,7 @@ IN: ui.tools.listener.tests
 
 [ ] [ <interactor> <pane> <pane-stream> >>output "interactor" set ] unit-test
 
-: text "Hello world.\nThis is a test." ;
+CONSTANT: text "Hello world.\nThis is a test."
 
 [ ] [ text "interactor" get set-editor-string ] unit-test
 
index 4429f058f11dbdcae28bf5ef52d78d72d1a48a0e..7cb3c70cbc2de118de752be69697f5463fd4e78c 100644 (file)
@@ -2,12 +2,13 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs calendar combinators locals
 colors.constants combinators.short-circuit compiler.units
-concurrency.flags concurrency.mailboxes continuations destructors
-documents documents.elements fry hashtables help help.markup io
-io.styles kernel lexer listener math models models.delay models.arrow
-namespaces parser prettyprint quotations sequences strings threads
-tools.vocabs vocabs vocabs.loader vocabs.parser words debugger ui ui.commands
-ui.pens.solid ui.gadgets ui.gadgets.glass ui.gadgets.buttons ui.gadgets.editors
+help.tips concurrency.flags concurrency.mailboxes continuations
+destructors documents documents.elements fry hashtables help
+help.markup io io.styles kernel lexer listener math models
+models.delay models.arrow namespaces parser prettyprint quotations
+sequences strings threads tools.vocabs vocabs vocabs.loader
+vocabs.parser words debugger ui ui.commands ui.pens.solid ui.gadgets
+ui.gadgets.glass ui.gadgets.buttons ui.gadgets.editors
 ui.gadgets.labeled ui.gadgets.panes ui.gadgets.scrollers
 ui.gadgets.status-bar ui.gadgets.tracks ui.gadgets.borders ui.gestures
 ui.operations ui.tools.browser ui.tools.common ui.tools.debugger
@@ -84,6 +85,8 @@ M: interactor model-changed
         [ 2drop ] [ [ value>> ] dip show-summary ] if
     ] [ call-next-method ] if ;
 
+M: interactor stream-element-type drop +character+ ;
+
 GENERIC: (print-input) ( object -- )
 
 M: input (print-input)
@@ -260,8 +263,9 @@ M: listener-operation invoke-command ( target command -- )
 
 : listener-run-files ( seq -- )
     [
-        [ \ listener-run-files ] dip
-        '[ _ [ run-file ] each ] call-listener
+        '[ _ [ run-file ] each ]
+        \ listener-run-files
+        call-listener
     ] unless-empty ;
 
 : com-end ( listener -- )
@@ -352,16 +356,11 @@ interactor "completion" f {
     { T{ key-down f { C+ } "r" } history-completion-popup }
 } define-command-map
 
-: welcome. ( -- )
-    "If this is your first time with Factor, please read the " print
-    "handbook" ($link) ". To see a list of keyboard shortcuts," print
-    "press F1." print nl ;
-
 : listener-thread ( listener -- )
     dup listener-streams [
         [ com-browse ] help-hook set
         '[ [ _ input>> ] 2dip debugger-popup ] error-hook set
-        welcome.
+        tip-of-the-day. nl
         listener
     ] with-streams* ;
 
@@ -383,7 +382,7 @@ interactor "completion" f {
         [ wait-for-listener ]
     } cleave ;
 
-: listener-help ( -- ) "ui-listener" com-browse ;
+: listener-help ( -- ) "help.home" com-browse ;
 
 \ listener-help H{ { +nullary+ t } } define-command
 
diff --git a/basis/ui/tools/operations/operations-docs.factor b/basis/ui/tools/operations/operations-docs.factor
new file mode 100644 (file)
index 0000000..455e4f5
--- /dev/null
@@ -0,0 +1,8 @@
+USING: help.tips help.markup help.syntax ui.operations
+tools.walker tools.time tools.profiler ui.tools.operations ;
+
+TIP: "Press " { $operation com-stack-effect } " to print the stack effect of the code in the input field without executing it (" { $link "inference" } ")." ;
+
+TIP: "Press " { $operation walk } " to single-step through the code in the input field (" { $link "ui-walker" } ")." ;
+
+TIP: "Press " { $operation time } " to time execution of the code in the input field (" { $link "timing" } ")." ;
index 6d6cda1dba76af5aaf71a69d2a53b6c7445f6b9c..c6371ac8aaf3794e8f9eae2eb4a639f52e134bd7 100644 (file)
@@ -9,7 +9,7 @@ compiler.units accessors vocabs.parser macros.expander ui
 ui.tools.browser ui.tools.listener ui.tools.listener.completion
 ui.tools.profiler ui.tools.inspector ui.tools.traceback
 ui.commands ui.gadgets.editors ui.gestures ui.operations
-ui.tools.deploy models ;
+ui.tools.deploy models help.tips ;
 IN: ui.tools.operations
 
 ! Objects
@@ -81,8 +81,6 @@ IN: ui.tools.operations
     { +listener+ t }
 } define-operation
 
-UNION: definition word method-spec link vocab vocab-link ;
-
 [ definition? ] \ edit H{
     { +keyboard+ T{ key-down f { C+ } "e" } }
     { +listener+ t }
@@ -157,8 +155,6 @@ M: word com-stack-effect 1quotation com-stack-effect ;
     { +listener+ t }
 } define-operation
 
-: com-profile ( quot -- ) profile profiler-window ;
-
 [ quotation? ] \ com-profile H{
     { +keyboard+ T{ key-down f { C+ } "o" } }
     { +listener+ t }
diff --git a/basis/ui/tools/profiler/profiler-docs.factor b/basis/ui/tools/profiler/profiler-docs.factor
new file mode 100644 (file)
index 0000000..e2a0ef5
--- /dev/null
@@ -0,0 +1,11 @@
+IN: ui.tools.profiler
+USING: help.markup help.syntax ui.operations help.tips ;
+
+ARTICLE: "ui.tools.profiler" "UI profiler tool"
+"The " { $vocab-link "ui.tools.profiler" } " vocabulary implements a graphical tool for viewing profiling results (see " { $link "profiling" } ")."
+$nl
+"To use the profiler, enter a piece of code in the listener's input area and press " { $operation com-profile } "." ;
+
+TIP: "Press " { $operation com-profile } " to run the code in the input field with profiling enabled (" { $link "ui.tools.profiler" } ")." ;
+
+ABOUT: "ui.tools.profiler"
\ No newline at end of file
index bbd9237c872e256222865cdea0dae1f62a1c51db..1c2318a35e94328d30cdf8f41231591ebb638cc5 100644 (file)
@@ -208,4 +208,6 @@ profiler-gadget "toolbar" f {
 : profiler-window ( -- )
     <profiler-gadget> "Profiling results" open-status-window ;
 
-MAIN: profiler-window
\ No newline at end of file
+: com-profile ( quot -- ) profile profiler-window ;
+
+MAIN: profiler-window
index d3078cc1788de9027f7dc3908fb8e0064d531fde..52cd77d7263cdb656b02bad68248c59eca720dd1 100644 (file)
@@ -1,7 +1,8 @@
 USING: editors help.markup help.syntax summary inspector io io.styles
 listener parser prettyprint tools.profiler tools.walker ui.commands
 ui.gadgets.panes ui.gadgets.presentations ui.operations
-ui.tools.operations ui.tools.profiler ui.tools.common vocabs see ;
+ui.tools.operations ui.tools.profiler ui.tools.common vocabs see
+help.tips ;
 IN: ui.tools
 
 ARTICLE: "starting-ui-tools" "Starting the UI tools"
@@ -54,17 +55,23 @@ $nl
 
 ARTICLE: "ui-tools" "UI developer tools"
 "The " { $vocab-link "ui.tools" } " vocabulary hierarchy implements a collection of simple developer tools."
-$nl
+{ $subsection "starting-ui-tools" }
 "To take full advantage of the UI tools, you should be using a supported text editor. See " { $link "editor" } "."
+$nl
+"Common functionality:"
 { $subsection "ui-shortcuts" }
 { $subsection "ui-presentations" }
+{ $subsection "definitions.icons" }
+"Tools:"
 { $subsection "ui-listener" }
 { $subsection "ui-browser" }
 { $subsection "ui-inspector" }
-{ $subsection "ui-profiler" }
+{ $subsection "ui.tools.profiler" }
 { $subsection "ui-walker" }
 { $subsection "ui.tools.deploy" }
 "Platform-specific features:"
 { $subsection "ui-cocoa" } ;
 
+TIP: "All UI developer tools support a common set of " { $link "ui-shortcuts" } ". Each individual tool has its own shortcuts as well; the F1 key is context-sensitive." ;
+
 ABOUT: "ui-tools"
index 1f427d9405b8defa1fd33640c52a9fef4b528056..6728fb8338ecb155ee0d08c0bc7a44ea15327bd1 100644 (file)
@@ -105,5 +105,5 @@ walker-gadget "multitouch" f {
 
 [
     dup find-walker-window dup
-    [ raise-window 3drop ] [ drop [ walker-window ] with-ui ] if
+    [ raise-window 3drop ] [ drop '[ _ _ _ walker-window ] with-ui ] if
 ] show-walker-hook set-global
diff --git a/basis/ui/traverse/traverse-docs.factor b/basis/ui/traverse/traverse-docs.factor
new file mode 100644 (file)
index 0000000..e69de29
index e18637a652da2af05897f4f2f526237190266f62..4d2072db1c70e6448f6bedded25ec3f258fa4145 100644 (file)
@@ -62,4 +62,4 @@ M: object (flatten-tree) , ;
     { 0 1 } { 2 0 1 } { { "a" "b" "c" "d" } { "e" "f" "g" } { { "h" "i" } "j" } } gadgets-in-range
 ] unit-test
 
-[ { array children>> } forget ] with-compilation-unit
+[ M\ array children>> forget ] with-compilation-unit
index 63c656205c9d410fcc1a17b5d759aae3d82aa324..9df084210dfdacea63ab361169543653f64ac0d6 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors namespaces make sequences kernel math arrays io
-ui.gadgets generic combinators ;
+ui.gadgets generic combinators fry sets ;
 IN: ui.traverse
 
 TUPLE: node value children ;
@@ -85,3 +85,13 @@ M: node gadget-text*
 
 : gadget-at-path ( parent path -- gadget )
     [ swap nth-gadget ] each ;
+
+GENERIC# leaves* 1 ( tree assoc -- )
+
+M: node leaves* [ children>> ] dip leaves* ;
+
+M: array leaves* '[ _ leaves* ] each ;
+
+M: gadget leaves* conjoin ;
+
+: leaves ( tree -- assoc ) H{ } clone [ leaves* ] keep ;
\ No newline at end of file
index 42885aecb70c7bb6145a4757aa41200b36c62b8c..8be486cb1a32fc646f35aa7183d002dfb0974102 100644 (file)
@@ -1,11 +1,10 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays assocs io kernel math models namespaces make dlists
-deques sequences threads sequences words continuations init call
-combinators hashtables concurrency.flags sets accessors calendar fry
-destructors ui.gadgets ui.gadgets.private ui.gadgets.worlds
-ui.gadgets.tracks ui.gestures ui.backend ui.render ui.text
-ui.text.private ;
+deques sequences threads sequences words continuations init
+combinators combinators.short-circuit hashtables concurrency.flags
+sets accessors calendar fry destructors ui.gadgets ui.gadgets.private
+ui.gadgets.worlds ui.gadgets.tracks ui.gestures ui.backend ui.render ;
 IN: ui
 
 <PRIVATE
@@ -63,7 +62,7 @@ M: world graft*
 : (ungraft-world) ( world -- )
     {
         [ handle>> select-gl-context ]
-        [ text-handle>> dispose ]
+        [ text-handle>> [ dispose ] when* ]
         [ images>> [ dispose ] when* ]
         [ hand-clicked close-global ]
         [ hand-gadget close-global ]
@@ -95,8 +94,7 @@ M: world ungraft*
 : restore-world ( world -- )
     {
         [ reset-world ]
-        [ init-text-rendering ]
-        [ f >>images drop ]
+        [ f >>text-handle f >>images drop ]
         [ restore-gadget ]
     } cleave ;
 
@@ -119,12 +117,10 @@ M: world ungraft*
     gesture-queue [ send-queued-gesture notify-queued ] slurp-deque ;
 
 : update-ui ( -- )
-    [
-        notify-queued
-        layout-queued
-        redraw-worlds
-        send-queued-gestures
-    ] [ ui-error ] recover ;
+    notify-queued
+    layout-queued
+    redraw-worlds
+    send-queued-gestures ;
 
 SYMBOL: ui-thread
 
@@ -135,8 +131,7 @@ SYMBOL: ui-thread
 PRIVATE>
 
 : find-window ( quot -- world )
-    windows get values
-    [ gadget-child swap call ] with find-last nip ; inline
+    [ windows get values ] dip '[ gadget-child @ ] find-last nip ; inline
 
 : ui-running? ( -- ? )
     \ ui-running get-global ;
@@ -144,16 +139,22 @@ PRIVATE>
 <PRIVATE
 
 : update-ui-loop ( -- )
-    [ ui-running? ui-thread get-global self eq? and ]
-    [ ui-notify-flag get lower-flag update-ui ]
-    while ;
+    #! Note the logic: if update-ui fails, we open an error window
+    #! and run one iteration of update-ui. If that also fails, well,
+    #! the whole UI subsystem is broken so we exit out of the
+    #! update-ui-loop.
+    [ { [ ui-running? ] [ ui-thread get-global self eq? ] } 0&& ]
+    [
+        ui-notify-flag get lower-flag
+        [ update-ui ] [ ui-error update-ui ] recover
+    ] while ;
 
 : start-ui-thread ( -- )
     [ self ui-thread set-global update-ui-loop ]
     "UI update" spawn drop ;
 
 : start-ui ( quot -- )
-    call notify-ui-thread start-ui-thread ;
+    call( -- ) notify-ui-thread start-ui-thread ;
 
 : restore-windows ( -- )
     [
@@ -193,6 +194,6 @@ M: object close-window
 ] "ui" add-init-hook
 
 : with-ui ( quot -- )
-    ui-running? [ call ] [ '[ init-ui @ ] (with-ui) ] if ;
+    ui-running? [ call( -- ) ] [ '[ init-ui @ ] (with-ui) ] if ;
 
-HOOK: beep ui-backend ( -- )
\ No newline at end of file
+HOOK: beep ui-backend ( -- )
index 493c2db0c2c7fa2efcfde51dcb3d9b1652bcd18d..3a26b012139ffc5ed3a5e5db47e5fe7141421c8d 100644 (file)
@@ -9,6 +9,9 @@ IN: unicode.breaks.tests
 [ 3 ] [ "\u001112\u001161\u0011abA\u000300a"
         dup last-grapheme head last-grapheme ] unit-test
 
+[ 3 ] [ 2 "hello" first-grapheme-from ] unit-test
+[ 1 ] [ 2 "hello" last-grapheme-from ] unit-test
+
 : grapheme-break-test ( -- filename )
     "vocab:unicode/breaks/GraphemeBreakTest.txt" ;
 
index f2e94545455972ba712c954d1d714b01db6d6ff3..1b1d9434f83e7db961cdcf9c3815d91165c91cd4 100644 (file)
@@ -2,9 +2,11 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators.short-circuit unicode.categories kernel math
 combinators splitting sequences math.parser io.files io assocs
-arrays namespaces make math.ranges unicode.normalize.private values
-io.encodings.ascii unicode.syntax unicode.data compiler.units fry
-alien.syntax sets accessors interval-maps memoize locals words ;
+arrays namespaces make math.ranges unicode.normalize
+unicode.normalize.private values io.encodings.ascii
+unicode.data compiler.units fry unicode.categories.syntax
+alien.syntax sets accessors interval-maps memoize locals words
+simple-flat-file ;
 IN: unicode.breaks
 
 <PRIVATE
@@ -30,9 +32,9 @@ CATEGORY: grapheme-control Zl Zp Cc Cf ;
         [ drop Control ]
     } case ;
 
-CATEGORY: (extend) Me Mn ;
-: extend? ( ch -- ? )
-    { [ (extend)? ] [ "Other_Grapheme_Extend" property? ] } 1|| ;
+CATEGORY: extend
+    Me Mn |
+    "Other_Grapheme_Extend" property? ;
 
 : loe? ( ch -- ? )
     "Logical_Order_Exception" property? ;
@@ -58,7 +60,7 @@ SYMBOL: table
 : finish-table ( -- table )
     table get [ [ 1 = ] map ] map ;
 
-: eval-seq ( seq -- seq ) [ dup word? [ execute ] when ] map ;
+: eval-seq ( seq -- seq ) [ ?execute ] map ;
 
 : (set-table) ( class1 class2 val -- )
     [ table get nth ] dip '[ _ or ] change-nth ;
@@ -99,6 +101,16 @@ PRIVATE>
     [ grapheme-class [ nip ] [ grapheme-break? ] 2bi ] find drop
     nip swap length or 1+ ;
 
+: first-grapheme-from ( start str -- i )
+    over tail-slice first-grapheme + ;
+
+: last-grapheme ( str -- i )
+    unclip-last-slice grapheme-class swap
+    [ grapheme-class dup rot grapheme-break? ] find-last drop ?1+ nip ;
+
+: last-grapheme-from ( end str -- i )
+    swap head-slice last-grapheme ;
+
 <PRIVATE
 
 : >pieces ( str quot: ( str -- i ) -- graphemes )
@@ -112,10 +124,6 @@ PRIVATE>
 : string-reverse ( str -- rts )
     >graphemes reverse concat ;
 
-: last-grapheme ( str -- i )
-    unclip-last-slice grapheme-class swap
-    [ grapheme-class dup rot grapheme-break? ] find-last drop ?1+ nip ;
-
 <PRIVATE
 
 graphemes init-table table
@@ -126,7 +134,7 @@ to: grapheme-table
 
 VALUE: word-break-table
 
-"vocab:unicode/data/WordBreakProperty.txt" load-script
+"vocab:unicode/data/WordBreakProperty.txt" load-interval-file
 to: word-break-table
 
 C-ENUM: wOther wCR wLF wNewline wExtend wFormat wKatakana wALetter wMidLetter
index 52a8d9755eb2ef7a99afbe90b0816e2f1c8a07be..a76f5e78c408c3a1cd8c7955db87d9828d75dc7b 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008, 2009 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: unicode.case unicode.case.private tools.test namespaces strings unicode.normalize ;
+USING: unicode.case tools.test namespaces strings unicode.normalize
+unicode.case.private ;
 IN: unicode.case.tests
 
 \ >upper must-infer
index c75582dacd82a5497ca91c43fdaf391adaf91983..1ad39317469939c54b144961b84f3df21598c440 100644 (file)
@@ -1,18 +1,12 @@
 ! Copyright (C) 2008, 2009 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: unicode.data sequences namespaces
-sbufs make unicode.syntax unicode.normalize math hints
-unicode.categories combinators unicode.syntax assocs combinators.short-circuit
+sbufs make unicode.normalize math hints
+unicode.categories combinators assocs combinators.short-circuit
 strings splitting kernel accessors unicode.breaks fry locals ;
 QUALIFIED: ascii
 IN: unicode.case
 
-<PRIVATE
-: ch>lower ( ch -- lower ) simple-lower at-default ; inline
-: ch>upper ( ch -- upper ) simple-upper at-default ; inline
-: ch>title ( ch -- title ) simple-title at-default ; inline
-PRIVATE>
-
 SYMBOL: locale ! Just casing locale, or overall?
 
 <PRIVATE
@@ -86,7 +80,7 @@ SYMBOL: locale ! Just casing locale, or overall?
 :: map-case ( string string-quot char-quot -- case )
     string length <sbuf> :> out
     string [
-        dup special-casing at
+        dup special-case
         [ string-quot call out push-all ]
         [ char-quot call out push ] ?if
     ] each out "" like ; inline
index b0870e28fb881c90705b87383449d9bccada73bc..924b197417d74fa72ffa29dca29b85c3726e0fbc 100644 (file)
@@ -12,6 +12,9 @@ HELP: Letter
 HELP: alpha
 { $class-description "The class of alphanumeric characters." } ;
 
+HELP: math
+{ $class-description "The class of Unicode math characters." } ;
+
 HELP: blank
 { $class-description "The class of whitespace characters." } ;
 
@@ -54,6 +57,8 @@ ARTICLE: "unicode.categories" "Character classes"
 { $subsection uncased }
 { $subsection uncased? }
 { $subsection character }
-{ $subsection character? } ;
+{ $subsection character? }
+{ $subsection math }
+{ $subsection math? } ;
 
 ABOUT: "unicode.categories"
index e16125b6423349fe0d924aa21020476410658924..0970df7ad8c6618b55cdd5c3e09e2433ba2b3e13 100644 (file)
@@ -1,4 +1,7 @@
-USING: tools.test kernel unicode.categories words sequences unicode.syntax ;
+! Copyright (C) 2008 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test kernel unicode.categories words sequences unicode.data ;
+IN: unicode.categories.tests
 
 [ { f f t t f t t f f t } ] [ CHAR: A { 
     blank? letter? LETTER? Letter? digit? 
@@ -9,3 +12,8 @@ USING: tools.test kernel unicode.categories words sequences unicode.syntax ;
 [ "Lo" ] [ HEX: 3450 category ] unit-test
 [ "Lo" ] [ HEX: 4DB5 category ] unit-test
 [ "Cs" ] [ HEX: DD00 category ] unit-test
+[ t ] [ CHAR: \t blank? ] unit-test
+[ t ] [ CHAR: \s blank? ] unit-test
+[ t ] [ CHAR: \r blank? ] unit-test
+[ t ] [ CHAR: \n blank? ] unit-test
+[ f ] [ CHAR: a blank? ] unit-test
index 0464e31b125063b60fa21489d8865b055efd60b4..4ca5c9a90e74bbd9723b14277376a20f4a430654 100644 (file)
@@ -1,15 +1,16 @@
 ! Copyright (C) 2008 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: unicode.syntax ;
+USING: unicode.categories.syntax sequences unicode.data ;
 IN: unicode.categories
 
-CATEGORY: blank Zs Zl Zp \r\n ;
-CATEGORY: letter Ll ;
-CATEGORY: LETTER Lu ;
-CATEGORY: Letter Lu Ll Lt Lm Lo ;
+CATEGORY: blank Zs Zl Zp | "\r\n\t" member? ;
+CATEGORY: letter Ll | "Other_Lowercase" property? ;
+CATEGORY: LETTER Lu | "Other_Uppercase" property? ;
+CATEGORY: Letter Lu Ll Lt Lm Lo Nl ;
 CATEGORY: digit Nd Nl No ;
 CATEGORY-NOT: printable Cc Cf Cs Co Cn ;
-CATEGORY: alpha Lu Ll Lt Lm Lo Nd Nl No ;
+CATEGORY: alpha Lu Ll Lt Lm Lo Nd Nl No | "Other_Alphabetic" property? ;
 CATEGORY: control Cc ;
 CATEGORY-NOT: uncased Lu Ll Lt Lm Mn Me ; 
 CATEGORY-NOT: character Cn ;
+CATEGORY: math Sm | "Other_Math" property? ;
diff --git a/basis/unicode/categories/syntax/authors.txt b/basis/unicode/categories/syntax/authors.txt
new file mode 100755 (executable)
index 0000000..f990dd0
--- /dev/null
@@ -0,0 +1 @@
+Daniel Ehrenberg
diff --git a/basis/unicode/categories/syntax/summary.txt b/basis/unicode/categories/syntax/summary.txt
new file mode 100644 (file)
index 0000000..651d51c
--- /dev/null
@@ -0,0 +1 @@
+Parsing words used by Unicode implementation
diff --git a/basis/unicode/categories/syntax/syntax-docs.factor b/basis/unicode/categories/syntax/syntax-docs.factor
new file mode 100644 (file)
index 0000000..6293b92
--- /dev/null
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.syntax help.markup ;
+IN: unicode.categories.syntax
+
+ABOUT: "unicode.categories.syntax"
+
+ARTICLE: "unicode.categories.syntax" "Unicode category syntax"
+"There is special syntax sugar for making predicate classes which are unions of Unicode general categories, plus some other code."
+{ $subsection POSTPONE: CATEGORY: }
+{ $subsection POSTPONE: CATEGORY-NOT: } ;
+
+HELP: CATEGORY:
+{ $syntax "CATEGORY: foo Nl Pd Lu | \"Diacritic\" property? ;" }
+{ $description "This defines a predicate class which is a subset of code points. In this example, " { $snippet "foo" } " is the class of characters which are in the general category Nl or Pd or Lu, or which have the Diacritic property." } ;
+
+HELP: CATEGORY-NOT:
+{ $syntax "CATEGORY-NOT: foo Nl Pd Lu | \"Diacritic\" property? ;" }
+{ $description "This defines a predicate class which is a subset of code points, the complement of what " { $link POSTPONE: CATEGORY: } " would define. In this example, " { $snippet "foo" } " is the class of characters which are neither in the general category Nl or Pd or Lu, nor have the Diacritic property." } ;
diff --git a/basis/unicode/categories/syntax/syntax-tests.factor b/basis/unicode/categories/syntax/syntax-tests.factor
new file mode 100644 (file)
index 0000000..1ec622f
--- /dev/null
@@ -0,0 +1,3 @@
+! Copyright (C) 2009 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+
diff --git a/basis/unicode/categories/syntax/syntax.factor b/basis/unicode/categories/syntax/syntax.factor
new file mode 100644 (file)
index 0000000..849f361
--- /dev/null
@@ -0,0 +1,34 @@
+! Copyright (C) 2008, 2009 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: unicode.data kernel math sequences parser unicode.data.private
+bit-arrays namespaces sequences.private arrays classes.parser
+assocs classes.predicate sets fry splitting accessors ;
+IN: unicode.categories.syntax
+
+! For use in CATEGORY:
+SYMBOLS: Cn Lu Ll Lt Lm Lo Mn Mc Me Nd Nl No Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So Zs Zl Zp Cc Cf Cs Co | ;
+
+<PRIVATE
+
+: [category] ( categories code -- quot )
+    '[ dup category# _ member? [ drop t ] _ if ] ;
+
+: integer-predicate-class ( word predicate -- )
+    integer swap define-predicate-class ;
+
+: define-category ( word categories code -- )
+    [category] integer-predicate-class ;
+
+: define-not-category ( word categories code -- )
+    [category] [ not ] compose integer-predicate-class ;
+
+: parse-category ( -- word tokens quot )
+    CREATE-CLASS \ ; parse-until { | } split1
+    [ [ name>> categories-map at ] map ]
+    [ [ [ ] like ] [ [ drop f ] ] if* ] bi* ;
+
+PRIVATE>
+
+SYNTAX: CATEGORY: parse-category define-category ;
+
+SYNTAX: CATEGORY-NOT: parse-category define-not-category ;
diff --git a/basis/unicode/categories/syntax/tags.txt b/basis/unicode/categories/syntax/tags.txt
new file mode 100755 (executable)
index 0000000..8e27be7
--- /dev/null
@@ -0,0 +1 @@
+text
index 2a94d501bdce30de81e10bc4db287f554760ce80..b6eddccae074f7257f9226af3e3f217c6b02bb5e 100755 (executable)
@@ -4,8 +4,8 @@ USING: combinators.short-circuit sequences io.files
 io.encodings.ascii kernel values splitting accessors math.parser\r
 ascii io assocs strings math namespaces make sorting combinators\r
 math.order arrays unicode.normalize unicode.data locals\r
-unicode.syntax macros sequences.deep words unicode.breaks\r
-quotations combinators.short-circuit ;\r
+macros sequences.deep words unicode.breaks\r
+quotations combinators.short-circuit simple-flat-file ;\r
 IN: unicode.collation\r
 \r
 <PRIVATE\r
@@ -20,13 +20,11 @@ TUPLE: weight primary secondary tertiary ignorable? ;
         [ >>primary ] [ >>secondary ] [ >>tertiary ] tri*\r
     ] map ;\r
 \r
-: parse-line ( line -- code-poing weight )\r
-    ";" split1 [ [ blank? ] trim ] bi@\r
-    [ " " split [ hex> ] "" map-as ] [ parse-weight ] bi* ;\r
+: parse-keys ( string -- chars )\r
+    " " split [ hex> ] "" map-as ;\r
 \r
 : parse-ducet ( file -- ducet )\r
-    ascii file-lines filter-comments\r
-    [ parse-line ] H{ } map>assoc ;\r
+    data [ [ parse-keys ] [ parse-weight ] bi* ] H{ } assoc-map-as ;\r
 \r
 "vocab:unicode/collation/allkeys.txt" parse-ducet to: ducet\r
 \r
index 55fed313866d753fc60ea61dbd261d4c6b3d7b8a..82706729bf94ee7e2ed6ea97e5a13ab0b63b8517 100644 (file)
@@ -1,22 +1,24 @@
+! Copyright (C) 2009 Daniel Ehrenberg
+! See http://factorcode.org/license.txt for BSD license.
 USING: help.syntax help.markup strings ;
 IN: unicode.data
 
 ABOUT: "unicode.data"
 
 ARTICLE: "unicode.data" "Unicode data tables"
-"The " { $vocab-link "unicode.data" "unicode.data" } " vocabulary contains core Unicode data tables and code for parsing this from files."
-{ $subsection load-script }
+"The " { $vocab-link "unicode.data" "unicode.data" } " vocabulary contains core Unicode data tables and code for parsing this from files. The following words access these data tables."
 { $subsection canonical-entry }
 { $subsection combine-chars }
 { $subsection combining-class }
 { $subsection non-starter? }
 { $subsection name>char }
 { $subsection char>name }
-{ $subsection property? } ;
-
-HELP: load-script
-{ $values { "filename" string } { "table" "an interval map" } }
-{ $description "This loads a file that looks like Script.txt in the Unicode Character Database and converts it into an efficient interval map, where the keys are characters and the values are strings for the properties." } ;
+{ $subsection property? }
+{ $subsection category }
+{ $subsection ch>upper }
+{ $subsection ch>lower } 
+{ $subsection ch>title } 
+{ $subsection special-case } ;
 
 HELP: canonical-entry
 { $values { "char" "a code point" } { "seq" string } }
@@ -49,3 +51,23 @@ HELP: name>char
 HELP: property?
 { $values { "char" "a code point" } { "property" string } { "?" "a boolean" } }
 { $description "Tests whether the code point is listed under the given property in PropList.txt in the Unicode Character Database." } ;
+
+HELP: category
+{ $values { "char" "a code point" } { "category" string } }
+{ $description "Returns the general category of a code point, in the form of a string. This will always be a string within the ASCII range of length two. If the code point is unassigned, then it returns " { $snippet "Cn" } "." } ;
+
+HELP: ch>upper
+{ $values { "ch" "a code point" } { "upper" "a code point" } }
+{ $description "Returns the simple upper-cased version of the code point, if it exists. This does not handle context-sensitive or locale-dependent properties of linguistically accurate case conversion, and does not correctly handle characters which become multiple characters on conversion to this case." } ;
+
+HELP: ch>lower
+{ $values { "ch" "a code point" } { "lower" "a code point" } }
+{ $description "Returns the simple lower-cased version of the code point, if it exists. This does not handle context-sensitive or locale-dependent properties of linguistically accurate case conversion, and does not correctly handle characters which become multiple characters on conversion to this case." } ;
+
+HELP: ch>title
+{ $values { "ch" "a code point" } { "title" "a code point" } }
+{ $description "Returns the simple title-cased version of the code point, if it exists. This does not handle context-sensitive or locale-dependent properties of linguistically accurate case conversion, and does not correctly handle characters which become multiple characters on conversion to this case." } ;
+
+HELP: special-case
+{ $values { "ch" "a code point" } { "casing-tuple" { "a tuple, or " { $link f } } } }
+{ $description "If a code point has special casing behavior, returns a tuple which represents that information." } ;
index bff4ddeaab3856507e3606cc52aaf08e4f44aead..779ae64d485b3ee293c251183b5217d697a995df 100644 (file)
@@ -1,13 +1,15 @@
-! Copyright (C) 2008 Daniel Ehrenberg.
+! Copyright (C) 2008, 2009 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators.short-circuit assocs math kernel sequences
 io.files hashtables quotations splitting grouping arrays io
 math.parser hash2 math.order byte-arrays words namespaces words
 compiler.units parser io.encodings.ascii values interval-maps
 ascii sets combinators locals math.ranges sorting make
-strings.parser io.encodings.utf8 ;
+strings.parser io.encodings.utf8 memoize simple-flat-file ;
 IN: unicode.data
 
+<PRIVATE
+
 VALUE: simple-lower
 VALUE: simple-upper
 VALUE: simple-title
@@ -16,35 +18,69 @@ VALUE: combine-map
 VALUE: class-map
 VALUE: compatibility-map
 VALUE: category-map
-VALUE: name-map
 VALUE: special-casing
 VALUE: properties
 
-: canonical-entry ( char -- seq ) canonical-map at ;
-: combine-chars ( a b -- char/f ) combine-map hash2 ;
-: compatibility-entry ( char -- seq ) compatibility-map at  ;
-: combining-class ( char -- n ) class-map at ;
-: non-starter? ( char -- ? ) combining-class { 0 f } member? not ;
-: name>char ( name -- char ) name-map at ;
-: char>name ( char -- name ) name-map value-at ;
-: property? ( char property -- ? ) properties at interval-key? ;
+PRIVATE>
 
-! Loading data from UnicodeData.txt
+VALUE: name-map
 
-: split-; ( line -- array )
-    ";" split [ [ blank? ] trim ] map ;
+: canonical-entry ( char -- seq ) canonical-map at ; inline
+: combine-chars ( a b -- char/f ) combine-map hash2 ; inline
+: compatibility-entry ( char -- seq ) compatibility-map at ; inline
+: combining-class ( char -- n ) class-map at ; inline
+: non-starter? ( char -- ? ) combining-class { 0 f } member? not ; inline
+: name>char ( name -- char ) name-map at ; inline
+: char>name ( char -- name ) name-map value-at ; inline
+: property? ( char property -- ? ) properties at interval-key? ; inline
+: ch>lower ( ch -- lower ) simple-lower at-default ; inline
+: ch>upper ( ch -- upper ) simple-upper at-default ; inline
+: ch>title ( ch -- title ) simple-title at-default ; inline
+: special-case ( ch -- casing-tuple ) special-casing at ; inline
 
-: data ( filename -- data )
-    ascii file-lines [ split-; ] map ;
+! For non-existent characters, use Cn
+CONSTANT: categories
+    { "Cn"
+      "Lu" "Ll" "Lt" "Lm" "Lo"
+      "Mn" "Mc" "Me"
+      "Nd" "Nl" "No"
+      "Pc" "Pd" "Ps" "Pe" "Pi" "Pf" "Po"
+      "Sm" "Sc" "Sk" "So"
+      "Zs" "Zl" "Zp"
+      "Cc" "Cf" "Cs" "Co" }
+
+<PRIVATE
+
+MEMO: categories-map ( -- hashtable )
+    categories <enum> [ swap ] H{ } assoc-map-as ;
+
+CONSTANT: num-chars HEX: 2FA1E
+
+PRIVATE>
+
+: category# ( char -- n )
+    ! There are a few characters that should be Cn
+    ! that this gives Cf or Mn
+    ! Cf = 26; Mn = 5; Cn = 29
+    ! Use a compressed array instead?
+    dup category-map ?nth [ ] [
+        dup HEX: E0001 HEX: E007F between?
+        [ drop 26 ] [
+            HEX: E0100 HEX: E01EF between?  5 29 ?
+        ] if
+    ] ?if ;
+
+: category ( char -- category )
+    category# categories nth ;
+
+<PRIVATE
+
+! Loading data from UnicodeData.txt
 
 : load-data ( -- data )
     "vocab:unicode/data/UnicodeData.txt" data ;
 
-: filter-comments ( lines -- lines )
-    [ "#@" split first ] map harvest ;
-
 : (process-data) ( index data -- newdata )
-    filter-comments
     [ [ nth ] keep first swap ] with { } map>assoc
     [ [ hex> ] dip ] assoc-map ;
 
@@ -97,19 +133,6 @@ VALUE: properties
     [ nip zero? not ] assoc-filter
     >hashtable ;
 
-! For non-existent characters, use Cn
-CONSTANT: categories
-    { "Cn"
-      "Lu" "Ll" "Lt" "Lm" "Lo"
-      "Mn" "Mc" "Me"
-      "Nd" "Nl" "No"
-      "Pc" "Pd" "Ps" "Pe" "Pi" "Pf" "Po"
-      "Sm" "Sc" "Sk" "So"
-      "Zs" "Zl" "Zp"
-      "Cc" "Cf" "Cs" "Co" }
-
-CONSTANT: num-chars HEX: 2FA1E
-
 ! the maximum unicode char in the first 3 planes
 
 : ?set-nth ( val index seq -- )
@@ -124,10 +147,10 @@ CONSTANT: num-chars HEX: 2FA1E
     ] assoc-each table ;
 
 :: process-category ( data -- category-listing )
-    [let | table [ num-chars <byte-array> ] |
-        2 data (process-data) [| char cat |
-            cat categories index char table ?set-nth
-        ] assoc-each table fill-ranges ] ;
+    num-chars <byte-array> :> table
+    2 data (process-data) [| char cat |
+        cat categories-map at char table ?set-nth
+    ] assoc-each table fill-ranges ;
 
 : process-names ( data -- names-hash )
     1 swap (process-data) [
@@ -137,24 +160,26 @@ CONSTANT: num-chars HEX: 2FA1E
 : multihex ( hexstring -- string )
     " " split [ hex> ] map sift ;
 
+PRIVATE>
+
 TUPLE: code-point lower title upper ;
 
 C: <code-point> code-point
 
+<PRIVATE
+
 : set-code-point ( seq -- )
     4 head [ multihex ] map first4
     <code-point> swap first set ;
 
 ! Extra properties
-: properties-lines ( -- lines )
-    "vocab:unicode/data/PropList.txt"
-    ascii file-lines ;
-
 : parse-properties ( -- {{[a,b],prop}} )
-    properties-lines filter-comments [
-        split-; first2
-        [ ".." split1 [ dup ] unless* [ hex> ] bi@ 2array ] dip
-    ] { } map>assoc ;
+    "vocab:unicode/data/PropList.txt" data [
+        [
+            ".." split1 [ dup ] unless*
+            [ hex> ] bi@ 2array
+        ] dip
+    ] assoc-map ;
 
 : properties>intervals ( properties -- assoc[str,interval] )
     dup values prune [ f ] H{ } map>assoc
@@ -192,33 +217,5 @@ load-special-casing to: special-casing
 
 load-properties to: properties
 
-! Utility to load resource files that look like Scripts.txt
-
-SYMBOL: interned
-
-: parse-script ( filename -- assoc )
-    ! assoc is code point/range => name
-    ascii file-lines filter-comments [ split-; ] map ;
-
-: range, ( value key -- )
-    swap interned get
-    [ = ] with find nip 2array , ;
-
-: expand-ranges ( assoc -- interval-map )
-    [
-        [
-            swap CHAR: . over member? [
-                ".." split1 [ hex> ] bi@ 2array
-            ] [ hex> ] if range,
-        ] assoc-each
-    ] { } make <interval-map> ;
-
-: process-script ( ranges -- table )
-    dup values prune interned
-    [ expand-ranges ] with-variable ;
-
-: load-script ( filename -- table )
-    parse-script process-script ;
-
 [ name>char [ "Invalid character" throw ] unless* ]
 name>char-hook set-global
index f3ecb96af97dc72c1d17fd4f96b9dd22d3531a38..f774016272168f8771670543a5ec4cf822877137 100644 (file)
@@ -1,5 +1,5 @@
 USING: unicode.normalize kernel tools.test sequences
-unicode.data io.encodings.utf8 io.files splitting math.parser
+simple-flat-file io.encodings.utf8 io.files splitting math.parser
 locals math quotations assocs combinators unicode.normalize.private ;
 IN: unicode.normalize.tests
 
@@ -23,9 +23,8 @@ IN: unicode.normalize.tests
 [ "\u00d55c" ] [ "\u001112\u001161\u0011ab" nfc ] unit-test
 
 : parse-test ( -- tests )
-    "vocab:unicode/normalize/NormalizationTest.txt"
-    utf8 file-lines filter-comments
-    [ ";" split 5 head [ " " split [ hex> ] "" map-as ] map ] map ;
+    "vocab:unicode/normalize/NormalizationTest.txt" data
+    [ 5 head [ " " split [ hex> ] "" map-as ] map ] map ;
 
 :: assert= ( test spec quot -- )
     spec [
index 602d9555ea64c26d775f0057cd8b3140b0f1c43f..aca96a56942c315303dc84afd4c52a9061883c7c 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: ascii sequences namespaces make unicode.data kernel math arrays
 locals sorting.insertion accessors assocs math.order combinators
-unicode.syntax strings sbufs hints combinators.short-circuit vectors ;
+strings sbufs hints combinators.short-circuit vectors ;
 IN: unicode.normalize
 
 <PRIVATE
index 6612825c21eb971f833ee9783df862e62041f8ec..2860f83befd02f51143800755f324501859e9165 100644 (file)
@@ -1,6 +1,14 @@
-USING: help.syntax help.markup ;\r
+! Copyright (C) 2009 Daniel Ehrenberg\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: help.syntax help.markup strings ;\r
 IN: unicode.script\r
 \r
+ABOUT: "unicode.script"\r
+\r
+ARTICLE: "unicode.script" "Unicode script properties"\r
+"The unicode standard gives every character a script. Note that this is different from a language, and that it is non-trivial to detect language from a string. To get the script of a character, use"\r
+{ $subsection script-of } ;\r
+\r
 HELP: script-of\r
-{ $values { "char" "a code point" } { "script" "a symbol" } }\r
-{ $description "Gets a symbol representing the code point of a given character. The word name of the symbol is the same as the one " } ;\r
+{ $values { "char" "a code point" } { "script" string } }\r
+{ $description "Finds the script of the given Unicode code point, represented as a string." } ;\r
index 383f9e3de3ca4c225325af461283327d29e1f888..4243c816234ffb5de1eb0c5d642b243ff426c380 100644 (file)
@@ -1,16 +1,16 @@
 ! Copyright (C) 2008 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors values kernel sequences assocs io.files
-io.encodings ascii math.ranges io splitting math.parser
-namespaces make byte-arrays locals math sets io.encodings.ascii
-words words.symbol compiler.units arrays interval-maps
-unicode.data ;
+USING: values interval-maps simple-flat-file ;
 IN: unicode.script
 
+<PRIVATE
+
 VALUE: script-table
 
-"vocab:unicode/script/Scripts.txt" load-script
+"vocab:unicode/script/Scripts.txt" load-interval-file
 to: script-table
 
+PRIVATE>
+
 : script-of ( char -- script )
     script-table interval-at ;
diff --git a/basis/unicode/syntax/authors.txt b/basis/unicode/syntax/authors.txt
deleted file mode 100755 (executable)
index f990dd0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Daniel Ehrenberg
diff --git a/basis/unicode/syntax/summary.txt b/basis/unicode/syntax/summary.txt
deleted file mode 100644 (file)
index 651d51c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Parsing words used by Unicode implementation
diff --git a/basis/unicode/syntax/syntax.factor b/basis/unicode/syntax/syntax.factor
deleted file mode 100644 (file)
index b7ac022..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-! Copyright (C) 2008 Daniel Ehrenberg.
-! See http://factorcode.org/license.txt for BSD license.
-USING: unicode.data kernel math sequences parser lexer
-bit-arrays namespaces make sequences.private arrays quotations
-assocs classes.predicate math.order strings.parser ;
-IN: unicode.syntax
-
-! Character classes (categories)
-
-: category# ( char -- category )
-    ! There are a few characters that should be Cn
-    ! that this gives Cf or Mn
-    ! Cf = 26; Mn = 5; Cn = 29
-    ! Use a compressed array instead?
-    dup category-map ?nth [ ] [
-        dup HEX: E0001 HEX: E007F between?
-        [ drop 26 ] [
-            HEX: E0100 HEX: E01EF between?  5 29 ?
-        ] if
-    ] ?if ;
-
-: category ( char -- category )
-    category# categories nth ;
-
-: >category-array ( categories -- bitarray )
-    categories [ swap member? ] with map >bit-array ;
-
-: as-string ( strings -- bit-array )
-    concat unescape-string ;
-
-: [category] ( categories -- quot )
-    [
-        [ [ categories member? not ] filter as-string ] keep 
-        [ categories member? ] filter >category-array
-        [ dup category# ] % , [ nth-unsafe [ drop t ] ] %
-        \ member? 2array >quotation ,
-        \ if ,
-    ] [ ] make ;
-
-: define-category ( word categories -- )
-    [category] integer swap define-predicate-class ;
-
-: CATEGORY:
-    CREATE ";" parse-tokens define-category ; parsing
-
-: seq-minus ( seq1 seq2 -- diff )
-    [ member? not ] curry filter ;
-
-: CATEGORY-NOT:
-    CREATE ";" parse-tokens
-    categories swap seq-minus define-category ; parsing
diff --git a/basis/unicode/syntax/tags.txt b/basis/unicode/syntax/tags.txt
deleted file mode 100755 (executable)
index 8e27be7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-text
index 4ae326ac84bf3429c33edb0960b4856fff625277..56432585c0fac349dc4840d5e847df9db8df9cdd 100644 (file)
@@ -1,7 +1,7 @@
 USING: help.markup help.syntax strings ;
 IN: unicode
 
-ARTICLE: "unicode" "Unicode"
+ARTICLE: "unicode" "Unicode support"
 "The " { $vocab-link "unicode" } " vocabulary and its sub-vocabularies implement support for the Unicode 5.1 character set."
 $nl
 "The Unicode character set contains most of the world's writing systems. Unicode is intended as a replacement for, and is a superset of, such legacy character sets as ASCII, Latin1, MacRoman, and so on. Unicode characters are called " { $emphasis "code points" } "; Factor's " { $link "strings" } " are sequences of code points."
@@ -15,7 +15,7 @@ $nl
 { $vocab-subsection "Word and grapheme breaks" "unicode.breaks" }
 { $vocab-subsection "Unicode normalization" "unicode.normalize" }
 "The following are mostly for internal use:"
-{ $vocab-subsection "Unicode syntax" "unicode.syntax" }
+{ $vocab-subsection "Unicode category syntax" "unicode.categories.syntax" }
 { $vocab-subsection "Unicode data tables" "unicode.data" }
 { $see-also "ascii" "io.encodings" } ;
 
index 87b1812ef8dccf3c4700a90a862c4fdf7e45532c..78e31a764df16020d3debd71f959eb7cd8ce17b4 100644 (file)
@@ -26,3 +26,7 @@ USING: urls.encoding tools.test arrays kernel assocs present accessors ;
 [ H{ { "text" "hello world" } } ] [ "text=hello+world" query>assoc ] unit-test
 
 [ "a=3" ] [ { { "a" 3 } } assoc>query ] unit-test
+
+[ "a" ] [ { { "a" f } } assoc>query ] unit-test
+
+[ H{ { "a" f } } ] [ "a" query>assoc ] unit-test
\ No newline at end of file
index f9dc64485d20c4574986c1d9c4c383fb6aedbc13..a5f5d62bfc885984865546e49157788f12cf6165 100644 (file)
@@ -96,6 +96,15 @@ PRIVATE>
         ] when*
     ] 2keep set-at ;
 
+: assoc-strings ( assoc -- assoc' )
+    [
+        {
+            { [ dup not ] [ ] }
+            { [ dup array? ] [ [ present ] map ] }
+            [ present 1array ]
+        } cond
+    ] assoc-map ;
+
 PRIVATE>
 
 : query>assoc ( query -- assoc )
@@ -110,11 +119,8 @@ PRIVATE>
 
 : assoc>query ( assoc -- str )
     [
-        dup array? [ [ present ] map ] [ present 1array ] if
-    ] assoc-map
-    [
-        [
+        assoc-strings [
             [ url-encode ] dip
-            [ url-encode "=" glue , ] with each
+            [ [ url-encode "=" glue , ] with each ] [ , ] if*
         ] assoc-each
     ] { } make "&" join ;
index 59fb79e8d35c5c39f406836d9a537e09fe6a9f35..35e428c8fa30005b650b03c0ff21bd2686fe2e4c 100644 (file)
@@ -1,6 +1,9 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel present prettyprint.custom prettyprint.backend urls ;
+USING: kernel present prettyprint.custom prettyprint.sections
+prettyprint.backend urls ;
 IN: urls.prettyprint
 
-M: url pprint* dup present "URL\" " "\"" pprint-string ;
+M: url pprint*
+    \ URL" record-vocab
+    dup present "URL\" " "\"" pprint-string ;
index 437a9419e39131a2b67d6c33974b97b243cc0312..eb8e452ca4a628d16ef6b329639dab7dbe46493b 100644 (file)
@@ -65,9 +65,8 @@ HELP: derive-url
 } ;
 
 HELP: ensure-port
-{ $values { "url" url } }
-{ $description "If the URL does not specify a port number, fill in the default for the URL's protocol. If the protocol is unknown, the port number is not changed." }
-{ $side-effects "url" }
+{ $values { "url" url } { "url'" url } }
+{ $description "If the URL does not specify a port number, create a new URL which is equal except the port number is set to the default for the URL's protocol. If the protocol is unknown, outputs an exact copy of the input URL." }
 { $examples
     { $example
         "USING: accessors prettyprint urls ;"
@@ -82,9 +81,9 @@ HELP: parse-host
 { $notes "This word is used by " { $link >url } ". It can also be used directly to parse " { $snippet "host:port" } " strings which are not full URLs." }
 { $examples
     { $example
-        "USING: prettyprint urls kernel ;"
-        "\"sbcl.org:80\" parse-host .s 2drop"
-        "\"sbcl.org\"\n80"
+        "USING: arrays kernel prettyprint urls ;"
+        "\"sbcl.org:80\" parse-host 2array ."
+        "{ \"sbcl.org\" 80 }"
     }
 } ;
 
index cac206bf3cc8cfe44e39c2c84a5e5c232411127e..f2ecd6ec6921d0ecf6e6883e7b875c52865cd482 100644 (file)
@@ -1,8 +1,8 @@
 IN: urls.tests
-USING: urls urls.private tools.test
+USING: urls urls.private tools.test prettyprint
 arrays kernel assocs present accessors ;
 
-: urls
+CONSTANT: urls
     {
         {
             T{ url
@@ -80,7 +80,16 @@ arrays kernel assocs present accessors ;
             }
             "ftp://slava:secret@ftp.kernel.org/"
         }
-    } ;
+        {
+            T{ url
+               { protocol "http" }
+               { host "foo.com" }
+               { path "/" }
+               { query H{ { "a" f } } }
+            }
+            "http://foo.com/?a"
+        }
+    }
 
 urls [
     [ 1array ] [ [ >url ] curry ] bi* unit-test
@@ -227,3 +236,5 @@ urls [
 [ "http://localhost/?foo=bar" >url ] unit-test
 
 [ "/" ] [ "http://www.jedit.org" >url path>> ] unit-test
+
+[ "USING: urls ;\nURL\" foo\"" ] [ URL" foo" unparse-use ] unit-test
\ No newline at end of file
index d71ce4ef7b992a3791f76975e8fe4edee36c67ba..1e886ae3e26e1e6fac90f75bb175640023d031d9 100644 (file)
@@ -175,11 +175,11 @@ PRIVATE>
     ] [ protocol>> ] bi
     secure-protocol? [ >secure-addr ] when ;
 
-: ensure-port ( url -- url )
-    dup protocol>> '[ _ protocol-port or ] change-port ;
+: ensure-port ( url -- url' )
+    clone dup protocol>> '[ _ protocol-port or ] change-port ;
 
 ! Literal syntax
-: URL" lexer get skip-blank parse-string >url parsed ; parsing
+SYNTAX: URL" lexer get skip-blank parse-string >url parsed ;
 
 USING: vocabs vocabs.loader ;
 
index df38869fbf35ae52a5f5cb53555a848172580df1..7c96f19ac9fd40830464f1a890a36c3fe421effa 100644 (file)
@@ -2,7 +2,7 @@ USING: help.markup help.syntax ;
 IN: values\r
 \r
 ARTICLE: "values" "Global values"\r
-"Usually, dynamically scoped variables are sufficient for holding data which is not literal. But occasionally, for global information that's calculated just once, it's useful to use the word mechanism instead, and set the word to the appropriate value just once. The " { $vocab-link "values" } " vocabulary implements " { $emphasis "values" } ", which abstract over this concept. To create a new word as a value, use the following syntax:"\r
+"Usually, dynamically-scoped variables subsume global variables and are sufficient for holding global data. But occasionally, for global information that's calculated just once and must be accessed more rapidly than a dynamic variable lookup can provide, it's useful to use the word mechanism instead, and set a word to the appropriate value just once. The " { $vocab-link "values" } " vocabulary implements " { $emphasis "values" } ", which abstract over this concept. To create a new word as a value, use the following syntax:"\r
 { $subsection POSTPONE: VALUE: }\r
 "To get the value, just call the word. The following words manipulate values:"\r
 { $subsection get-value }\r
index 75a37339b1797c60bcab6b6c8663b6dab74f5b8f..b15dcebe491ea0d76494815433a76c1651360e17 100644 (file)
@@ -30,11 +30,11 @@ PREDICATE: value-word < word
         [ second \ obj>> = ]
     } 1&& ;
 
-: VALUE:
+SYNTAX: VALUE:
     CREATE-WORD
     dup t "no-def-strip" set-word-prop
     T{ value-holder } clone [ obj>> ] curry
-    (( -- value )) define-declared ; parsing
+    (( -- value )) define-declared ;
 
 M: value-word definer drop \ VALUE: f ;
 
@@ -43,9 +43,9 @@ M: value-word definition drop f ;
 : set-value ( value word -- )
     def>> first (>>obj) ;
 
-: to:
+SYNTAX: to:
     scan-word literalize parsed
-    \ set-value parsed ; parsing
+    \ set-value parsed ;
 
 : get-value ( word -- value )
     def>> first obj>> ;
index e4f64ca8f80c42119c766b815d82d2b7e73ed0c4..ae106cbf93b9dfbb3ce2ada86972815320dfaac2 100644 (file)
@@ -50,7 +50,7 @@ M: vlist like
 
 INSTANCE: vlist immutable-sequence
 
-: VL{ \ } [ >vlist ] parse-literal ; parsing
+SYNTAX: VL{ \ } [ >vlist ] parse-literal ;
 
 M: vlist pprint-delims drop \ VL{ \ } ;
 M: vlist >pprint-sequence ;
@@ -87,7 +87,7 @@ M: valist assoc-like
 
 INSTANCE: valist assoc
 
-: VA{ \ } [ >valist ] parse-literal ; parsing
+SYNTAX: VA{ \ } [ >valist ] parse-literal ;
 
 M: valist pprint-delims drop \ VA{ \ } ;
 M: valist >pprint-sequence >alist ;
index 948612b2b2122c28824ab3bbd4140f12a80630e1..ff6a9ad4fcb4eeaeca9c7a429f230227bd07b961 100644 (file)
@@ -1,4 +1,4 @@
-USING: alien sequences ;
+USING: alien sequences alien.libraries ;
 {
     { "advapi32" "\\windows\\coredll.dll" "stdcall" }
     { "gdi32"    "\\windows\\coredll.dll" "stdcall" }
@@ -10,6 +10,5 @@ USING: alien sequences ;
     { "libm"     "\\windows\\coredll.dll" "stdcall"   }
     ! { "gl"       "libGLES_CM.dll"         "stdcall" }
     ! { "glu"      "libGLES_CM.dll"         "stdcall" }
-    ! { "freetype" "libfreetype-6.dll"      "stdcall" }
     { "ole32"    "ole32.dll"    "stdcall" }
 } [ first3 add-library ] each
index 620b608afc6297a616240a3144e17a67f1b35133..59a76bf4d7df97a763d6f22af27a063eae6f4a0f 100755 (executable)
@@ -90,14 +90,13 @@ unless
 
 PRIVATE>
 
-: COM-INTERFACE:
+SYNTAX: COM-INTERFACE:
     scan
     scan find-com-interface-definition
     scan string>guid
     parse-com-functions
     <com-interface-definition>
     dup save-com-interface-definition
-    define-words-for-com-interface
-    ; parsing
+    define-words-for-com-interface ;
 
-: GUID: scan string>guid parsed ; parsing
+SYNTAX: GUID: scan string>guid parsed ;
index 314fb167e3172520fb247762c3d8aa75879f1b98..cd1033d41870b4f0085d9b1160751cd88a9fef9a 100755 (executable)
@@ -832,7 +832,7 @@ SYMBOLS:
     define-keyboard-format-constant
     define-hid-keyboard-format-constant ;
 
-: define-constants
+: define-constants ( -- )
     define-guid-constants
     define-format-constants ;
 
index 1cd22beb75d5da6a84ebc27ad2df94bbfecc8d28..20a54dff9884ca6eb94205c9d2e9b0b262e6a95a 100755 (executable)
@@ -2,12 +2,6 @@ USING: windows.kernel32 windows.ole32 windows.com windows.com.syntax
 alien alien.c-types alien.syntax kernel system namespaces math ;
 IN: windows.dinput
 
-<<
-    os windows?
-    [ "dinput" "dinput8.dll" "stdcall" add-library ]
-    when
->>
-
 LIBRARY: dinput
 
 TYPEDEF: void* LPDIENUMDEVICESCALLBACKW
@@ -27,15 +21,15 @@ TYPEDEF: void* LPDIENUMEFFECTSCALLBACKW
     [ "BOOL" { "LPCDIEFFECTINFOW" "LPVOID" } "stdcall" ]
     dip alien-callback ; inline
 TYPEDEF: void* LPDIENUMCREATEDEFFECTOBJECTSCALLBACK
-: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK
+: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK ( quot -- callback )
     [ "BOOL" { "LPDIRECTINPUTEFFECT" "LPVOID" } "stdcall" ]
     dip alien-callback ; inline
 TYPEDEF: void* LPDIENUMEFFECTSINFILECALLBACK
-: LPDIENUMEFFECTSINFILECALLBACK
+: LPDIENUMEFFECTSINFILECALLBACK ( quot -- callback )
     [ "BOOL" { "LPCDIFILEEFFECT" "LPVOID" } "stdcall" ]
     dip alien-callback ; inline
 TYPEDEF: void* LPDIENUMDEVICEOBJECTSCALLBACKW
-: LPDIENUMDEVICEOBJECTSCALLBACKW
+: LPDIENUMDEVICEOBJECTSCALLBACKW ( quot -- callback )
     [ "BOOL" { "LPCDIDEVICEOBJECTINSTANCEW" "LPVOID" } "stdcall" ]
     dip alien-callback ; inline
 
diff --git a/basis/windows/fonts/fonts.factor b/basis/windows/fonts/fonts.factor
new file mode 100755 (executable)
index 0000000..a034856
--- /dev/null
@@ -0,0 +1,37 @@
+USING: assocs memoize locals kernel accessors init fonts math\r
+combinators windows windows.types windows.gdi32 ;\r
+IN: windows.fonts\r
+\r
+: windows-font-name ( string -- string' )\r
+    H{\r
+        { "sans-serif" "Tahoma" }\r
+        { "serif" "Times New Roman" }\r
+        { "monospace" "Courier New" }\r
+    } at-default ;\r
+    \r
+MEMO:: (cache-font) ( font -- HFONT )\r
+    font size>> neg ! nHeight\r
+    0 0 0 ! nWidth, nEscapement, nOrientation\r
+    font bold?>> FW_BOLD FW_NORMAL ? ! fnWeight\r
+    font italic?>> TRUE FALSE ? ! fdwItalic\r
+    FALSE ! fdwUnderline\r
+    FALSE ! fdWStrikeOut\r
+    DEFAULT_CHARSET ! fdwCharSet\r
+    OUT_OUTLINE_PRECIS ! fdwOutputPrecision\r
+    CLIP_DEFAULT_PRECIS ! fdwClipPrecision\r
+    DEFAULT_QUALITY ! fdwQuality\r
+    DEFAULT_PITCH ! fdwPitchAndFamily\r
+    font name>> windows-font-name\r
+    CreateFont\r
+    dup win32-error=0/f ;\r
+\r
+: cache-font ( font -- HFONT ) strip-font-colors (cache-font) ;\r
+\r
+[ \ (cache-font) reset-memoized ] "windows.fonts" add-init-hook\r
+\r
+: TEXTMETRIC>metrics ( TEXTMETRIC -- metrics )\r
+    [ metrics new 0 >>width ] dip {\r
+        [ TEXTMETRICW-tmHeight >>height ]\r
+        [ TEXTMETRICW-tmAscent >>ascent ]\r
+        [ TEXTMETRICW-tmDescent >>descent ]\r
+    } cleave ;\r
index 077adf1961bc75eb4731cf5d78c0777b4737925f..794aa0e32e17277fd1cfc92ab5263bc43838d84c 100755 (executable)
-! FUNCTION: AbortDoc
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax kernel windows.types ;
+USING: alien alien.syntax alien.destructors kernel windows.types
+math.bitwise ;
 IN: windows.gdi32
 
-! Stock Logical Objects
-CONSTANT: WHITE_BRUSH         0
-CONSTANT: LTGRAY_BRUSH        1
-CONSTANT: GRAY_BRUSH          2
-CONSTANT: DKGRAY_BRUSH        3
-CONSTANT: BLACK_BRUSH         4
-CONSTANT: NULL_BRUSH          5
-ALIAS: HOLLOW_BRUSH        NULL_BRUSH
-CONSTANT: WHITE_PEN           6
-CONSTANT: BLACK_PEN           7
-CONSTANT: NULL_PEN            8
-CONSTANT: OEM_FIXED_FONT      10
-CONSTANT: ANSI_FIXED_FONT     11
-CONSTANT: ANSI_VAR_FONT       12
-CONSTANT: SYSTEM_FONT         13
+CONSTANT: BI_RGB 0
+CONSTANT: BI_RLE8 1
+CONSTANT: BI_RLE4 2
+CONSTANT: BI_BITFIELDS 3
+CONSTANT: BI_JPEG 4
+CONSTANT: BI_PNG 5
+CONSTANT: LF_FACESIZE 32
+CONSTANT: LF_FULLFACESIZE 64
+CONSTANT: CA_NEGATIVE 1
+CONSTANT: CA_LOG_FILTER 2
+CONSTANT: ILLUMINANT_DEVICE_DEFAULT 0
+CONSTANT: ILLUMINANT_A 1
+CONSTANT: ILLUMINANT_B 2
+CONSTANT: ILLUMINANT_C 3
+CONSTANT: ILLUMINANT_D50 4
+CONSTANT: ILLUMINANT_D55 5
+CONSTANT: ILLUMINANT_D65 6
+CONSTANT: ILLUMINANT_D75 7
+CONSTANT: ILLUMINANT_F2 8
+ALIAS: ILLUMINANT_MAX_INDEX ILLUMINANT_F2
+ALIAS: ILLUMINANT_TUNGSTEN ILLUMINANT_A
+ALIAS: ILLUMINANT_DAYLIGHT ILLUMINANT_C
+ALIAS: ILLUMINANT_FLUORESCENT ILLUMINANT_F2
+ALIAS: ILLUMINANT_NTSC ILLUMINANT_C
+CONSTANT: RGB_GAMMA_MIN 2500
+CONSTANT: RGB_GAMMA_MAX 65000
+CONSTANT: REFERENCE_WHITE_MIN 6000
+CONSTANT: REFERENCE_WHITE_MAX 10000
+CONSTANT: REFERENCE_BLACK_MIN 0
+CONSTANT: REFERENCE_BLACK_MAX 4000
+CONSTANT: COLOR_ADJ_MIN -100
+CONSTANT: COLOR_ADJ_MAX 100
+CONSTANT: CCHDEVICENAME 32
+CONSTANT: CCHFORMNAME 32
+CONSTANT: DI_COMPAT 4
+CONSTANT: DI_DEFAULTSIZE 8
+CONSTANT: DI_IMAGE 2
+CONSTANT: DI_MASK 1
+CONSTANT: DI_NORMAL 3
+CONSTANT: DI_APPBANDING 1
+CONSTANT: EMR_HEADER 1
+CONSTANT: EMR_POLYBEZIER 2
+CONSTANT: EMR_POLYGON 3
+CONSTANT: EMR_POLYLINE 4
+CONSTANT: EMR_POLYBEZIERTO 5
+CONSTANT: EMR_POLYLINETO 6
+CONSTANT: EMR_POLYPOLYLINE 7
+CONSTANT: EMR_POLYPOLYGON 8
+CONSTANT: EMR_SETWINDOWEXTEX 9
+CONSTANT: EMR_SETWINDOWORGEX 10
+CONSTANT: EMR_SETVIEWPORTEXTEX 11
+CONSTANT: EMR_SETVIEWPORTORGEX 12
+CONSTANT: EMR_SETBRUSHORGEX 13
+CONSTANT: EMR_EOF 14
+CONSTANT: EMR_SETPIXELV 15
+CONSTANT: EMR_SETMAPPERFLAGS 16
+CONSTANT: EMR_SETMAPMODE 17
+CONSTANT: EMR_SETBKMODE 18
+CONSTANT: EMR_SETPOLYFILLMODE 19
+CONSTANT: EMR_SETROP2 20
+CONSTANT: EMR_SETSTRETCHBLTMODE 21
+CONSTANT: EMR_SETTEXTALIGN 22
+CONSTANT: EMR_SETCOLORADJUSTMENT 23
+CONSTANT: EMR_SETTEXTCOLOR 24
+CONSTANT: EMR_SETBKCOLOR 25
+CONSTANT: EMR_OFFSETCLIPRGN 26
+CONSTANT: EMR_MOVETOEX 27
+CONSTANT: EMR_SETMETARGN 28
+CONSTANT: EMR_EXCLUDECLIPRECT 29
+CONSTANT: EMR_INTERSECTCLIPRECT 30
+CONSTANT: EMR_SCALEVIEWPORTEXTEX 31
+CONSTANT: EMR_SCALEWINDOWEXTEX 32
+CONSTANT: EMR_SAVEDC 33
+CONSTANT: EMR_RESTOREDC 34
+CONSTANT: EMR_SETWORLDTRANSFORM 35
+CONSTANT: EMR_MODIFYWORLDTRANSFORM 36
+CONSTANT: EMR_SELECTOBJECT 37
+CONSTANT: EMR_CREATEPEN 38
+CONSTANT: EMR_CREATEBRUSHINDIRECT 39
+CONSTANT: EMR_DELETEOBJECT 40
+CONSTANT: EMR_ANGLEARC 41
+CONSTANT: EMR_ELLIPSE 42
+CONSTANT: EMR_RECTANGLE 43
+CONSTANT: EMR_ROUNDRECT 44
+CONSTANT: EMR_ARC 45
+CONSTANT: EMR_CHORD 46
+CONSTANT: EMR_PIE 47
+CONSTANT: EMR_SELECTPALETTE 48
+CONSTANT: EMR_CREATEPALETTE 49
+CONSTANT: EMR_SETPALETTEENTRIES 50
+CONSTANT: EMR_RESIZEPALETTE 51
+CONSTANT: EMR_REALIZEPALETTE 52
+CONSTANT: EMR_EXTFLOODFILL 53
+CONSTANT: EMR_LINETO 54
+CONSTANT: EMR_ARCTO 55
+CONSTANT: EMR_POLYDRAW 56
+CONSTANT: EMR_SETARCDIRECTION 57
+CONSTANT: EMR_SETMITERLIMIT 58
+CONSTANT: EMR_BEGINPATH 59
+CONSTANT: EMR_ENDPATH 60
+CONSTANT: EMR_CLOSEFIGURE 61
+CONSTANT: EMR_FILLPATH 62
+CONSTANT: EMR_STROKEANDFILLPATH 63
+CONSTANT: EMR_STROKEPATH 64
+CONSTANT: EMR_FLATTENPATH 65
+CONSTANT: EMR_WIDENPATH 66
+CONSTANT: EMR_SELECTCLIPPATH 67
+CONSTANT: EMR_ABORTPATH 68
+CONSTANT: EMR_GDICOMMENT 70
+CONSTANT: EMR_FILLRGN 71
+CONSTANT: EMR_FRAMERGN 72
+CONSTANT: EMR_INVERTRGN 73
+CONSTANT: EMR_PAINTRGN 74
+CONSTANT: EMR_EXTSELECTCLIPRGN 75
+CONSTANT: EMR_BITBLT 76
+CONSTANT: EMR_STRETCHBLT 77
+CONSTANT: EMR_MASKBLT 78
+CONSTANT: EMR_PLGBLT 79
+CONSTANT: EMR_SETDIBITSTODEVICE 80
+CONSTANT: EMR_STRETCHDIBITS 81
+CONSTANT: EMR_EXTCREATEFONTINDIRECTW 82
+CONSTANT: EMR_EXTTEXTOUTA 83
+CONSTANT: EMR_EXTTEXTOUTW 84
+CONSTANT: EMR_POLYBEZIER16 85
+CONSTANT: EMR_POLYGON16 86
+CONSTANT: EMR_POLYLINE16 87
+CONSTANT: EMR_POLYBEZIERTO16 88
+CONSTANT: EMR_POLYLINETO16 89
+CONSTANT: EMR_POLYPOLYLINE16 90
+CONSTANT: EMR_POLYPOLYGON16 91
+CONSTANT: EMR_POLYDRAW16 92
+CONSTANT: EMR_CREATEMONOBRUSH 93
+CONSTANT: EMR_CREATEDIBPATTERNBRUSHPT 94
+CONSTANT: EMR_EXTCREATEPEN 95
+CONSTANT: EMR_POLYTEXTOUTA 96
+CONSTANT: EMR_POLYTEXTOUTW 97
+CONSTANT: EMR_SETICMMODE 98
+CONSTANT: EMR_CREATECOLORSPACE 99
+CONSTANT: EMR_SETCOLORSPACE 100
+CONSTANT: EMR_DELETECOLORSPACE 101
+CONSTANT: EMR_GLSRECORD 102
+CONSTANT: EMR_GLSBOUNDEDRECORD 103
+CONSTANT: EMR_PIXELFORMAT 104
+CONSTANT: ENHMETA_SIGNATURE 1179469088
+CONSTANT: EPS_SIGNATURE HEX: 46535045
+CONSTANT: FR_PRIVATE HEX: 10
+CONSTANT: FR_NOT_ENUM HEX: 20
+CONSTANT: META_SETBKCOLOR HEX: 201
+CONSTANT: META_SETBKMODE HEX: 102
+CONSTANT: META_SETMAPMODE HEX: 103
+CONSTANT: META_SETROP2 HEX: 104
+CONSTANT: META_SETRELABS HEX: 105
+CONSTANT: META_SETPOLYFILLMODE HEX: 106
+CONSTANT: META_SETSTRETCHBLTMODE HEX: 107
+CONSTANT: META_SETTEXTCHAREXTRA HEX: 108
+CONSTANT: META_SETTEXTCOLOR HEX: 209
+CONSTANT: META_SETTEXTJUSTIFICATION HEX: 20A
+CONSTANT: META_SETWINDOWORG HEX: 20B
+CONSTANT: META_SETWINDOWEXT HEX: 20C
+CONSTANT: META_SETVIEWPORTORG HEX: 20D
+CONSTANT: META_SETVIEWPORTEXT HEX: 20E
+CONSTANT: META_OFFSETWINDOWORG HEX: 20F
+CONSTANT: META_SCALEWINDOWEXT HEX: 410
+CONSTANT: META_OFFSETVIEWPORTORG HEX: 211
+CONSTANT: META_SCALEVIEWPORTEXT HEX: 412
+CONSTANT: META_LINETO HEX: 213
+CONSTANT: META_MOVETO HEX: 214
+CONSTANT: META_EXCLUDECLIPRECT HEX: 415
+CONSTANT: META_INTERSECTCLIPRECT HEX: 416
+CONSTANT: META_ARC HEX: 817
+CONSTANT: META_ELLIPSE HEX: 418
+CONSTANT: META_FLOODFILL HEX: 419
+CONSTANT: META_PIE HEX: 81A
+CONSTANT: META_RECTANGLE HEX: 41B
+CONSTANT: META_ROUNDRECT HEX: 61C
+CONSTANT: META_PATBLT HEX: 61D
+CONSTANT: META_SAVEDC HEX: 1E
+CONSTANT: META_SETPIXEL HEX: 41F
+CONSTANT: META_OFFSETCLIPRGN HEX: 220
+CONSTANT: META_TEXTOUT HEX: 521
+CONSTANT: META_BITBLT HEX: 922
+CONSTANT: META_STRETCHBLT HEX: b23
+CONSTANT: META_POLYGON HEX: 324
+CONSTANT: META_POLYLINE HEX: 325
+CONSTANT: META_ESCAPE HEX: 626
+CONSTANT: META_RESTOREDC HEX: 127
+CONSTANT: META_FILLREGION HEX: 228
+CONSTANT: META_FRAMEREGION HEX: 429
+CONSTANT: META_INVERTREGION HEX: 12A
+CONSTANT: META_PAINTREGION HEX: 12B
+CONSTANT: META_SELECTCLIPREGION HEX: 12C
+CONSTANT: META_SELECTOBJECT HEX: 12D
+CONSTANT: META_SETTEXTALIGN HEX: 12E
+CONSTANT: META_CHORD HEX: 830
+CONSTANT: META_SETMAPPERFLAGS HEX: 231
+CONSTANT: META_EXTTEXTOUT HEX: a32
+CONSTANT: META_SETDIBTODEV HEX: d33
+CONSTANT: META_SELECTPALETTE HEX: 234
+CONSTANT: META_REALIZEPALETTE HEX: 35
+CONSTANT: META_ANIMATEPALETTE HEX: 436
+CONSTANT: META_SETPALENTRIES HEX: 37
+CONSTANT: META_POLYPOLYGON HEX: 538
+CONSTANT: META_RESIZEPALETTE HEX: 139
+CONSTANT: META_DIBBITBLT HEX: 940
+CONSTANT: META_DIBSTRETCHBLT HEX: b41
+CONSTANT: META_DIBCREATEPATTERNBRUSH HEX: 142
+CONSTANT: META_STRETCHDIB HEX: f43
+CONSTANT: META_EXTFLOODFILL HEX: 548
+CONSTANT: META_DELETEOBJECT HEX: 1f0
+CONSTANT: META_CREATEPALETTE HEX: f7
+CONSTANT: META_CREATEPATTERNBRUSH HEX: 1F9
+CONSTANT: META_CREATEPENINDIRECT HEX: 2FA
+CONSTANT: META_CREATEFONTINDIRECT HEX: 2FB
+CONSTANT: META_CREATEBRUSHINDIRECT HEX: 2FC
+CONSTANT: META_CREATEREGION HEX: 6FF
+CONSTANT: ELF_VENDOR_SIZE 4
+CONSTANT: ELF_VERSION 0
+CONSTANT: ELF_CULTURE_LATIN 0
+CONSTANT: PFD_TYPE_RGBA 0
+CONSTANT: PFD_TYPE_COLORINDEX 1
+CONSTANT: PFD_MAIN_PLANE 0
+CONSTANT: PFD_OVERLAY_PLANE 1
+CONSTANT: PFD_UNDERLAY_PLANE -1
+CONSTANT: PFD_DOUBLEBUFFER 1
+CONSTANT: PFD_STEREO 2
+CONSTANT: PFD_DRAW_TO_WINDOW 4
+CONSTANT: PFD_DRAW_TO_BITMAP 8
+CONSTANT: PFD_SUPPORT_GDI 16
+CONSTANT: PFD_SUPPORT_OPENGL 32
+CONSTANT: PFD_GENERIC_FORMAT 64
+CONSTANT: PFD_NEED_PALETTE 128
+CONSTANT: PFD_NEED_SYSTEM_PALETTE HEX: 00000100
+CONSTANT: PFD_SWAP_EXCHANGE HEX: 00000200
+CONSTANT: PFD_SWAP_COPY HEX: 00000400
+CONSTANT: PFD_SWAP_LAYER_BUFFERS HEX: 00000800
+CONSTANT: PFD_GENERIC_ACCELERATED HEX: 00001000
+CONSTANT: PFD_DEPTH_DONTCARE HEX: 20000000
+CONSTANT: PFD_DOUBLEBUFFER_DONTCARE HEX: 40000000
+CONSTANT: PFD_STEREO_DONTCARE HEX: 80000000
+CONSTANT: SP_ERROR -1
+CONSTANT: SP_OUTOFDISK -4
+CONSTANT: SP_OUTOFMEMORY -5
+CONSTANT: SP_USERABORT -3
+CONSTANT: SP_APPABORT -2
+CONSTANT: BLACKNESS HEX: 00000042
+CONSTANT: NOTSRCERASE HEX: 001100A6
+CONSTANT: NOTSRCCOPY HEX: 00330008
+CONSTANT: SRCERASE HEX: 00440328
+CONSTANT: DSTINVERT HEX: 00550009
+CONSTANT: PATINVERT HEX: 005A0049
+CONSTANT: SRCINVERT HEX: 00660046
+CONSTANT: SRCAND HEX: 008800C6
+CONSTANT: MERGEPAINT HEX: 00BB0226
+CONSTANT: MERGECOPY HEX: 00C000CA
+CONSTANT: SRCCOPY HEX: 00CC0020
+CONSTANT: SRCPAINT HEX: 00EE0086
+CONSTANT: PATCOPY HEX: 00F00021
+CONSTANT: PATPAINT HEX: 00FB0A09
+CONSTANT: WHITENESS HEX: 00FF0062
+CONSTANT: CAPTUREBLT HEX: 40000000
+CONSTANT: NOMIRRORBITMAP HEX: 80000000
+CONSTANT: R2_BLACK 1
+CONSTANT: R2_COPYPEN 13
+CONSTANT: R2_MASKNOTPEN 3
+CONSTANT: R2_MASKPEN 9
+CONSTANT: R2_MASKPENNOT 5
+CONSTANT: R2_MERGENOTPEN 12
+CONSTANT: R2_MERGEPEN 15
+CONSTANT: R2_MERGEPENNOT 14
+CONSTANT: R2_NOP 11
+CONSTANT: R2_NOT 6
+CONSTANT: R2_NOTCOPYPEN 4
+CONSTANT: R2_NOTMASKPEN 8
+CONSTANT: R2_NOTMERGEPEN 2
+CONSTANT: R2_NOTXORPEN 10
+CONSTANT: R2_WHITE 16
+CONSTANT: R2_XORPEN 7
+CONSTANT: CM_OUT_OF_GAMUT 255
+CONSTANT: CM_IN_GAMUT 0
+CONSTANT: RGN_AND 1
+CONSTANT: RGN_COPY 5
+CONSTANT: RGN_DIFF 4
+CONSTANT: RGN_OR 2
+CONSTANT: RGN_XOR 3
+CONSTANT: NULLREGION 1
+CONSTANT: SIMPLEREGION 2
+CONSTANT: COMPLEXREGION 3
+CONSTANT: ERROR 0
+CONSTANT: CBM_INIT 4
+CONSTANT: DIB_PAL_COLORS 1
+CONSTANT: DIB_RGB_COLORS 0
+CONSTANT: FW_DONTCARE 0
+CONSTANT: FW_THIN 100
+CONSTANT: FW_EXTRALIGHT 200
+ALIAS: FW_ULTRALIGHT FW_EXTRALIGHT
+CONSTANT: FW_LIGHT 300
+CONSTANT: FW_NORMAL 400
+CONSTANT: FW_REGULAR 400
+CONSTANT: FW_MEDIUM 500
+CONSTANT: FW_SEMIBOLD 600
+ALIAS: FW_DEMIBOLD FW_SEMIBOLD
+CONSTANT: FW_BOLD 700
+CONSTANT: FW_EXTRABOLD 800
+ALIAS: FW_ULTRABOLD FW_EXTRABOLD
+CONSTANT: FW_HEAVY 900
+ALIAS: FW_BLACK FW_HEAVY
+CONSTANT: ANSI_CHARSET 0
+CONSTANT: DEFAULT_CHARSET 1
+CONSTANT: SYMBOL_CHARSET 2
+CONSTANT: SHIFTJIS_CHARSET 128
+CONSTANT: HANGEUL_CHARSET 129
+CONSTANT: HANGUL_CHARSET 129
+CONSTANT: GB2312_CHARSET 134
+CONSTANT: CHINESEBIG5_CHARSET 136
+CONSTANT: GREEK_CHARSET 161
+CONSTANT: TURKISH_CHARSET 162
+CONSTANT: HEBREW_CHARSET 177
+CONSTANT: ARABIC_CHARSET 178
+CONSTANT: BALTIC_CHARSET 186
+CONSTANT: RUSSIAN_CHARSET 204
+CONSTANT: THAI_CHARSET 222
+CONSTANT: EASTEUROPE_CHARSET 238
+CONSTANT: OEM_CHARSET 255
+CONSTANT: JOHAB_CHARSET 130
+CONSTANT: VIETNAMESE_CHARSET 163
+CONSTANT: MAC_CHARSET 77
+CONSTANT: OUT_DEFAULT_PRECIS 0
+CONSTANT: OUT_STRING_PRECIS 1
+CONSTANT: OUT_CHARACTER_PRECIS 2
+CONSTANT: OUT_STROKE_PRECIS 3
+CONSTANT: OUT_TT_PRECIS 4
+CONSTANT: OUT_DEVICE_PRECIS 5
+CONSTANT: OUT_RASTER_PRECIS 6
+CONSTANT: OUT_TT_ONLY_PRECIS 7
+CONSTANT: OUT_OUTLINE_PRECIS 8
+CONSTANT: CLIP_DEFAULT_PRECIS 0
+CONSTANT: CLIP_CHARACTER_PRECIS 1
+CONSTANT: CLIP_STROKE_PRECIS 2
+CONSTANT: CLIP_MASK 15
+CONSTANT: CLIP_LH_ANGLES 16
+CONSTANT: CLIP_TT_ALWAYS 32
+CONSTANT: CLIP_EMBEDDED 128
+CONSTANT: DEFAULT_QUALITY 0
+CONSTANT: DRAFT_QUALITY 1
+CONSTANT: PROOF_QUALITY 2
+CONSTANT: NONANTIALIASED_QUALITY 3
+CONSTANT: ANTIALIASED_QUALITY 4
+CONSTANT: DEFAULT_PITCH 0
+CONSTANT: FIXED_PITCH 1
+CONSTANT: VARIABLE_PITCH 2
+CONSTANT: MONO_FONT 8
+CONSTANT: FF_DECORATIVE 80
+CONSTANT: FF_DONTCARE 0
+CONSTANT: FF_MODERN 48
+CONSTANT: FF_ROMAN 16
+CONSTANT: FF_SCRIPT 64
+CONSTANT: FF_SWISS 32
+CONSTANT: PANOSE_COUNT 10
+CONSTANT: PAN_FAMILYTYPE_INDEX 0
+CONSTANT: PAN_SERIFSTYLE_INDEX 1
+CONSTANT: PAN_WEIGHT_INDEX 2
+CONSTANT: PAN_PROPORTION_INDEX 3
+CONSTANT: PAN_CONTRAST_INDEX 4
+CONSTANT: PAN_STROKEVARIATION_INDEX 5
+CONSTANT: PAN_ARMSTYLE_INDEX 6
+CONSTANT: PAN_LETTERFORM_INDEX 7
+CONSTANT: PAN_MIDLINE_INDEX 8
+CONSTANT: PAN_XHEIGHT_INDEX 9
+CONSTANT: PAN_CULTURE_LATIN 0
+CONSTANT: PAN_ANY 0
+CONSTANT: PAN_NO_FIT 1
+CONSTANT: PAN_FAMILY_TEXT_DISPLAY 2
+CONSTANT: PAN_FAMILY_SCRIPT 3
+CONSTANT: PAN_FAMILY_DECORATIVE 4
+CONSTANT: PAN_FAMILY_PICTORIAL 5
+CONSTANT: PAN_SERIF_COVE 2
+CONSTANT: PAN_SERIF_OBTUSE_COVE 3
+CONSTANT: PAN_SERIF_SQUARE_COVE 4
+CONSTANT: PAN_SERIF_OBTUSE_SQUARE_COVE 5
+CONSTANT: PAN_SERIF_SQUARE 6
+CONSTANT: PAN_SERIF_THIN 7
+CONSTANT: PAN_SERIF_BONE 8
+CONSTANT: PAN_SERIF_EXAGGERATED 9
+CONSTANT: PAN_SERIF_TRIANGLE 10
+CONSTANT: PAN_SERIF_NORMAL_SANS 11
+CONSTANT: PAN_SERIF_OBTUSE_SANS 12
+CONSTANT: PAN_SERIF_PERP_SANS 13
+CONSTANT: PAN_SERIF_FLARED 14
+CONSTANT: PAN_SERIF_ROUNDED 15
+CONSTANT: PAN_WEIGHT_VERY_LIGHT 2
+CONSTANT: PAN_WEIGHT_LIGHT 3
+CONSTANT: PAN_WEIGHT_THIN 4
+CONSTANT: PAN_WEIGHT_BOOK 5
+CONSTANT: PAN_WEIGHT_MEDIUM 6
+CONSTANT: PAN_WEIGHT_DEMI 7
+CONSTANT: PAN_WEIGHT_BOLD 8
+CONSTANT: PAN_WEIGHT_HEAVY 9
+CONSTANT: PAN_WEIGHT_BLACK 10
+CONSTANT: PAN_WEIGHT_NORD 11
+CONSTANT: PAN_PROP_OLD_STYLE 2
+CONSTANT: PAN_PROP_MODERN 3
+CONSTANT: PAN_PROP_EVEN_WIDTH 4
+CONSTANT: PAN_PROP_EXPANDED 5
+CONSTANT: PAN_PROP_CONDENSED 6
+CONSTANT: PAN_PROP_VERY_EXPANDED 7
+CONSTANT: PAN_PROP_VERY_CONDENSED 8
+CONSTANT: PAN_PROP_MONOSPACED 9
+CONSTANT: PAN_CONTRAST_NONE 2
+CONSTANT: PAN_CONTRAST_VERY_LOW 3
+CONSTANT: PAN_CONTRAST_LOW 4
+CONSTANT: PAN_CONTRAST_MEDIUM_LOW 5
+CONSTANT: PAN_CONTRAST_MEDIUM 6
+CONSTANT: PAN_CONTRAST_MEDIUM_HIGH 7
+CONSTANT: PAN_CONTRAST_HIGH 8
+CONSTANT: PAN_CONTRAST_VERY_HIGH 9
+CONSTANT: PAN_STROKE_GRADUAL_DIAG 2
+CONSTANT: PAN_STROKE_GRADUAL_TRAN 3
+CONSTANT: PAN_STROKE_GRADUAL_VERT 4
+CONSTANT: PAN_STROKE_GRADUAL_HORZ 5
+CONSTANT: PAN_STROKE_RAPID_VERT 6
+CONSTANT: PAN_STROKE_RAPID_HORZ 7
+CONSTANT: PAN_STROKE_INSTANT_VERT 8
+CONSTANT: PAN_STRAIGHT_ARMS_HORZ 2
+CONSTANT: PAN_STRAIGHT_ARMS_WEDGE 3
+CONSTANT: PAN_STRAIGHT_ARMS_VERT 4
+CONSTANT: PAN_STRAIGHT_ARMS_SINGLE_SERIF 5
+CONSTANT: PAN_STRAIGHT_ARMS_DOUBLE_SERIF 6
+CONSTANT: PAN_BENT_ARMS_HORZ 7
+CONSTANT: PAN_BENT_ARMS_WEDGE 8
+CONSTANT: PAN_BENT_ARMS_VERT 9
+CONSTANT: PAN_BENT_ARMS_SINGLE_SERIF 10
+CONSTANT: PAN_BENT_ARMS_DOUBLE_SERIF 11
+CONSTANT: PAN_LETT_NORMAL_CONTACT 2
+CONSTANT: PAN_LETT_NORMAL_WEIGHTED 3
+CONSTANT: PAN_LETT_NORMAL_BOXED 4
+CONSTANT: PAN_LETT_NORMAL_FLATTENED 5
+CONSTANT: PAN_LETT_NORMAL_ROUNDED 6
+CONSTANT: PAN_LETT_NORMAL_OFF_CENTER 7
+CONSTANT: PAN_LETT_NORMAL_SQUARE 8
+CONSTANT: PAN_LETT_OBLIQUE_CONTACT 9
+CONSTANT: PAN_LETT_OBLIQUE_WEIGHTED 10
+CONSTANT: PAN_LETT_OBLIQUE_BOXED 11
+CONSTANT: PAN_LETT_OBLIQUE_FLATTENED 12
+CONSTANT: PAN_LETT_OBLIQUE_ROUNDED 13
+CONSTANT: PAN_LETT_OBLIQUE_OFF_CENTER 14
+CONSTANT: PAN_LETT_OBLIQUE_SQUARE 15
+CONSTANT: PAN_MIDLINE_STANDARD_TRIMMED 2
+CONSTANT: PAN_MIDLINE_STANDARD_POINTED 3
+CONSTANT: PAN_MIDLINE_STANDARD_SERIFED 4
+CONSTANT: PAN_MIDLINE_HIGH_TRIMMED 5
+CONSTANT: PAN_MIDLINE_HIGH_POINTED 6
+CONSTANT: PAN_MIDLINE_HIGH_SERIFED 7
+CONSTANT: PAN_MIDLINE_CONSTANT_TRIMMED 8
+CONSTANT: PAN_MIDLINE_CONSTANT_POINTED 9
+CONSTANT: PAN_MIDLINE_CONSTANT_SERIFED 10
+CONSTANT: PAN_MIDLINE_LOW_TRIMMED 11
+CONSTANT: PAN_MIDLINE_LOW_POINTED 12
+CONSTANT: PAN_MIDLINE_LOW_SERIFED 13
+CONSTANT: PAN_XHEIGHT_CONSTANT_SMALL 2
+CONSTANT: PAN_XHEIGHT_CONSTANT_STD 3
+CONSTANT: PAN_XHEIGHT_CONSTANT_LARGE 4
+CONSTANT: PAN_XHEIGHT_DUCKING_SMALL 5
+CONSTANT: PAN_XHEIGHT_DUCKING_STD 6
+CONSTANT: PAN_XHEIGHT_DUCKING_LARGE 7
+CONSTANT: FS_LATIN1 1
+CONSTANT: FS_LATIN2 2
+CONSTANT: FS_CYRILLIC 4
+CONSTANT: FS_GREEK 8
+CONSTANT: FS_TURKISH 16
+CONSTANT: FS_HEBREW 32
+CONSTANT: FS_ARABIC 64
+CONSTANT: FS_BALTIC 128
+CONSTANT: FS_THAI HEX: 10000
+CONSTANT: FS_JISJAPAN HEX: 20000
+CONSTANT: FS_CHINESESIMP HEX: 40000
+CONSTANT: FS_WANSUNG HEX: 80000
+CONSTANT: FS_CHINESETRAD HEX: 100000
+CONSTANT: FS_JOHAB HEX: 200000
+CONSTANT: FS_SYMBOL HEX: 80000000
+CONSTANT: HS_BDIAGONAL 3
+CONSTANT: HS_CROSS 4
+CONSTANT: HS_DIAGCROSS 5
+CONSTANT: HS_FDIAGONAL 2
+CONSTANT: HS_HORIZONTAL 0
+CONSTANT: HS_VERTICAL 1
+CONSTANT: PS_GEOMETRIC 65536
+CONSTANT: PS_COSMETIC 0
+CONSTANT: PS_ALTERNATE 8
+CONSTANT: PS_SOLID 0
+CONSTANT: PS_DASH 1
+CONSTANT: PS_DOT 2
+CONSTANT: PS_DASHDOT 3
+CONSTANT: PS_DASHDOTDOT 4
+CONSTANT: PS_NULL 5
+CONSTANT: PS_USERSTYLE 7
+CONSTANT: PS_INSIDEFRAME 6
+CONSTANT: PS_ENDCAP_ROUND 0
+CONSTANT: PS_ENDCAP_SQUARE 256
+CONSTANT: PS_ENDCAP_FLAT 512
+CONSTANT: PS_JOIN_BEVEL 4096
+CONSTANT: PS_JOIN_MITER 8192
+CONSTANT: PS_JOIN_ROUND 0
+CONSTANT: PS_STYLE_MASK 15
+CONSTANT: PS_ENDCAP_MASK 3840
+CONSTANT: PS_TYPE_MASK 983040
+CONSTANT: ALTERNATE 1
+CONSTANT: WINDING 2
+CONSTANT: DC_BINNAMES 12
+CONSTANT: DC_BINS 6
+CONSTANT: DC_COPIES 18
+CONSTANT: DC_DRIVER 11
+CONSTANT: DC_DATATYPE_PRODUCED 21
+CONSTANT: DC_DUPLEX 7
+CONSTANT: DC_EMF_COMPLIANT 20
+CONSTANT: DC_ENUMRESOLUTIONS 13
+CONSTANT: DC_EXTRA 9
+CONSTANT: DC_FIELDS 1
+CONSTANT: DC_FILEDEPENDENCIES 14
+CONSTANT: DC_MAXEXTENT 5
+CONSTANT: DC_MINEXTENT 4
+CONSTANT: DC_ORIENTATION 17
+CONSTANT: DC_PAPERNAMES 16
+CONSTANT: DC_PAPERS 2
+CONSTANT: DC_PAPERSIZE 3
+CONSTANT: DC_SIZE 8
+CONSTANT: DC_TRUETYPE 15
+CONSTANT: DCTT_BITMAP 1
+CONSTANT: DCTT_DOWNLOAD 2
+CONSTANT: DCTT_SUBDEV 4
+CONSTANT: DCTT_DOWNLOAD_OUTLINE 8
+CONSTANT: DC_VERSION 10
+CONSTANT: DC_BINADJUST 19
+CONSTANT: DC_MANUFACTURER 23
+CONSTANT: DC_MODEL 24
+CONSTANT: DC_PERSONALITY 25
+CONSTANT: DC_PRINTRATE 26
+CONSTANT: DC_PRINTRATEUNIT 27
+CONSTANT: DC_PRINTERMEM 28
+CONSTANT: DC_MEDIAREADY 29
+CONSTANT: DC_STAPLE 30
+CONSTANT: DC_PRINTRATEPPM 31
+CONSTANT: DC_COLORDEVICE 32
+CONSTANT: DC_NUP 33
+CONSTANT: DC_MEDIATYPENAMES 34
+CONSTANT: DC_MEDIATYPES 35
+CONSTANT: DCBA_FACEUPNONE 0
+CONSTANT: DCBA_FACEUPCENTER 1
+CONSTANT: DCBA_FACEUPLEFT 2
+CONSTANT: DCBA_FACEUPRIGHT 3
+CONSTANT: DCBA_FACEDOWNNONE 256
+CONSTANT: DCBA_FACEDOWNCENTER 257
+CONSTANT: DCBA_FACEDOWNLEFT 258
+CONSTANT: DCBA_FACEDOWNRIGHT 259
+CONSTANT: FLOODFILLBORDER 0
+CONSTANT: FLOODFILLSURFACE 1
+CONSTANT: ETO_CLIPPED HEX: 0004
+CONSTANT: ETO_GLYPH_INDEX HEX: 0010
+CONSTANT: ETO_OPAQUE HEX: 0002
+CONSTANT: ETO_NUMERICSLATIN HEX: 0800
+CONSTANT: ETO_NUMERICSLOCAL HEX: 0400
+CONSTANT: ETO_RTLREADING HEX: 0080
+CONSTANT: ETO_IGNORELANGUAGE HEX: 1000
+CONSTANT: ETO_PDY HEX: 2000
+CONSTANT: GDICOMMENT_WINDOWS_METAFILE -2147483647
+CONSTANT: GDICOMMENT_BEGINGROUP 2
+CONSTANT: GDICOMMENT_ENDGROUP 3
+CONSTANT: GDICOMMENT_MULTIFORMATS 1073741828
+CONSTANT: GDICOMMENT_IDENTIFIER 1128875079
+CONSTANT: AD_COUNTERCLOCKWISE 1
+CONSTANT: AD_CLOCKWISE 2
+CONSTANT: RDH_RECTANGLES 1
+CONSTANT: GCPCLASS_LATIN 1
+CONSTANT: GCPCLASS_HEBREW 2
+CONSTANT: GCPCLASS_ARABIC 2
+CONSTANT: GCPCLASS_NEUTRAL 3
+CONSTANT: GCPCLASS_LOCALNUMBER 4
+CONSTANT: GCPCLASS_LATINNUMBER 5
+CONSTANT: GCPCLASS_LATINNUMERICTERMINATOR 6
+CONSTANT: GCPCLASS_LATINNUMERICSEPARATOR 7
+CONSTANT: GCPCLASS_NUMERICSEPARATOR 8
+CONSTANT: GCPCLASS_PREBOUNDLTR 128
+CONSTANT: GCPCLASS_PREBOUNDRTL 64
+CONSTANT: GCPCLASS_POSTBOUNDLTR 32
+CONSTANT: GCPCLASS_POSTBOUNDRTL 16
+CONSTANT: GCPGLYPH_LINKBEFORE HEX: 8000
+CONSTANT: GCPGLYPH_LINKAFTER HEX: 4000
+CONSTANT: DCB_DISABLE 8
+CONSTANT: DCB_ENABLE 4
+CONSTANT: DCB_RESET 1
+CONSTANT: DCB_SET 3
+CONSTANT: DCB_ACCUMULATE 2
+CONSTANT: DCB_DIRTY 2
+CONSTANT: OBJ_BRUSH 2
+CONSTANT: OBJ_PEN 1
+CONSTANT: OBJ_PAL 5
+CONSTANT: OBJ_FONT 6
+CONSTANT: OBJ_BITMAP 7
+CONSTANT: OBJ_EXTPEN 11
+CONSTANT: OBJ_REGION 8
+CONSTANT: OBJ_DC 3
+CONSTANT: OBJ_MEMDC 10
+CONSTANT: OBJ_METAFILE 9
+CONSTANT: OBJ_METADC 4
+CONSTANT: OBJ_ENHMETAFILE 13
+CONSTANT: OBJ_ENHMETADC 12
+CONSTANT: DRIVERVERSION 0
+CONSTANT: TECHNOLOGY 2
+CONSTANT: DT_PLOTTER 0
+CONSTANT: DT_RASDISPLAY 1
+CONSTANT: DT_RASPRINTER 2
+CONSTANT: DT_RASCAMERA 3
+CONSTANT: DT_CHARSTREAM 4
+CONSTANT: DT_METAFILE 5
+CONSTANT: DT_DISPFILE 6
+CONSTANT: HORZSIZE 4
+CONSTANT: VERTSIZE 6
+CONSTANT: HORZRES 8
+CONSTANT: VERTRES 10
+CONSTANT: LOGPIXELSX 88
+CONSTANT: LOGPIXELSY 90
+CONSTANT: BITSPIXEL 12
+CONSTANT: PLANES 14
+CONSTANT: NUMBRUSHES 16
+CONSTANT: NUMPENS 18
+CONSTANT: NUMFONTS 22
+CONSTANT: NUMCOLORS 24
+CONSTANT: NUMMARKERS 20
+CONSTANT: ASPECTX 40
+CONSTANT: ASPECTY 42
+CONSTANT: ASPECTXY 44
+CONSTANT: PDEVICESIZE 26
+CONSTANT: CLIPCAPS 36
+CONSTANT: SIZEPALETTE 104
+CONSTANT: NUMRESERVED 106
+CONSTANT: COLORRES 108
+CONSTANT: PHYSICALWIDTH 110
+CONSTANT: PHYSICALHEIGHT 111
+CONSTANT: PHYSICALOFFSETX 112
+CONSTANT: PHYSICALOFFSETY 113
+CONSTANT: SCALINGFACTORX 114
+CONSTANT: SCALINGFACTORY 115
+CONSTANT: VREFRESH 116
+CONSTANT: DESKTOPHORZRES 118
+CONSTANT: DESKTOPVERTRES 117
+CONSTANT: BLTALIGNMENT 119
+CONSTANT: SHADEBLENDCAPS 120
+CONSTANT: SB_NONE HEX: 00
+CONSTANT: SB_CONST_ALPHA HEX: 01
+CONSTANT: SB_PIXEL_ALPHA HEX: 02
+CONSTANT: SB_PREMULT_ALPHA HEX: 04
+CONSTANT: SB_GRAD_RECT HEX: 10
+CONSTANT: SB_GRAD_TRI HEX: 20
+CONSTANT: COLORMGMTCAPS 121
+CONSTANT: CM_NONE HEX: 00
+CONSTANT: CM_DEVICE_ICM HEX: 01
+CONSTANT: CM_GAMMA_RAMP HEX: 02
+CONSTANT: CM_CMYK_COLOR HEX: 04
+CONSTANT: RASTERCAPS 38
+CONSTANT: RC_BITBLT 1
+CONSTANT: RC_BITMAP64 8
+CONSTANT: RC_DI_BITMAP 128
+CONSTANT: RC_DIBTODEV 512
+CONSTANT: RC_FLOODFILL 4096
+CONSTANT: RC_STRETCHBLT 2048
+CONSTANT: RC_STRETCHDIB 8192
+CONSTANT: CURVECAPS 28
+CONSTANT: CC_NONE 0
+CONSTANT: CC_CIRCLES 1
+CONSTANT: CC_PIE 2
+CONSTANT: CC_CHORD 4
+CONSTANT: CC_ELLIPSES 8
+CONSTANT: CC_WIDE 16
+CONSTANT: CC_STYLED 32
+CONSTANT: CC_WIDESTYLED 64
+CONSTANT: CC_INTERIORS 128
+CONSTANT: CC_ROUNDRECT 256
+CONSTANT: LINECAPS 30
+CONSTANT: LC_NONE 0
+CONSTANT: LC_POLYLINE 2
+CONSTANT: LC_MARKER 4
+CONSTANT: LC_POLYMARKER 8
+CONSTANT: LC_WIDE 16
+CONSTANT: LC_STYLED 32
+CONSTANT: LC_WIDESTYLED 64
+CONSTANT: LC_INTERIORS 128
+CONSTANT: POLYGONALCAPS 32
+CONSTANT: RC_BANDING 2
+CONSTANT: RC_BIGFONT 1024
+CONSTANT: RC_DEVBITS HEX: 8000
+CONSTANT: RC_GDI20_OUTPUT 16
+CONSTANT: RC_GDI20_STATE 32
+CONSTANT: RC_NONE 0
+CONSTANT: RC_OP_DX_OUTPUT HEX: 4000
+CONSTANT: RC_PALETTE 256
+CONSTANT: RC_SAVEBITMAP 64
+CONSTANT: RC_SCALING 4
+CONSTANT: PC_NONE 0
+CONSTANT: PC_POLYGON 1
+CONSTANT: PC_POLYPOLYGON 256
+CONSTANT: PC_PATHS 512
+CONSTANT: PC_RECTANGLE 2
+CONSTANT: PC_WINDPOLYGON 4
+CONSTANT: PC_SCANLINE 8
+CONSTANT: PC_TRAPEZOID 4
+CONSTANT: PC_WIDE 16
+CONSTANT: PC_STYLED 32
+CONSTANT: PC_WIDESTYLED 64
+CONSTANT: PC_INTERIORS 128
+CONSTANT: TEXTCAPS 34
+CONSTANT: TC_OP_CHARACTER 1
+CONSTANT: TC_OP_STROKE 2
+CONSTANT: TC_CP_STROKE 4
+CONSTANT: TC_CR_90 8
+CONSTANT: TC_CR_ANY 16
+CONSTANT: TC_SF_X_YINDEP 32
+CONSTANT: TC_SA_DOUBLE 64
+CONSTANT: TC_SA_INTEGER 128
+CONSTANT: TC_SA_CONTIN 256
+CONSTANT: TC_EA_DOUBLE 512
+CONSTANT: TC_IA_ABLE 1024
+CONSTANT: TC_UA_ABLE 2048
+CONSTANT: TC_SO_ABLE 4096
+CONSTANT: TC_RA_ABLE 8192
+CONSTANT: TC_VA_ABLE 16384
+CONSTANT: TC_RESERVED 32768
+CONSTANT: TC_SCROLLBLT 65536
+CONSTANT: GCP_DBCS 1
+CONSTANT: GCP_ERROR HEX: 8000
+CONSTANT: GCP_CLASSIN HEX: 80000
+CONSTANT: GCP_DIACRITIC 256
+CONSTANT: GCP_DISPLAYZWG HEX: 400000
+CONSTANT: GCP_GLYPHSHAPE 16
+CONSTANT: GCP_JUSTIFY HEX: 10000
+CONSTANT: GCP_JUSTIFYIN HEX: 200000
+CONSTANT: GCP_KASHIDA 1024
+CONSTANT: GCP_LIGATE 32
+CONSTANT: GCP_MAXEXTENT HEX: 100000
+CONSTANT: GCP_NEUTRALOVERRIDE HEX: 2000000
+CONSTANT: GCP_NUMERICOVERRIDE HEX: 1000000
+CONSTANT: GCP_NUMERICSLATIN HEX: 4000000
+CONSTANT: GCP_NUMERICSLOCAL HEX: 8000000
+CONSTANT: GCP_REORDER 2
+CONSTANT: GCP_SYMSWAPOFF HEX: 800000
+CONSTANT: GCP_USEKERNING 8
+CONSTANT: FLI_GLYPHS HEX: 40000
+CONSTANT: FLI_MASK HEX: 103b
+CONSTANT: GGO_METRICS 0
+CONSTANT: GGO_BITMAP 1
+CONSTANT: GGO_NATIVE 2
+CONSTANT: GGO_BEZIER 3
+CONSTANT: GGO_GRAY2_BITMAP 4
+CONSTANT: GGO_GRAY4_BITMAP 5
+CONSTANT: GGO_GRAY8_BITMAP 6
+CONSTANT: GGO_GLYPH_INDEX 128
+CONSTANT: GGO_UNHINTED 256
+CONSTANT: GM_COMPATIBLE 1
+CONSTANT: GM_ADVANCED 2
+CONSTANT: MM_ANISOTROPIC 8
+CONSTANT: MM_HIENGLISH 5
+CONSTANT: MM_HIMETRIC 3
+CONSTANT: MM_ISOTROPIC 7
+CONSTANT: MM_LOENGLISH 4
+CONSTANT: MM_LOMETRIC 2
+CONSTANT: MM_TEXT 1
+CONSTANT: MM_TWIPS 6
+ALIAS: MM_MAX_FIXEDSCALE MM_TWIPS
+CONSTANT: ABSOLUTE 1
+CONSTANT: RELATIVE 2
+CONSTANT: PC_EXPLICIT 2
+CONSTANT: PC_NOCOLLAPSE 4
+CONSTANT: PC_RESERVED 1
+CONSTANT: CLR_NONE HEX: ffffffff
+ALIAS: CLR_INVALID CLR_NONE
+CONSTANT: CLR_DEFAULT HEX: ff000000
+CONSTANT: PT_MOVETO 6
+CONSTANT: PT_LINETO 2
+CONSTANT: PT_BEZIERTO 4
+CONSTANT: PT_CLOSEFIGURE 1
+CONSTANT: TT_AVAILABLE 1
+CONSTANT: TT_ENABLED 2
+CONSTANT: BLACK_BRUSH 4
+CONSTANT: DKGRAY_BRUSH 3
+CONSTANT: GRAY_BRUSH 2
+CONSTANT: HOLLOW_BRUSH 5
+CONSTANT: LTGRAY_BRUSH 1
+CONSTANT: NULL_BRUSH 5
+CONSTANT: WHITE_BRUSH 0
+CONSTANT: BLACK_PEN 7
+CONSTANT: NULL_PEN 8
+CONSTANT: WHITE_PEN 6
+CONSTANT: ANSI_FIXED_FONT 11
+CONSTANT: ANSI_VAR_FONT 12
 CONSTANT: DEVICE_DEFAULT_FONT 14
-CONSTANT: DEFAULT_PALETTE     15
-CONSTANT: SYSTEM_FIXED_FONT   16
-CONSTANT: DEFAULT_GUI_FONT    17
-CONSTANT: DC_BRUSH            18
-CONSTANT: DC_PEN              19
-                  
-CONSTANT: BI_RGB        0
-CONSTANT: BI_RLE8       1
-CONSTANT: BI_RLE4       2
-CONSTANT: BI_BITFIELDS  3
+CONSTANT: DEFAULT_GUI_FONT 17
+CONSTANT: OEM_FIXED_FONT 10
+CONSTANT: SYSTEM_FONT 13
+CONSTANT: SYSTEM_FIXED_FONT 16
+CONSTANT: DEFAULT_PALETTE 15
+CONSTANT: DC_BRUSH 18
+CONSTANT: DC_PEN 19
+CONSTANT: SYSPAL_ERROR 0
+CONSTANT: SYSPAL_STATIC 1
+CONSTANT: SYSPAL_NOSTATIC 2
+CONSTANT: SYSPAL_NOSTATIC256 3 
+CONSTANT: TA_BASELINE 24
+CONSTANT: TA_BOTTOM 8
+CONSTANT: TA_TOP 0
+CONSTANT: TA_CENTER 6
+CONSTANT: TA_LEFT 0
+CONSTANT: TA_RIGHT 2
+CONSTANT: TA_RTLREADING 256
+CONSTANT: TA_NOUPDATECP 0
+CONSTANT: TA_UPDATECP 1
+: TA_MASK ( -- n ) { TA_BASELINE TA_CENTER TA_UPDATECP TA_RTLREADING } flags ; foldable
+CONSTANT: VTA_BASELINE 24
+CONSTANT: VTA_CENTER 6
+ALIAS: VTA_LEFT TA_BOTTOM
+ALIAS: VTA_RIGHT TA_TOP
+ALIAS: VTA_BOTTOM TA_RIGHT
+ALIAS: VTA_TOP TA_LEFT
+CONSTANT: MWT_IDENTITY 1
+CONSTANT: MWT_LEFTMULTIPLY 2
+CONSTANT: MWT_RIGHTMULTIPLY 3
+CONSTANT: OPAQUE 2
+CONSTANT: TRANSPARENT 1
+CONSTANT: BLACKONWHITE 1
+CONSTANT: WHITEONBLACK 2
+CONSTANT: COLORONCOLOR 3
+CONSTANT: HALFTONE 4
+CONSTANT: MAXSTRETCHBLTMODE 4
+CONSTANT: STRETCH_ANDSCANS 1
+CONSTANT: STRETCH_DELETESCANS 3
+CONSTANT: STRETCH_HALFTONE 4
+CONSTANT: STRETCH_ORSCANS 2
+CONSTANT: TCI_SRCCHARSET 1
+CONSTANT: TCI_SRCCODEPAGE 2
+CONSTANT: TCI_SRCFONTSIG 3
+CONSTANT: ICM_ON 2
+CONSTANT: ICM_OFF 1
+CONSTANT: ICM_QUERY 3
+CONSTANT: NEWFRAME 1
+CONSTANT: ABORTDOC 2
+CONSTANT: NEXTBAND 3
+CONSTANT: SETCOLORTABLE 4
+CONSTANT: GETCOLORTABLE 5
+CONSTANT: FLUSHOUTPUT 6
+CONSTANT: DRAFTMODE 7
+CONSTANT: QUERYESCSUPPORT 8
+CONSTANT: SETABORTPROC 9
+CONSTANT: STARTDOC 10
+CONSTANT: ENDDOC 11
+CONSTANT: GETPHYSPAGESIZE 12
+CONSTANT: GETPRINTINGOFFSET 13
+CONSTANT: GETSCALINGFACTOR 14
+CONSTANT: MFCOMMENT 15
+CONSTANT: GETPENWIDTH 16
+CONSTANT: SETCOPYCOUNT 17
+CONSTANT: SELECTPAPERSOURCE 18
+CONSTANT: DEVICEDATA 19
+CONSTANT: PASSTHROUGH 19
+CONSTANT: GETTECHNOLGY 20
+CONSTANT: GETTECHNOLOGY 20
+CONSTANT: SETLINECAP 21
+CONSTANT: SETLINEJOIN 22
+CONSTANT: SETMITERLIMIT 23
+CONSTANT: BANDINFO 24
+CONSTANT: DRAWPATTERNRECT 25
+CONSTANT: GETVECTORPENSIZE 26
+CONSTANT: GETVECTORBRUSHSIZE 27
+CONSTANT: ENABLEDUPLEX 28
+CONSTANT: GETSETPAPERBINS 29
+CONSTANT: GETSETPRINTORIENT 30
+CONSTANT: ENUMPAPERBINS 31
+CONSTANT: SETDIBSCALING 32
+CONSTANT: EPSPRINTING 33
+CONSTANT: ENUMPAPERMETRICS 34
+CONSTANT: GETSETPAPERMETRICS 35
+CONSTANT: POSTSCRIPT_DATA 37
+CONSTANT: POSTSCRIPT_IGNORE 38
+CONSTANT: MOUSETRAILS 39
+CONSTANT: GETDEVICEUNITS 42
+CONSTANT: GETEXTENDEDTEXTMETRICS 256
+CONSTANT: GETEXTENTTABLE 257
+CONSTANT: GETPAIRKERNTABLE 258
+CONSTANT: GETTRACKKERNTABLE 259
+CONSTANT: EXTTEXTOUT 512
+CONSTANT: GETFACENAME 513
+CONSTANT: DOWNLOADFACE 514
+CONSTANT: ENABLERELATIVEWIDTHS 768
+CONSTANT: ENABLEPAIRKERNING 769
+CONSTANT: SETKERNTRACK 770
+CONSTANT: SETALLJUSTVALUES 771
+CONSTANT: SETCHARSET 772
+CONSTANT: STRETCHBLT 2048
+CONSTANT: GETSETSCREENPARAMS 3072
+CONSTANT: QUERYDIBSUPPORT 3073
+CONSTANT: BEGIN_PATH 4096
+CONSTANT: CLIP_TO_PATH 4097
+CONSTANT: END_PATH 4098
+CONSTANT: EXT_DEVICE_CAPS 4099
+CONSTANT: RESTORE_CTM 4100
+CONSTANT: SAVE_CTM 4101
+CONSTANT: SET_ARC_DIRECTION 4102
+CONSTANT: SET_BACKGROUND_COLOR 4103
+CONSTANT: SET_POLY_MODE 4104
+CONSTANT: SET_SCREEN_ANGLE 4105
+CONSTANT: SET_SPREAD 4106
+CONSTANT: TRANSFORM_CTM 4107
+CONSTANT: SET_CLIP_BOX 4108
+CONSTANT: SET_BOUNDS 4109
+CONSTANT: SET_MIRROR_MODE 4110
+CONSTANT: OPENCHANNEL 4110
+CONSTANT: DOWNLOADHEADER 4111
+CONSTANT: CLOSECHANNEL 4112
+CONSTANT: POSTSCRIPT_PASSTHROUGH 4115
+CONSTANT: ENCAPSULATED_POSTSCRIPT 4116
+CONSTANT: QDI_SETDIBITS 1
+CONSTANT: QDI_GETDIBITS 2
+CONSTANT: QDI_DIBTOSCREEN 4
+CONSTANT: QDI_STRETCHDIB 8
+CONSTANT: SP_NOTREPORTED HEX: 4000
+CONSTANT: PR_JOBSTATUS 0
+CONSTANT: ASPECT_FILTERING 1
+CONSTANT: BS_SOLID 0
+CONSTANT: BS_NULL 1
+CONSTANT: BS_HOLLOW 1
+CONSTANT: BS_HATCHED 2
+CONSTANT: BS_PATTERN 3
+CONSTANT: BS_INDEXED 4
+CONSTANT: BS_DIBPATTERN 5
+CONSTANT: BS_DIBPATTERNPT 6
+CONSTANT: BS_PATTERN8X8 7
+CONSTANT: BS_DIBPATTERN8X8 8
+CONSTANT: LCS_CALIBRATED_RGB 0
+CONSTANT: LCS_DEVICE_RGB 1
+CONSTANT: LCS_DEVICE_CMYK 2
+CONSTANT: LCS_GM_BUSINESS 1
+CONSTANT: LCS_GM_GRAPHICS 2
+CONSTANT: LCS_GM_IMAGES 4
+CONSTANT: RASTER_FONTTYPE 1
+CONSTANT: DEVICE_FONTTYPE 2
+CONSTANT: TRUETYPE_FONTTYPE 4
+CONSTANT: DMORIENT_PORTRAIT 1
+CONSTANT: DMORIENT_LANDSCAPE 2
+CONSTANT: DMPAPER_FIRST 1
+CONSTANT: DMPAPER_LETTER 1
+CONSTANT: DMPAPER_LETTERSMALL 2
+CONSTANT: DMPAPER_TABLOID 3
+CONSTANT: DMPAPER_LEDGER 4
+CONSTANT: DMPAPER_LEGAL 5
+CONSTANT: DMPAPER_STATEMENT 6
+CONSTANT: DMPAPER_EXECUTIVE 7
+CONSTANT: DMPAPER_A3 8
+CONSTANT: DMPAPER_A4 9
+CONSTANT: DMPAPER_A4SMALL 10
+CONSTANT: DMPAPER_A5 11
+CONSTANT: DMPAPER_B4 12
+CONSTANT: DMPAPER_B5 13
+CONSTANT: DMPAPER_FOLIO 14
+CONSTANT: DMPAPER_QUARTO 15
+CONSTANT: DMPAPER_10X14 16
+CONSTANT: DMPAPER_11X17 17
+CONSTANT: DMPAPER_NOTE 18
+CONSTANT: DMPAPER_ENV_9 19
+CONSTANT: DMPAPER_ENV_10 20
+CONSTANT: DMPAPER_ENV_11 21
+CONSTANT: DMPAPER_ENV_12 22
+CONSTANT: DMPAPER_ENV_14 23
+CONSTANT: DMPAPER_CSHEET 24
+CONSTANT: DMPAPER_DSHEET 25
+CONSTANT: DMPAPER_ESHEET 26
+CONSTANT: DMPAPER_ENV_DL 27
+CONSTANT: DMPAPER_ENV_C5 28
+CONSTANT: DMPAPER_ENV_C3 29
+CONSTANT: DMPAPER_ENV_C4 30
+CONSTANT: DMPAPER_ENV_C6 31
+CONSTANT: DMPAPER_ENV_C65 32
+CONSTANT: DMPAPER_ENV_B4 33
+CONSTANT: DMPAPER_ENV_B5 34
+CONSTANT: DMPAPER_ENV_B6 35
+CONSTANT: DMPAPER_ENV_ITALY 36
+CONSTANT: DMPAPER_ENV_MONARCH 37
+CONSTANT: DMPAPER_ENV_PERSONAL 38
+CONSTANT: DMPAPER_FANFOLD_US 39
+CONSTANT: DMPAPER_FANFOLD_STD_GERMAN 40
+CONSTANT: DMPAPER_FANFOLD_LGL_GERMAN 41
+CONSTANT: DMPAPER_ISO_B4 42
+CONSTANT: DMPAPER_JAPANESE_POSTCARD 43
+CONSTANT: DMPAPER_9X11 44
+CONSTANT: DMPAPER_10X11 45
+CONSTANT: DMPAPER_15X11 46
+CONSTANT: DMPAPER_ENV_INVITE 47
+CONSTANT: DMPAPER_RESERVED_48 48
+CONSTANT: DMPAPER_RESERVED_49 49
+CONSTANT: DMPAPER_LETTER_EXTRA 50
+CONSTANT: DMPAPER_LEGAL_EXTRA 51
+CONSTANT: DMPAPER_TABLOID_EXTRA 52
+CONSTANT: DMPAPER_A4_EXTRA 53
+CONSTANT: DMPAPER_LETTER_TRANSVERSE 54
+CONSTANT: DMPAPER_A4_TRANSVERSE 55
+CONSTANT: DMPAPER_LETTER_EXTRA_TRANSVERSE 56
+CONSTANT: DMPAPER_A_PLUS 57
+CONSTANT: DMPAPER_B_PLUS 58
+CONSTANT: DMPAPER_LETTER_PLUS 59
+CONSTANT: DMPAPER_A4_PLUS 60
+CONSTANT: DMPAPER_A5_TRANSVERSE 61
+CONSTANT: DMPAPER_B5_TRANSVERSE 62
+CONSTANT: DMPAPER_A3_EXTRA 63
+CONSTANT: DMPAPER_A5_EXTRA 64
+CONSTANT: DMPAPER_B5_EXTRA 65
+CONSTANT: DMPAPER_A2 66
+CONSTANT: DMPAPER_A3_TRANSVERSE 67
+CONSTANT: DMPAPER_A3_EXTRA_TRANSVERSE 68
+CONSTANT: DMPAPER_DBL_JAPANESE_POSTCARD 69
+CONSTANT: DMPAPER_A6 70
+CONSTANT: DMPAPER_JENV_KAKU2 71
+CONSTANT: DMPAPER_JENV_KAKU3 72
+CONSTANT: DMPAPER_JENV_CHOU3 73
+CONSTANT: DMPAPER_JENV_CHOU4 74
+CONSTANT: DMPAPER_LETTER_ROTATED 75
+CONSTANT: DMPAPER_A3_ROTATED 76
+CONSTANT: DMPAPER_A4_ROTATED 77
+CONSTANT: DMPAPER_A5_ROTATED 78
+CONSTANT: DMPAPER_B4_JIS_ROTATED 79
+CONSTANT: DMPAPER_B5_JIS_ROTATED 80
+CONSTANT: DMPAPER_JAPANESE_POSTCARD_ROTATED 81
+CONSTANT: DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED 82
+CONSTANT: DMPAPER_A6_ROTATED 83
+CONSTANT: DMPAPER_JENV_KAKU2_ROTATED 84
+CONSTANT: DMPAPER_JENV_KAKU3_ROTATED 85
+CONSTANT: DMPAPER_JENV_CHOU3_ROTATED 86
+CONSTANT: DMPAPER_JENV_CHOU4_ROTATED 87
+CONSTANT: DMPAPER_B6_JIS 88
+CONSTANT: DMPAPER_B6_JIS_ROTATED 89
+CONSTANT: DMPAPER_12X11 90
+CONSTANT: DMPAPER_JENV_YOU4 91
+CONSTANT: DMPAPER_JENV_YOU4_ROTATED 92
+CONSTANT: DMPAPER_P16K 93
+CONSTANT: DMPAPER_P32K 94
+CONSTANT: DMPAPER_P32KBIG 95
+CONSTANT: DMPAPER_PENV_1 96
+CONSTANT: DMPAPER_PENV_2 97
+CONSTANT: DMPAPER_PENV_3 98
+CONSTANT: DMPAPER_PENV_4 99
+CONSTANT: DMPAPER_PENV_5 100
+CONSTANT: DMPAPER_PENV_6 101
+CONSTANT: DMPAPER_PENV_7 102
+CONSTANT: DMPAPER_PENV_8 103
+CONSTANT: DMPAPER_PENV_9 104
+CONSTANT: DMPAPER_PENV_10 105
+CONSTANT: DMPAPER_P16K_ROTATED 106
+CONSTANT: DMPAPER_P32K_ROTATED 107
+CONSTANT: DMPAPER_P32KBIG_ROTATED 108
+CONSTANT: DMPAPER_PENV_1_ROTATED 109
+CONSTANT: DMPAPER_PENV_2_ROTATED 110
+CONSTANT: DMPAPER_PENV_3_ROTATED 111
+CONSTANT: DMPAPER_PENV_4_ROTATED 112
+CONSTANT: DMPAPER_PENV_5_ROTATED 113
+CONSTANT: DMPAPER_PENV_6_ROTATED 114
+CONSTANT: DMPAPER_PENV_7_ROTATED 115
+CONSTANT: DMPAPER_PENV_8_ROTATED 116
+CONSTANT: DMPAPER_PENV_9_ROTATED 117
+CONSTANT: DMPAPER_PENV_10_ROTATED 118
+CONSTANT: DMPAPER_LAST 118
+CONSTANT: DMPAPER_USER 256
+CONSTANT: DMBIN_FIRST 1
+CONSTANT: DMBIN_UPPER 1
+CONSTANT: DMBIN_ONLYONE 1
+CONSTANT: DMBIN_LOWER 2
+CONSTANT: DMBIN_MIDDLE 3
+CONSTANT: DMBIN_MANUAL 4
+CONSTANT: DMBIN_ENVELOPE 5
+CONSTANT: DMBIN_ENVMANUAL 6
+CONSTANT: DMBIN_AUTO 7
+CONSTANT: DMBIN_TRACTOR 8
+CONSTANT: DMBIN_SMALLFMT 9
+CONSTANT: DMBIN_LARGEFMT 10
+CONSTANT: DMBIN_LARGECAPACITY 11
+CONSTANT: DMBIN_CASSETTE 14
+CONSTANT: DMBIN_FORMSOURCE 15
+CONSTANT: DMBIN_LAST 15
+CONSTANT: DMBIN_USER 256
+CONSTANT: DMRES_DRAFT -1
+CONSTANT: DMRES_LOW -2
+CONSTANT: DMRES_MEDIUM -3
+CONSTANT: DMRES_HIGH -4
+CONSTANT: DMCOLOR_MONOCHROME 1
+CONSTANT: DMCOLOR_COLOR 2
+CONSTANT: DMDUP_SIMPLEX 1
+CONSTANT: DMDUP_VERTICAL 2
+CONSTANT: DMDUP_HORIZONTAL 3
+CONSTANT: DMTT_BITMAP 1
+CONSTANT: DMTT_DOWNLOAD 2
+CONSTANT: DMTT_SUBDEV 3
+CONSTANT: DMTT_DOWNLOAD_OUTLINE 4
+CONSTANT: DMCOLLATE_FALSE 0
+CONSTANT: DMCOLLATE_TRUE 1
+CONSTANT: DM_SPECVERSION 800
+CONSTANT: DM_GRAYSCALE 1
+CONSTANT: DM_INTERLACED 2
+CONSTANT: DM_UPDATE 1
+CONSTANT: DM_COPY 2
+CONSTANT: DM_PROMPT 4
+CONSTANT: DM_MODIFY 8
+ALIAS: DM_IN_BUFFER DM_MODIFY
+ALIAS: DM_IN_PROMPT DM_PROMPT
+ALIAS: DM_OUT_BUFFER DM_COPY
+ALIAS: DM_OUT_DEFAULT DM_UPDATE
+CONSTANT: DM_ORIENTATION HEX: 00000001
+CONSTANT: DM_PAPERSIZE HEX: 00000002
+CONSTANT: DM_PAPERLENGTH HEX: 00000004
+CONSTANT: DM_PAPERWIDTH HEX: 00000008
+CONSTANT: DM_SCALE HEX: 00000010
+CONSTANT: DM_POSITION HEX: 00000020
+CONSTANT: DM_COPIES HEX: 00000100
+CONSTANT: DM_DEFAULTSOURCE HEX: 00000200
+CONSTANT: DM_PRINTQUALITY HEX: 00000400
+CONSTANT: DM_COLOR HEX: 00000800
+CONSTANT: DM_DUPLEX HEX: 00001000
+CONSTANT: DM_YRESOLUTION HEX: 00002000
+CONSTANT: DM_TTOPTION HEX: 00004000
+CONSTANT: DM_COLLATE HEX: 00008000
+CONSTANT: DM_FORMNAME HEX: 00010000
+CONSTANT: DM_LOGPIXELS HEX: 00020000
+CONSTANT: DM_BITSPERPEL HEX: 00040000
+CONSTANT: DM_PELSWIDTH HEX: 00080000
+CONSTANT: DM_PELSHEIGHT HEX: 00100000
+CONSTANT: DM_DISPLAYFLAGS HEX: 00200000
+CONSTANT: DM_DISPLAYFREQUENCY HEX: 00400000
+CONSTANT: DM_ICMMETHOD HEX: 00800000
+CONSTANT: DM_ICMINTENT HEX: 01000000
+CONSTANT: DM_MEDIATYPE HEX: 02000000
+CONSTANT: DM_DITHERTYPE HEX: 04000000
+CONSTANT: DM_PANNINGWIDTH HEX: 08000000
+CONSTANT: DM_PANNINGHEIGHT HEX: 10000000
+CONSTANT: DM_DISPLAYFIXEDOUTPUT HEX: 20000000
+CONSTANT: DM_DISPLAYORIENTATION HEX: 00000080
+CONSTANT: DMDO_DEFAULT HEX: 00000000
+CONSTANT: DMDO_90 HEX: 00000001
+CONSTANT: DMDO_180 HEX: 00000002
+CONSTANT: DMDO_270 HEX: 00000003
+CONSTANT: DMDFO_DEFAULT HEX: 00000000
+CONSTANT: DMDFO_STRETCH HEX: 00000001
+CONSTANT: DMDFO_CENTER HEX: 00000002
+CONSTANT: DMICMMETHOD_NONE 1
+CONSTANT: DMICMMETHOD_SYSTEM 2
+CONSTANT: DMICMMETHOD_DRIVER 3
+CONSTANT: DMICMMETHOD_DEVICE 4
+CONSTANT: DMICMMETHOD_USER 256
+CONSTANT: DMICM_SATURATE 1
+CONSTANT: DMICM_CONTRAST 2
+CONSTANT: DMICM_COLORMETRIC 3
+CONSTANT: DMICM_USER 256
+CONSTANT: DMMEDIA_STANDARD 1
+CONSTANT: DMMEDIA_TRANSPARENCY 2
+CONSTANT: DMMEDIA_GLOSSY 3
+CONSTANT: DMMEDIA_USER 256
+CONSTANT: DMDITHER_NONE 1
+CONSTANT: DMDITHER_COARSE 2
+CONSTANT: DMDITHER_FINE 3
+CONSTANT: DMDITHER_LINEART 4
+CONSTANT: DMDITHER_ERRORDIFFUSION 5
+CONSTANT: DMDITHER_RESERVED6 6
+CONSTANT: DMDITHER_RESERVED7 7
+CONSTANT: DMDITHER_RESERVED8 8
+CONSTANT: DMDITHER_RESERVED9 9
+CONSTANT: DMDITHER_GRAYSCALE 10
+CONSTANT: DMDITHER_USER 256
+CONSTANT: GDI_ERROR HEX: FFFFFFFF
+: HGDI_ERROR ( -- alien ) GDI_ERROR <alien> ; inline
+CONSTANT: TMPF_FIXED_PITCH 1
+CONSTANT: TMPF_VECTOR 2
+CONSTANT: TMPF_TRUETYPE 4
+CONSTANT: TMPF_DEVICE 8
+CONSTANT: NTM_ITALIC 1
+CONSTANT: NTM_BOLD 32
+CONSTANT: NTM_REGULAR 64
+CONSTANT: TT_POLYGON_TYPE 24
+CONSTANT: TT_PRIM_LINE 1
+CONSTANT: TT_PRIM_QSPLINE 2
+CONSTANT: TT_PRIM_CSPLINE 3 
+CONSTANT: FONTMAPPER_MAX 10
+CONSTANT: ENHMETA_STOCK_OBJECT HEX: 80000000
+CONSTANT: WGL_FONT_LINES 0
+CONSTANT: WGL_FONT_POLYGONS 1
+CONSTANT: LPD_DOUBLEBUFFER 1
+CONSTANT: LPD_STEREO 2
+CONSTANT: LPD_SUPPORT_GDI 16
+CONSTANT: LPD_SUPPORT_OPENGL 32
+CONSTANT: LPD_SHARE_DEPTH 64
+CONSTANT: LPD_SHARE_STENCIL 128
+CONSTANT: LPD_SHARE_ACCUM 256
+CONSTANT: LPD_SWAP_EXCHANGE 512
+CONSTANT: LPD_SWAP_COPY 1024
+CONSTANT: LPD_TRANSPARENT 4096
+CONSTANT: LPD_TYPE_RGBA 0
+CONSTANT: LPD_TYPE_COLORINDEX 1
+CONSTANT: WGL_SWAP_MAIN_PLANE 1
+CONSTANT: WGL_SWAP_OVERLAY1 2
+CONSTANT: WGL_SWAP_OVERLAY2 4
+CONSTANT: WGL_SWAP_OVERLAY3 8
+CONSTANT: WGL_SWAP_OVERLAY4 16
+CONSTANT: WGL_SWAP_OVERLAY5 32
+CONSTANT: WGL_SWAP_OVERLAY6 64
+CONSTANT: WGL_SWAP_OVERLAY7 128
+CONSTANT: WGL_SWAP_OVERLAY8 256
+CONSTANT: WGL_SWAP_OVERLAY9 512
+CONSTANT: WGL_SWAP_OVERLAY10 1024
+CONSTANT: WGL_SWAP_OVERLAY11 2048
+CONSTANT: WGL_SWAP_OVERLAY12 4096
+CONSTANT: WGL_SWAP_OVERLAY13 8192
+CONSTANT: WGL_SWAP_OVERLAY14 16384
+CONSTANT: WGL_SWAP_OVERLAY15 32768
+CONSTANT: WGL_SWAP_UNDERLAY1 65536
+CONSTANT: WGL_SWAP_UNDERLAY2 HEX: 20000
+CONSTANT: WGL_SWAP_UNDERLAY3 HEX: 40000
+CONSTANT: WGL_SWAP_UNDERLAY4 HEX: 80000
+CONSTANT: WGL_SWAP_UNDERLAY5 HEX: 100000
+CONSTANT: WGL_SWAP_UNDERLAY6 HEX: 200000
+CONSTANT: WGL_SWAP_UNDERLAY7 HEX: 400000
+CONSTANT: WGL_SWAP_UNDERLAY8 HEX: 800000
+CONSTANT: WGL_SWAP_UNDERLAY9 HEX: 1000000
+CONSTANT: WGL_SWAP_UNDERLAY10 HEX: 2000000
+CONSTANT: WGL_SWAP_UNDERLAY11 HEX: 4000000
+CONSTANT: WGL_SWAP_UNDERLAY12 HEX: 8000000
+CONSTANT: WGL_SWAP_UNDERLAY13 HEX: 10000000
+CONSTANT: WGL_SWAP_UNDERLAY14 HEX: 20000000
+CONSTANT: WGL_SWAP_UNDERLAY15 HEX: 40000000
+CONSTANT: AC_SRC_OVER HEX: 00
+CONSTANT: AC_SRC_ALPHA HEX: 01
+CONSTANT: AC_SRC_NO_PREMULT_ALPHA HEX: 01
+CONSTANT: AC_SRC_NO_ALPHA HEX: 02
+CONSTANT: AC_DST_NO_PREMULT_ALPHA HEX: 10
+CONSTANT: AC_DST_NO_ALPHA HEX: 20
+CONSTANT: LAYOUT_RTL 1
+CONSTANT: LAYOUT_BITMAPORIENTATIONPRESERVED 8
+CONSTANT: CS_ENABLE HEX: 00000001
+CONSTANT: CS_DISABLE HEX: 00000002
+CONSTANT: CS_DELETE_TRANSFORM HEX: 00000003
+CONSTANT: GRADIENT_FILL_RECT_H HEX: 00
+CONSTANT: GRADIENT_FILL_RECT_V HEX: 01
+CONSTANT: GRADIENT_FILL_TRIANGLE HEX: 02
+CONSTANT: GRADIENT_FILL_OP_FLAG HEX: ff
+CONSTANT: COLORMATCHTOTARGET_EMBEDED HEX: 00000001
+CONSTANT: CREATECOLORSPACE_EMBEDED HEX: 00000001
+CONSTANT: SETICMPROFILE_EMBEDED HEX: 00000001
 
-CONSTANT: DIB_RGB_COLORS 0
-CONSTANT: DIB_PAL_COLORS 1
+CONSTANT: DISPLAY_DEVICE_ATTACHED_TO_DESKTOP HEX: 00000001
+CONSTANT: DISPLAY_DEVICE_MULTI_DRIVER HEX: 00000002
+CONSTANT: DISPLAY_DEVICE_PRIMARY_DEVICE HEX: 00000004
+CONSTANT: DISPLAY_DEVICE_MIRRORING_DRIVER HEX: 00000008
+CONSTANT: DISPLAY_DEVICE_VGA_COMPATIBLE HEX: 00000010
+CONSTANT: DISPLAY_DEVICE_REMOVABLE HEX: 00000020
+CONSTANT: DISPLAY_DEVICE_MODESPRUNED HEX: 08000000
+
+CONSTANT: NTM_NONNEGATIVE_AC HEX: 00010000
+CONSTANT: NTM_PS_OPENTYPE HEX: 00020000
+CONSTANT: NTM_TT_OPENTYPE HEX: 00040000
+CONSTANT: NTM_MULTIPLEMASTER HEX: 00080000
+CONSTANT: NTM_TYPE1 HEX: 00100000
+CONSTANT: NTM_DSIG HEX: 00200000
+
+CONSTANT: GGI_MARK_NONEXISTING_GLYPHS 1
 
 LIBRARY: gdi32
 
+! FUNCTION: AbortDoc
 ! FUNCTION: AbortPath
 ! FUNCTION: AddFontMemResourceEx
 ! FUNCTION: AddFontResourceA
@@ -100,7 +1335,8 @@ FUNCTION: HBITMAP CreateDIBSection ( HDC hdc, BITMAPINFO* pbmi, UINT iUsage, voi
 ! FUNCTION: CreateFontIndirectExA
 ! FUNCTION: CreateFontIndirectExW
 ! FUNCTION: CreateFontIndirectW
-! FUNCTION: CreateFontW
+FUNCTION: HFONT CreateFontW ( int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace ) ;
+ALIAS: CreateFont CreateFontW
 ! FUNCTION: CreateHalftonePalette
 ! FUNCTION: CreateHatchBrush
 ! FUNCTION: CreateICA
@@ -118,7 +1354,7 @@ FUNCTION: HRGN CreateRectRgn ( int x, int y, int w, int h ) ;
 ! FUNCTION: CreateRoundRectRgn
 ! FUNCTION: CreateScalableFontResourceA
 ! FUNCTION: CreateScalableFontResourceW
-! FUNCTION: CreateSolidBrush
+FUNCTION: HBRUSH CreateSolidBrush ( COLORREF colorref ) ;
 ! FUNCTION: DdEntry0
 ! FUNCTION: DdEntry1
 ! FUNCTION: DdEntry10
@@ -178,9 +1414,11 @@ FUNCTION: HRGN CreateRectRgn ( int x, int y, int w, int h ) ;
 ! FUNCTION: DdEntry9
 ! FUNCTION: DeleteColorSpace
 FUNCTION: BOOL DeleteDC ( HDC hdc ) ;
+DESTRUCTOR: DeleteDC
 ! FUNCTION: DeleteEnhMetaFile
 ! FUNCTION: DeleteMetaFile
 FUNCTION: BOOL DeleteObject ( HGDIOBJ hObject ) ;
+DESTRUCTOR: DeleteObject
 ! FUNCTION: DescribePixelFormat
 ! FUNCTION: DeviceCapabilitiesExA
 ! FUNCTION: DeviceCapabilitiesExW
@@ -260,8 +1498,10 @@ FUNCTION: BOOL DeleteObject ( HGDIOBJ hObject ) ;
 ! FUNCTION: ExtFloodFill
 ! FUNCTION: ExtSelectClipRgn
 ! FUNCTION: ExtTextOutA
-! FUNCTION: ExtTextOutW
+FUNCTION: BOOL ExtTextOutW ( HDC hdc, int X, int Y, UINT fuOptions, RECT* lprc, LPCTSTR lpString, UINT cbCount, INT* lpDx ) ;
+ALIAS: ExtTextOut ExtTextOutW
 ! FUNCTION: FillPath
+FUNCTION: int FillRect ( HDC hDC, RECT* lprc, HBRUSH hbr ) ;
 ! FUNCTION: FillRgn
 ! FUNCTION: FixBrushOrgEx
 ! FUNCTION: FlattenPath
@@ -484,7 +1724,8 @@ FUNCTION: HGDIOBJ GetStockObject ( int fnObject ) ;
 ! FUNCTION: GetTextFaceAliasW
 ! FUNCTION: GetTextFaceW
 ! FUNCTION: GetTextMetricsA
-! FUNCTION: GetTextMetricsW
+FUNCTION: BOOL GetTextMetricsW ( HDC hdc, LPTEXTMETRIC lptm ) ;
+ALIAS: GetTextMetrics GetTextMetricsW
 ! FUNCTION: GetTransform
 ! FUNCTION: GetViewportExtEx
 ! FUNCTION: GetViewportOrgEx
@@ -539,7 +1780,7 @@ FUNCTION: HGDIOBJ GetStockObject ( int fnObject ) ;
 ! FUNCTION: PtVisible
 ! FUNCTION: QueryFontAssocStatus
 ! FUNCTION: RealizePalette
-! FUNCTION: Rectangle
+FUNCTION: BOOL Rectangle ( HDC hdc, int x, int y, int w, int h ) ;
 ! FUNCTION: RectInRegion
 ! FUNCTION: RectVisible
 ! FUNCTION: RemoveFontMemResourceEx
@@ -567,15 +1808,15 @@ FUNCTION: HGDIOBJ SelectObject ( HDC hdc, HGDIOBJ hgdiobj ) ;
 ! FUNCTION: SetBitmapAttributes
 ! FUNCTION: SetBitmapBits
 ! FUNCTION: SetBitmapDimensionEx
-! FUNCTION: SetBkColor
+FUNCTION: COLORREF SetBkColor ( HDC hdc, COLORREF color ) ;
 ! FUNCTION: SetBkMode
 ! FUNCTION: SetBoundsRect
 ! FUNCTION: SetBrushAttributes
 ! FUNCTION: SetBrushOrgEx
 ! FUNCTION: SetColorAdjustment
 ! FUNCTION: SetColorSpace
-! FUNCTION: SetDCBrushColor
-! FUNCTION: SetDCPenColor
+FUNCTION: COLORREF SetDCBrushColor ( HDC hdc, COLORREF color ) ;
+FUNCTION: COLORREF SetDCPenColor ( HDC hdc, COLORREF color ) ;
 ! FUNCTION: SetDeviceGammaRamp
 ! FUNCTION: SetDIBColorTable
 ! FUNCTION: SetDIBits
@@ -606,7 +1847,8 @@ FUNCTION: BOOL SetPixelFormat ( HDC hDC, int iPixelFormat, PFD* ppfd ) ;
 ! FUNCTION: SetSystemPaletteUse
 ! FUNCTION: SetTextAlign
 ! FUNCTION: SetTextCharacterExtra
-! FUNCTION: SetTextColor
+FUNCTION: COLORREF SetTextColor ( HDC hdc, COLORREF crColor ) ;
+! FUNCTION: SetTextColor ( HDC hDC, 
 ! FUNCTION: SetTextJustification
 ! FUNCTION: SetViewportExtEx
 ! FUNCTION: SetViewportOrgEx
index 85aa9918572040d1b1ded4ef142d34802f2c841c..e05a409e67e4f479ab29aef8183fcd8115df6ed7 100644 (file)
@@ -1,6 +1,7 @@
-USING: alien sequences ;
+USING: alien sequences alien.libraries ;
 {
     { "advapi32" "advapi32.dll" "stdcall" }
+    { "dinput"   "dinput8.dll"  "stdcall" }
     { "gdi32"    "gdi32.dll"    "stdcall" }
     { "user32"   "user32.dll"   "stdcall" }
     { "kernel32" "kernel32.dll" "stdcall" }
@@ -12,4 +13,5 @@ USING: alien sequences ;
     { "gl"       "opengl32.dll" "stdcall" }
     { "glu"      "glu32.dll"    "stdcall" }
     { "ole32"    "ole32.dll"    "stdcall" }
+    { "usp10"    "usp10.dll"    "stdcall" }
 } [ first3 add-library ] each
diff --git a/basis/windows/offscreen/authors.txt b/basis/windows/offscreen/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/windows/offscreen/offscreen-tests.factor b/basis/windows/offscreen/offscreen-tests.factor
new file mode 100755 (executable)
index 0000000..5827397
--- /dev/null
@@ -0,0 +1,5 @@
+IN: windows.offscreen.tests\r
+USING: windows.offscreen effects tools.test kernel images ;\r
+\r
+{ 1 1 } [ [ [ ] make-bitmap-image ] with-memory-dc ] must-infer-as\r
+[ t ] [ [ { 10 10 } swap [ ] make-bitmap-image ] with-memory-dc image? ] unit-test\r
diff --git a/basis/windows/offscreen/offscreen.factor b/basis/windows/offscreen/offscreen.factor
new file mode 100755 (executable)
index 0000000..6e65958
--- /dev/null
@@ -0,0 +1,53 @@
+! Copyright (C) 2009 Joe Groff, Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types kernel combinators sequences
+math windows.gdi32 windows.types images destructors
+accessors fry locals ;
+IN: windows.offscreen
+
+: (bitmap-info) ( dim -- BITMAPINFO )
+    "BITMAPINFO" <c-object> [
+        BITMAPINFO-bmiHeader {
+            [ nip "BITMAPINFOHEADER" heap-size swap set-BITMAPINFOHEADER-biSize ]
+            [ [ first ] dip set-BITMAPINFOHEADER-biWidth ]
+            [ [ second ] dip set-BITMAPINFOHEADER-biHeight ]
+            [ nip 1 swap set-BITMAPINFOHEADER-biPlanes ]
+            [ nip 32 swap set-BITMAPINFOHEADER-biBitCount ]
+            [ nip BI_RGB swap set-BITMAPINFOHEADER-biCompression ]
+            [ [ first2 * 4 * ] dip set-BITMAPINFOHEADER-biSizeImage ]
+            [ nip 72 swap set-BITMAPINFOHEADER-biXPelsPerMeter ]
+            [ nip 72 swap set-BITMAPINFOHEADER-biYPelsPerMeter ]
+            [ nip 0 swap set-BITMAPINFOHEADER-biClrUsed ]
+            [ nip 0 swap set-BITMAPINFOHEADER-biClrImportant ]
+        } 2cleave
+    ] keep ;
+
+: make-bitmap ( dim dc -- hBitmap bits )
+    [ nip ]
+    [
+        swap (bitmap-info) DIB_RGB_COLORS f <void*>
+        [ f 0 CreateDIBSection ] keep *void*
+    ] 2bi
+    [ [ SelectObject drop ] keep ] dip ;
+
+: make-offscreen-dc-and-bitmap ( dim -- dc hBitmap bits )
+    [ f CreateCompatibleDC ] dip over make-bitmap ;
+
+: bitmap>byte-array ( bits dim -- byte-array )
+    product 4 * memory>byte-array ;
+
+: bitmap>image ( bits dim -- image )
+    [ bitmap>byte-array ] keep
+    <image>
+        swap >>dim
+        swap >>bitmap
+        BGRX >>component-order
+        t >>upside-down? ;
+
+: with-memory-dc ( quot: ( hDC -- ) -- )
+    [ [ f CreateCompatibleDC &DeleteDC ] dip call ] with-destructors ; inline
+
+:: make-bitmap-image ( dim dc quot -- image )
+    dim dc make-bitmap [ &DeleteObject drop ] dip
+    quot dip
+    dim bitmap>image ; inline
\ No newline at end of file
diff --git a/basis/windows/offscreen/summary.txt b/basis/windows/offscreen/summary.txt
new file mode 100755 (executable)
index 0000000..dd70405
--- /dev/null
@@ -0,0 +1 @@
+Utility words for memory DCs and bitmaps\r
diff --git a/basis/windows/offscreen/tags.txt b/basis/windows/offscreen/tags.txt
new file mode 100755 (executable)
index 0000000..6abe115
--- /dev/null
@@ -0,0 +1 @@
+unportable\r
index ee74e47feaa223e86b7c1d2ba3dbb8417c4df412..20bae06f30d82fb872b9291c1ae81659bc6c2bf3 100755 (executable)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax namespaces kernel words ;
+USING: alien alien.c-types alien.syntax namespaces kernel words
+sequences math math.bitwise math.vectors colors ;
 IN: windows.types
 
 TYPEDEF: char                CHAR
@@ -244,14 +245,14 @@ C-STRUCT: RECT
     { "LONG" "right" }
     { "LONG" "bottom" } ;
 
-C-STRUCT: PAINTSTRUCT
-    { "HDC" " hdc" }
-    { "BOOL" "fErase" }
-    { "RECT" "rcPaint" }
-    { "BOOL" "fRestore" }
-    { "BOOL" "fIncUpdate" }
-    { "BYTE[32]" "rgbReserved" }
-;
+C-STRUCT: PAINTSTRUCT
+    { "HDC" " hdc" }
+    { "BOOL" "fErase" }
+    { "RECT" "rcPaint" }
+    { "BOOL" "fRestore" }
+    { "BOOL" "fIncUpdate" }
+    { "BYTE[32]" "rgbReserved" }
+;
 
 C-STRUCT: BITMAPINFOHEADER
     { "DWORD"  "biSize" }
@@ -283,6 +284,10 @@ C-STRUCT: POINT
     { "LONG" "x" }
     { "LONG" "y" } ; 
 
+C-STRUCT: SIZE
+    { "LONG" "cx" }
+    { "LONG" "cy" } ; 
+
 C-STRUCT: MSG
     { "HWND" "hWnd" }
     { "UINT" "message" }
@@ -327,6 +332,14 @@ C-STRUCT: RECT
     { "LONG" "right" }
     { "LONG" "bottom" } ;
 
+: <RECT> ( loc dim -- RECT )
+    over v+
+    "RECT" <c-object>
+    over first over set-RECT-right
+    swap second over set-RECT-bottom
+    over first over set-RECT-left
+    swap second over set-RECT-top ;
+
 TYPEDEF: RECT* PRECT
 TYPEDEF: RECT* LPRECT
 TYPEDEF: PIXELFORMATDESCRIPTOR PFD
@@ -363,3 +376,36 @@ C-STRUCT: ACCEL
     { "WORD" "key" }
     { "WORD" "cmd" } ;
 TYPEDEF: ACCEL* LPACCEL
+
+TYPEDEF: DWORD COLORREF
+TYPEDEF: DWORD* LPCOLORREF
+
+: RGB ( r g b -- COLORREF )
+    { 16 8 0 } bitfield ; inline
+
+: color>RGB ( color -- COLORREF )
+    >rgba-components drop [ 255 * >integer ] tri@ RGB ;
+
+C-STRUCT: TEXTMETRICW
+    { "LONG" "tmHeight" }
+    { "LONG" "tmAscent" }
+    { "LONG" "tmDescent" }
+    { "LONG" "tmInternalLeading" }
+    { "LONG" "tmExternalLeading" }
+    { "LONG" "tmAveCharWidth" }
+    { "LONG" "tmMaxCharWidth" }
+    { "LONG" "tmWeight" }
+    { "LONG" "tmOverhang" }
+    { "LONG" "tmDigitizedAspectX" }
+    { "LONG" "tmDigitizedAspectY" }
+    { "WCHAR" "tmFirstChar" }
+    { "WCHAR" "tmLastChar" }
+    { "WCHAR" "tmDefaultChar" }
+    { "WCHAR" "tmBreakChar" }
+    { "BYTE" "tmItalic" }
+    { "BYTE" "tmUnderlined" }
+    { "BYTE" "tmStruckOut" }
+    { "BYTE" "tmPitchAndFamily" }
+    { "BYTE" "tmCharSet" } ;
+
+TYPEDEF: TEXTMETRICW* LPTEXTMETRIC
diff --git a/basis/windows/uniscribe/authors.txt b/basis/windows/uniscribe/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/windows/uniscribe/summary.txt b/basis/windows/uniscribe/summary.txt
new file mode 100755 (executable)
index 0000000..7b71cf1
--- /dev/null
@@ -0,0 +1 @@
+High-level wrapper around Uniscribe binding\r
diff --git a/basis/windows/uniscribe/tags.txt b/basis/windows/uniscribe/tags.txt
new file mode 100755 (executable)
index 0000000..6abe115
--- /dev/null
@@ -0,0 +1 @@
+unportable\r
diff --git a/basis/windows/uniscribe/uniscribe.factor b/basis/windows/uniscribe/uniscribe.factor
new file mode 100755 (executable)
index 0000000..fb0c134
--- /dev/null
@@ -0,0 +1,115 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel assocs math sequences fry io.encodings.string
+io.encodings.utf16n accessors arrays combinators destructors
+cache namespaces init fonts alien.c-types windows windows.usp10
+windows.offscreen windows.gdi32 windows.ole32 windows.types
+windows.fonts opengl.textures locals ;
+IN: windows.uniscribe
+
+TUPLE: script-string font string metrics ssa size image disposed ;
+
+: line-offset>x ( n script-string -- x )
+    2dup string>> length = [
+        ssa>> ! ssa
+        swap 1- ! icp
+        TRUE ! fTrailing
+    ] [
+        ssa>>
+        swap ! icp
+        FALSE ! fTrailing
+    ] if
+    0 <int> [ ScriptStringCPtoX ole32-error ] keep *int ;
+
+: x>line-offset ( x script-string -- n trailing )
+    ssa>> ! ssa
+    swap ! iX
+    0 <int> ! pCh
+    0 <int> ! piTrailing
+    [ ScriptStringXtoCP ole32-error ] 2keep [ *int ] bi@ ;
+
+<PRIVATE
+
+: make-script-string ( dc string -- script-string )
+    dup selection? [ string>> ] when
+    [ utf16n encode ] ! pString
+    [ length ] bi ! cString
+    dup 1.5 * 16 + >integer ! cGlyphs -- MSDN says this is "recommended size"
+    -1 ! iCharset -- Unicode
+    SSA_GLYPHS ! dwFlags
+    0 ! iReqWidth
+    f ! psControl
+    f ! psState
+    f ! piDx
+    f ! pTabdef
+    f ! pbInClass
+    f <void*> ! pssa
+    [ ScriptStringAnalyse ] keep
+    [ ole32-error ] [ |ScriptStringFree *void* ] bi* ;
+
+: set-dc-colors ( dc font -- )
+    [ background>> color>RGB SetBkColor drop ]
+    [ foreground>> color>RGB SetTextColor drop ] 2bi ;
+
+: selection-start/end ( script-string -- iMinSel iMaxSel )
+    string>> dup selection? [ [ start>> ] [ end>> ] bi ] [ drop 0 0 ] if ;
+
+: (draw-script-string) ( script-string -- )
+    [
+        ssa>> ! ssa
+        0 ! iX
+        0 ! iY
+        ETO_OPAQUE ! uOptions
+    ]
+    [ [ { 0 0 } ] dip size>> <RECT> ]
+    [ selection-start/end ] tri
+    ! iMinSel
+    ! iMaxSel
+    FALSE ! fDisabled
+    ScriptStringOut ole32-error ;
+
+: draw-script-string ( dc script-string -- )
+    [ font>> set-dc-colors ] keep (draw-script-string) ;
+
+:: make-script-string-image ( dc script-string -- image )
+    script-string size>> dc
+    [ dc script-string draw-script-string ] make-bitmap-image ;
+
+: set-dc-font ( dc font -- )
+    cache-font SelectObject win32-error=0/f ;
+
+: script-string-size ( script-string -- dim )
+    ssa>> ScriptString_pSize
+    dup win32-error=0/f
+    [ SIZE-cx ] [ SIZE-cy ] bi 2array ;
+
+: dc-metrics ( dc -- metrics )
+    "TEXTMETRICW" <c-object>
+    [ GetTextMetrics drop ] keep
+    TEXTMETRIC>metrics ;
+
+: <script-string> ( font string -- script-string )
+    [ script-string new ] 2dip
+        [ >>font ] [ >>string ] bi*
+    [
+        {
+            [ over font>> set-dc-font ]
+            [ dc-metrics >>metrics ]
+            [ over string>> make-script-string >>ssa ]
+            [ drop dup script-string-size >>size ]
+            [ over make-script-string-image >>image ]
+        } cleave
+    ] with-memory-dc ;
+
+PRIVATE>
+
+M: script-string dispose*
+    ssa>> <void*> ScriptStringFree ole32-error ;
+
+SYMBOL: cached-script-strings
+
+: cached-script-string ( font string -- script-string )
+    cached-script-strings get-global [ <script-string> ] 2cache ;
+
+[ <cache-assoc> cached-script-strings set-global ]
+"windows.uniscribe" add-init-hook
diff --git a/basis/windows/usp10/authors.txt b/basis/windows/usp10/authors.txt
new file mode 100755 (executable)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/basis/windows/usp10/usp10.factor b/basis/windows/usp10/usp10.factor
new file mode 100755 (executable)
index 0000000..50fa989
--- /dev/null
@@ -0,0 +1,339 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax alien.destructors ;
+IN: windows.usp10
+
+LIBRARY: usp10
+
+C-STRUCT: SCRIPT_CONTROL
+    { "DWORD" "flags" } ;
+
+C-STRUCT: SCRIPT_STATE
+    { "WORD" "flags" } ;
+
+C-STRUCT: SCRIPT_ANALYSIS
+    { "WORD" "flags" }
+    { "SCRIPT_STATE" "s" } ;
+
+C-STRUCT: SCRIPT_ITEM
+    { "int" "iCharPos" }
+    { "SCRIPT_ANALYSIS" "a" } ;
+
+FUNCTION: HRESULT ScriptItemize (
+    WCHAR* pwcInChars,
+    int cInChars,
+    int cMaxItems,
+    SCRIPT_CONTROL* psControl,
+    SCRIPT_STATE* psState,
+    SCRIPT_ITEM* pItems,
+    int* pcItems
+) ;
+
+FUNCTION: HRESULT ScriptLayout (
+    int cRuns,
+    BYTE* pbLevel,
+    int* piVisualToLogical,
+    int* piLogicalToVisual
+) ;
+
+C-ENUM: SCRIPT_JUSTIFY_NONE
+SCRIPT_JUSTIFY_ARABIC_BLANK
+SCRIPT_JUSTIFY_CHARACTER
+SCRIPT_JUSTIFY_RESERVED1
+SCRIPT_JUSTIFY_BLANK
+SCRIPT_JUSTIFY_RESERVED2
+SCRIPT_JUSTIFY_RESERVED3
+SCRIPT_JUSTIFY_ARABIC_NORMAL
+SCRIPT_JUSTIFY_ARABIC_KASHIDA
+SCRIPT_JUSTIFY_ALEF
+SCRIPT_JUSTIFY_HA
+SCRIPT_JUSTIFY_RA
+SCRIPT_JUSTIFY_BA
+SCRIPT_JUSTIFY_BARA
+SCRIPT_JUSTIFY_SEEN
+SCRIPT_JUSTIFFY_RESERVED4 ;
+
+C-STRUCT: SCRIPT_VISATTR
+    { "WORD" "flags" } ;
+
+FUNCTION: HRESULT ScriptShape (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    WCHAR* pwcChars,
+    int cChars,
+    int cMaxGlyphs,
+    SCRIPT_ANALYSIS* psa,
+    WORD* pwOutGlyphs,
+    WORD* pwLogClust,
+    SCRIPT_VISATTR* psva,
+    int* pcGlyphs
+) ;
+
+C-STRUCT: GOFFSET
+    { "LONG" "du" }
+    { "LONG" "dv" } ;
+
+FUNCTION: HRESULT ScriptPlace (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    WORD* pwGlyphs,
+    int cGlyphs,
+    SCRIPT_VISATTR* psva,
+    SCRIPT_ANALYSIS* psa,
+    int* piAdvance,
+    GOFFSET* pGoffset,
+    ABC* pABC
+) ;
+
+FUNCTION: HRESULT ScriptTextOut (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    int x,
+    int y,
+    UINT fuOptions,
+    RECT* lprc,
+    SCRIPT_ANALYSIS* psa,
+    WCHAR* pwcReserved,
+    int iReserved,
+    WORD* pwGlyphs,
+    int cGlyphs,
+    int* piAdvance,
+    int* piJustify,
+    GOFFSET* pGoffset
+) ;
+
+FUNCTION: HRESULT ScriptJustify (
+    SCRIPT_VISATTR* psva,
+    int* piAdvance,
+    int cGlyphs,
+    int iDx,
+    int iMinKashida,
+    int* piJustify
+) ;
+
+C-STRUCT: SCRIPT_LOGATTR
+    { "BYTE" "flags" } ;
+
+FUNCTION: HRESULT ScriptBreak (
+    WCHAR* pwcChars,
+    int cChars,
+    SCRIPT_ANALYSIS* psa,
+    SCRIPT_LOGATTR* psla
+) ;
+
+FUNCTION: HRESULT ScriptCPtoX (
+    int iCP,
+    BOOL fTrailing,
+    int cChars,
+    int cGlyphs,
+    WORD* pwLogClust,
+    SCRIPT_VISATTR* psva,
+    int* piAdvance,
+    SCRIPT_ANALYSIS* psa,
+    int* piX
+) ;
+
+FUNCTION: HRESULT ScriptXtoCP (
+    int iCP,
+    BOOL fTrailing,
+    int cChars,
+    int cGlyphs,
+    WORD* pwLogClust,
+    SCRIPT_VISATTR* psva,
+    int* piAdvance,
+    SCRIPT_ANALYSIS* psa,
+    int* piCP,
+    int* piTrailing
+) ;
+
+FUNCTION: HRESULT ScriptGetLogicalWidths (
+    SCRIPT_ANALYSIS* psa,
+    int cChars,
+    int cGlyphs,
+    int* piGlyphWidth,
+    WORD* pwLogClust,
+    SCRIPT_VISATTR* psva,
+    int* piDx
+) ;
+
+FUNCTION: HRESULT ScriptApplyLogicalWidth (
+    int* piDx,
+    int cChars,
+    int cGlyphs,
+    WORD* pwLogClust,
+    SCRIPT_VISATTR* psva,
+    int* piAdvance,
+    SCRIPT_ANALYSIS* psa,
+    ABC* pABC,
+    int* piJustify
+) ;
+
+FUNCTION: HRESULT ScriptGetCMap (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    WCHAR* pwcInChars,
+    int cChars,
+    DWORD dwFlags,
+    WORD* pwOutGlyphs
+) ;
+
+FUNCTION: HRESULT ScriptGetGlyphABCWidth (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    WORD wGlyph,
+    ABC* pABC
+) ;
+
+C-STRUCT: SCRIPT_PROPERTIES
+    { "DWORD" "flags" } ;
+
+FUNCTION: HRESULT ScriptGetProperties (
+    SCRIPT_PROPERTIES*** ppSp,
+    int* piNumScripts
+) ;
+
+C-STRUCT: SCRIPT_FONTPROPERTIES
+    { "int" "cBytes" }
+    { "WORD" "wgBlank" }
+    { "WORD" "wgDefault" }
+    { "WORD" "wgInvalid" }
+    { "WORD" "wgKashida" }
+    { "int" "iKashidaWidth" } ;
+
+FUNCTION: HRESULT ScriptGetFontProperties (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    SCRIPT_FONTPROPERTIES* sfp
+) ;
+
+FUNCTION: HRESULT ScriptCacheGetHeight (
+    HDC hdc,
+    SCRIPT_CACHE* psc,
+    long* tmHeight
+) ;
+
+CONSTANT: SSA_PASSWORD HEX: 00000001
+CONSTANT: SSA_TAB HEX: 00000002
+CONSTANT: SSA_CLIP HEX: 00000004
+CONSTANT: SSA_FIT HEX: 00000008
+CONSTANT: SSA_DZWG HEX: 00000010
+CONSTANT: SSA_FALLBACK HEX: 00000020
+CONSTANT: SSA_BREAK HEX: 00000040
+CONSTANT: SSA_GLYPHS HEX: 00000080
+CONSTANT: SSA_RTL HEX: 00000100
+CONSTANT: SSA_GCP HEX: 00000200
+CONSTANT: SSA_HOTKEY HEX: 00000400
+CONSTANT: SSA_METAFILE HEX: 00000800
+CONSTANT: SSA_LINK HEX: 00001000
+CONSTANT: SSA_HIDEHOTKEY HEX: 00002000
+CONSTANT: SSA_HOTKEYONLY HEX: 00002400
+CONSTANT: SSA_FULLMEASURE HEX: 04000000
+CONSTANT: SSA_LPKANSIFALLBACK HEX: 08000000
+CONSTANT: SSA_PIDX HEX: 10000000
+CONSTANT: SSA_LAYOUTRTL HEX: 20000000
+CONSTANT: SSA_DONTGLYPH HEX: 40000000
+CONSTANT: SSA_NOKASHIDA HEX: 80000000
+
+C-STRUCT: SCRIPT_TABDEF
+    { "int" "cTabStops" }
+    { "int" "iScale" }
+    { "int*" "pTabStops" }
+    { "int" "iTabOrigin" } ;
+
+TYPEDEF: void* SCRIPT_STRING_ANALYSIS
+
+FUNCTION: HRESULT ScriptStringAnalyse (
+    HDC hdc,
+    void* pString,
+    int cString,
+    int cGlyphs,
+    int iCharset,
+    DWORD dwFlags,
+    int iReqWidth,
+    SCRIPT_CONTROL* psControl,
+    SCRIPT_STATE* psState,
+    int* piDx,
+    SCRIPT_TABDEF* pTabDef,
+    BYTE* pbInClass,
+    SCRIPT_STRING_ANALYSIS* pssa
+) ;
+
+FUNCTION: HRESULT ScriptStringFree (
+    SCRIPT_STRING_ANALYSIS* pssa
+) ;
+
+DESTRUCTOR: ScriptStringFree
+
+FUNCTION: SIZE* ScriptString_pSize ( SCRIPT_STRING_ANALYSIS ssa ) ;
+
+FUNCTION: int* ScriptString_pcOutChars ( SCRIPT_STRING_ANALYSIS ssa ) ;
+
+FUNCTION: SCRIPT_LOGATTR* ScriptString_pLogAttr ( SCRIPT_STRING_ANALYSIS ssa ) ;
+
+FUNCTION: HRESULT ScriptStringGetOrder (
+    SCRIPT_STRING_ANALYSIS ssa,
+    UINT* puOrder
+) ;
+
+FUNCTION: HRESULT ScriptStringCPtoX (
+    SCRIPT_STRING_ANALYSIS ssa,
+    int icp,
+    BOOL fTrailing,
+    int* pX
+) ;
+
+FUNCTION: HRESULT ScriptStringXtoCP (
+    SCRIPT_STRING_ANALYSIS ssa,
+    int iX,
+    int* piCh,
+    int* piTrailing
+) ;
+
+FUNCTION: HRESULT ScriptStringGetLogicalWidths (
+    SCRIPT_STRING_ANALYSIS ssa,
+    int* piDx
+) ;
+
+FUNCTION: HRESULT ScriptStringValidate (
+    SCRIPT_STRING_ANALYSIS ssa
+) ;
+
+FUNCTION: HRESULT ScriptStringOut (
+    SCRIPT_STRING_ANALYSIS ssa,
+    int iX,
+    int iY,
+    UINT uOptions,
+    RECT* prc,
+    int iMinSel,
+    int iMaxSel,
+    BOOL fDisabled
+) ;
+
+CONSTANT: SIC_COMPLEX 1
+CONSTANT: SIC_ASCIIDIGIT 2
+CONSTANT: SIC_NEUTRAL 4
+
+FUNCTION: HRESULT ScriptIsComplex (
+    WCHAR* pwcInChars,
+    int cInChars,
+    DWORD dwFlags
+) ;
+
+C-STRUCT: SCRIPT_DIGITSUBSTITUTE
+    { "DWORD" "flags" } ;
+
+FUNCTION: HRESULT ScriptRecordDigitSubstitution (
+    LCID Locale,
+    SCRIPT_DIGITSUBSTITUTE* psds
+) ;
+
+CONSTANT: SCRIPT_DIGITSUBSTITUTE_CONTEXT 0
+CONSTANT: SCRIPT_DIGITSUBSTITUTE_NONE 1
+CONSTANT: SCRIPT_DIGITSUBSTITUTE_NATIONAL 2
+CONSTANT: SCRIPT_DIGITSUBSTITUTE_TRADITIONAL 3
+
+FUNCTION: HRESULT ScriptApplyDigitSubstitution (
+    SCRIPT_DIGITSUBSTITUTE* psds,
+    SCRIPT_CONTROL* psc,
+    SCRIPT_STATE* pss
+) ;
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 44db355..902b1be
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.syntax alien.c-types alien.strings arrays
-combinators kernel math namespaces parser prettyprint sequences
+combinators kernel math namespaces parser sequences
 windows.errors windows.types windows.kernel32 words
 io.encodings.utf16n ;
 IN: windows
index 0b7f869141a47dd61d64e3d3e04570297880434f..58957ba8e74265239d2e2346fd839a267c1553f6 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences math arrays locals fry accessors
-lists splitting call make combinators.short-circuit namespaces
+lists splitting make combinators.short-circuit namespaces
 grouping splitting.monotonic ;
 IN: wrap
 
index 8375636a72e64dc4d6ba0f2cff3ea89b207e2e3b..87b91624afb922eb4a86065e540ecf23df4249b5 100644 (file)
@@ -26,7 +26,7 @@ TUPLE: x-clipboard atom contents ;
     CurrentTime XConvertSelection drop ;
 
 : snarf-property ( prop-return -- string )
-    dup *void* [ *void* ascii alien>string ] [ drop f ] if ;
+    dup *void* [ *void* utf8 alien>string ] [ drop f ] if ;
 
 : window-property ( win prop delete? -- string )
     [ [ dpy get ] 2dip 0 -1 ] dip AnyPropertyType
@@ -37,7 +37,7 @@ TUPLE: x-clipboard atom contents ;
     swap XSelectionEvent-property zero? [
         drop f
     ] [
-        selection-property 1 window-property utf8 decode
+        selection-property 1 window-property
     ] if ;
 
 : own-selection ( prop win -- )
index 9619ae0bee3f1e252a04f94a81fa8bd3256947a0..8085907bef7c8e2fb950fd60738134376033d3d6 100644 (file)
@@ -6,10 +6,10 @@ arrays fry ;
 IN: x11.windows
 
 : create-window-mask ( -- n )
-    { CWBackPixel CWBorderPixel CWColormap CWEventMask } flags ;
+    { CWColormap CWEventMask } flags ;
 
 : create-colormap ( visinfo -- colormap )
-    dpy get root get rot XVisualInfo-visual AllocNone
+    [ dpy get root get ] dip XVisualInfo-visual AllocNone
     XCreateColormap ;
 
 : event-mask ( -- n )
@@ -29,8 +29,6 @@ IN: x11.windows
 
 : window-attributes ( visinfo -- attributes )
     "XSetWindowAttributes" <c-object>
-    0 over set-XSetWindowAttributes-background_pixel
-    0 over set-XSetWindowAttributes-border_pixel
     [ [ create-colormap ] dip set-XSetWindowAttributes-colormap ] keep
     event-mask over set-XSetWindowAttributes-event_mask ;
 
index fe4762acbe686d1edb84135b7ca58fb224c627eb..63482ff706f12097aa6972c82d5ccd1f57476fb4 100644 (file)
@@ -3,7 +3,7 @@
 USING: kernel namespaces xml.name io.encodings.utf8 xml.elements
 io.encodings.utf16 xml.tokenize xml.state math ascii sequences
 io.encodings.string io.encodings combinators accessors
-xml.data io.encodings.iana ;
+xml.data io.encodings.iana xml.errors ;
 IN: xml.autoencoding
 
 : decode-stream ( encoding -- )
@@ -35,7 +35,10 @@ IN: xml.autoencoding
 
 : prolog-encoding ( prolog -- )
     encoding>> dup "UTF-16" =
-    [ drop ] [ name>encoding [ decode-stream ] when* ] if ;
+    [ drop ] [
+        dup name>encoding
+        [ decode-stream ] [ bad-encoding ] ?if
+    ] if ;
 
 : instruct-encoding ( instruct/prolog -- )
     dup prolog?
index d510c8a881d47e8d9538db82b0653b0d1b7b3be3..3deab0a2872189681a76e52d5d4a7bd26474b3be 100644 (file)
@@ -1,19 +1,26 @@
 ! Copyright (C) 2005, 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences unicode.syntax math math.order combinators
-hints ;
+USING: kernel sequences unicode.categories.syntax math math.order
+combinators hints combinators.short-circuit ;
 IN: xml.char-classes
 
-CATEGORY: 1.0name-start* Ll Lu Lo Lt Nl \u000559\u0006E5\u0006E6_: ;
-: 1.0name-start? ( char -- ? )
-    dup 1.0name-start*? [ drop t ] 
-    [ HEX: 2BB HEX: 2C1 between? ] if ;
+CATEGORY: 1.0name-start
+    Ll Lu Lo Lt Nl | {
+        [ HEX: 2BB HEX: 2C1 between? ]
+        [ "\u000559\u0006E5\u0006E6_:" member? ]
+    } 1|| ;
 
-CATEGORY: 1.0name-char Ll Lu Lo Lt Nl Mc Me Mn Lm Nd _-.\u000387: ;
+CATEGORY: 1.0name-char
+    Ll Lu Lo Lt Nl Mc Me Mn Lm Nd |
+    "_-.\u000387:" member? ;
 
-CATEGORY: 1.1name-start Ll Lu Lo Lm Ln Nl _: ;
+CATEGORY: 1.1name-start
+    Ll Lu Lo Lm Nl |
+    "_:" member? ;
 
-CATEGORY: 1.1name-char Ll Lu Lo Lm Ln Nl Mc Mn Nd Pc Cf _-.\u0000b7: ;
+CATEGORY: 1.1name-char
+    Ll Lu Lo Lm Nl Mc Mn Nd Pc Cf |
+    "_-.\u0000b7:" member? ;
 
 : name-start? ( 1.0? char -- ? )
     swap [ 1.0name-start? ] [ 1.1name-start? ] if ;
index 8a469bc08fbe0d3f598b822e4b983d37d6ef6271..10d7bb63ca5b6e0628008941cee884da1f79c83b 100644 (file)
@@ -1,5 +1,5 @@
 USING: continuations xml xml.errors tools.test kernel arrays
-xml.data quotations fry ;
+xml.data quotations fry byte-arrays ;
 IN: xml.errors.tests
 
 : xml-error-test ( expected-error xml-string -- )
@@ -40,3 +40,4 @@ T{ bad-doctype f 1 22 T{ opener { name T{ name f "" "foo" "" } } { attrs T{ attr
 T{ disallowed-char f 1 4 1 } "<x>\u000001</x>" xml-error-test
 T{ missing-close f 1 8 } "<!-- foo" xml-error-test
 T{ misplaced-directive f 1 9 "ENTITY" } "<!ENTITY foo 'bar'><x/>" xml-error-test
+[ "<?xml version='1.0' encoding='foobar'?>" >byte-array bytes>xml ] [ T{ bad-encoding f 1 39 "foobar" } = ] must-fail-with
index 35111f5a54473cfb2ae9bcb43b9aa670e38db86a..7be7e074c3a26fa07202e5c983ba4a6cb06b9720 100644 (file)
@@ -338,5 +338,14 @@ TUPLE: bad-doctype < xml-error-at contents ;
 M: bad-doctype summary
     call-next-method "\nDTD contains invalid object" append ;
 
+TUPLE: bad-encoding < xml-error-at encoding ;
+: bad-encoding ( encoding -- * )
+    \ bad-encoding xml-error-at
+        swap >>encoding
+    throw ;
+M: bad-encoding summary
+    call-next-method
+    "\nEncoding in XML document does not exist" append ;
+
 UNION: xml-error
     multitags notags pre/post-content xml-error-at ;
index 067bb9ec1173756fca636c8bbf75524bf8f2fa64..f39592036cd35e17c4606a1f2c587167c4fcc98c 100644 (file)
@@ -1,10 +1,11 @@
 ! Copyright (C) 2005, 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: words assocs kernel accessors parser sequences summary
-lexer splitting combinators locals xml.data memoize sequences.deep
-xml.data xml.state xml namespaces present arrays generalizations strings
-make math macros multiline inverse combinators.short-circuit 
-sorting fry unicode.categories ;
+USING: words assocs kernel accessors parser effects.parser
+sequences summary lexer splitting combinators locals xml.data
+memoize sequences.deep xml.data xml.state xml namespaces present
+arrays generalizations strings make math macros multiline
+inverse combinators.short-circuit sorting fry unicode.categories
+effects ;
 IN: xml.syntax
 
 <PRIVATE
@@ -17,26 +18,26 @@ M: no-tag summary
     >alist swap '[ _ no-tag boa throw ] suffix
     '[ dup main>> _ case ] ;
 
-: define-tags ( word -- )
-    dup dup "xtable" word-prop compile-tags define ;
+: define-tags ( word effect -- )
+    [ dup dup "xtable" word-prop compile-tags ] dip define-declared ;
 
 :: define-tag ( string word quot -- )
     quot string word "xtable" word-prop set-at
-    word define-tags ;
+    word word stack-effect define-tags ;
 
 PRIVATE>
 
-: TAGS:
-    CREATE
-    [ H{ } clone "xtable" set-word-prop ]
-    [ define-tags ] bi ; parsing
+SYNTAX: TAGS:
+    CREATE-WORD complete-effect
+    [ drop H{ } clone "xtable" set-word-prop ]
+    [ define-tags ]
+    2bi ;
 
-: TAG:
-    scan scan-word parse-definition define-tag ; parsing
+SYNTAX: TAG:
+    scan scan-word parse-definition define-tag ;
 
-: XML-NS:
-    CREATE-WORD (( string -- name )) over set-stack-effect
-    scan '[ f swap _ <name> ] define-memoized ; parsing
+SYNTAX: XML-NS:
+    CREATE-WORD scan '[ f swap _ <name> ] (( string -- name )) define-memoized ;
 
 <PRIVATE
 
@@ -168,11 +169,11 @@ MACRO: interpolate-xml ( xml -- quot )
 
 PRIVATE>
 
-: <XML
-    "XML>" [ string>doc ] parse-def ; parsing
+SYNTAX: <XML
+    "XML>" [ string>doc ] parse-def ;
 
-: [XML
-    "XML]" [ string>chunk ] parse-def ; parsing
+SYNTAX: [XML
+    "XML]" [ string>chunk ] parse-def ;
 
 <PRIVATE
 
index 71c0ff728276e0787cbda7cfcb9e0b4656368f1e..4f4a20b1cb83326b5706914cdb913f14055e1d0b 100644 (file)
@@ -1 +1,2 @@
+extensions
 syntax
index 4861f86d7b98f00e234ef5e65099b5a2c702521d..7f7d8d28918e73ecefb1d4745d95fb0c72d378fa 100644 (file)
@@ -2,8 +2,8 @@ USING: kernel xml sequences assocs tools.test io arrays namespaces fry
 accessors xml.data xml.traversal xml.writer generic sequences.deep multiline ;
 IN: xml.tests
 
-: sub-tag
-    T{ name f f "sub" "http://littledan.onigirihouse.com/namespaces/replace" } ;
+CONSTANT: sub-tag
+    T{ name f f "sub" "http://littledan.onigirihouse.com/namespaces/replace" }
 
 SYMBOL: ref-table
 
index 818a28c892896584e9385da9083fd6e524b06d7d..1d07aa94063ad07f2c28a979b5d74154846cd84e 100644 (file)
@@ -74,3 +74,4 @@ SYMBOL: xml-file
 [ "foo" ] [ "<!DOCTYPE foo [<!ENTITY bar 'foo'>]><x>&bar;</x>" string>xml children>string ] unit-test
 [ T{ xml-chunk f V{ "hello" } } ] [ "hello" string>xml-chunk ] unit-test
 [ "1.1" ] [ "<?xml version='1.1'?><x/>" string>xml prolog>> version>> ] unit-test
+[ "ß" ] [ "<x>ß</x>" <string-reader> read-xml children>string ] unit-test
index 532c1db29f4e3bf44fbc2c4c3daf6a63baa5dcc5..c41b05eb8539a69cc1497f4224952e93f27037da 100644 (file)
@@ -17,7 +17,7 @@ TUPLE: xml-test id uri sections description type ;
 : parse-tests ( xml -- tests )
     "TEST" tags-named [ >xml-test ] map ;
 
-: base "vocab:xml/tests/xmltest/" ;
+CONSTANT: base "vocab:xml/tests/xmltest/"
 
 MACRO: drop-output ( quot -- newquot )
     dup infer out>> '[ @ _ ndrop ] ;
index 1329c4975e438cfbc133cc3faefe953314b1e702..9f26774647868f015e35b547e9f0822d1d788aa8 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2005, 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax xml.data sequences strings ;
+USING: help.markup help.syntax xml.data sequences strings multiline ;
 IN: xml.traversal
 
 ABOUT: "xml.traversal"
@@ -8,7 +8,7 @@ ABOUT: "xml.traversal"
 ARTICLE: "xml.traversal" "Utilities for traversing XML"
     "The " { $vocab-link "xml.traversal" } " vocabulary provides utilities for traversing an XML DOM tree and viewing the contents of a single tag. The following words are defined:"
     $nl
-    "Note: the difference between deep-tag-named and tag-named is that the former searches recursively among all children and children of children of the tag, while the latter only looks at the direct children, and is therefore more efficient."
+    { $subsection { "xml.traversal" "intro" } }
     { $subsection tag-named }
     { $subsection tags-named }
     { $subsection deep-tag-named }
@@ -20,6 +20,20 @@ ARTICLE: "xml.traversal" "Utilities for traversing XML"
     { $subsection first-child-tag }
     { $subsection assert-tag } ;
 
+ARTICLE: { "xml.traversal" "intro" } "An example of XML processing"
+"To illustrate how to use the XML library, we develop a simple Atom parser in Factor. Atom is an XML-based syndication format, like RSS. To see the full version of what we develop here, look at " { $snippet "basis/syndication" } " at the " { $snippet "atom1.0" } " word. First, we want to load a file and get a DOM tree for it."
+{ $code <" "file.xml" file>xml "> }
+"No encoding descriptor is needed, because XML files contain sufficient information to auto-detect the encoding. Next, we want to extract information from the tree. To get the title, we can use the following:"
+{ $code <" "title" tag-named children>string "> }
+"The " { $link tag-named } " word finds the first tag named " { $snippet "title" } " in the top level (just under the main tag). Then, with a tag on the stack, its children are asserted to be a string, and the string is returned." $nl
+"For a slightly more complicated example, we can look at how entries are parsed. To get a sequence of tags with the name " { $snippet "entry" } ":"
+{ $code <" "entry" tags-named "> }
+"Imagine that, for each of these, we want to get the URL of the entry. In Atom, the URLs are in a " { $snippet "link" } " tag which is contained in the " { $snippet "entry" } " tag. There are multiple " { $snippet "link" } " tags, but one of them contains the attribute " { $snippet "rel=alternate" } ", and the " { $snippet "href" } " attribute has the URL. So, given an element of the sequence produced in the above quotation, we run the code:"
+{ $code <" "link" tags-named [ "rel" attr "alternate" = ] find nip "> }
+"to get the link tag on the stack, and"
+{ $code <" "href" attr >url "> }
+"to extract the URL from it." ;
+
 HELP: deep-tag-named
 { $values { "tag" "an XML tag or document" } { "name/string" "an XML name or string representing a name" } { "matching-tag" tag } }
 { $description "Finds an XML tag with a matching name, recursively searching children and children of children." }
index 421c2a2b5db7fc7c705dbec8f487a03b4fad4a77..f19e845ab926fc1cd338527824c1f449f0757d0c 100644 (file)
@@ -61,7 +61,7 @@ IN: xml.writer.tests
 [ "<foo>         bar            </foo>" string>xml pprint-xml>string ] unit-test
 [ "<foo'>" ] [ "<foo'>" <unescaped> xml>string ] unit-test
 
-: test-file "resource:basis/xml/writer/test.xml" ;
+CONSTANT: test-file "resource:basis/xml/writer/test.xml"
 
 [ ] [ "<?xml version='1.0' encoding='UTF-16BE'?><x/>" string>xml test-file utf8 [ write-xml ] with-file-writer ] unit-test
 [ "x" ] [ test-file file>xml body>> name>> main>> ] unit-test
index 77969c55cde415545dc554c7ee8d1cabf2dfba70..434209620b9b837c9674fb2809ab022c7393346f 100644 (file)
@@ -67,9 +67,9 @@ HELP: string>dtd
 \r
 ARTICLE: { "xml" "reading" } "Reading XML"\r
     "The following words are used to read something into an XML document"\r
-    { $subsection string>xml }\r
     { $subsection read-xml }\r
     { $subsection read-xml-chunk }\r
+    { $subsection string>xml }\r
     { $subsection string>xml-chunk }\r
     { $subsection file>xml }\r
     { $subsection bytes>xml }\r
@@ -90,10 +90,16 @@ ARTICLE: { "xml" "events" } "Event-based XML parsing"
     { $subsection pull-event }\r
     { $subsection pull-elem } ;\r
 \r
+ARTICLE: { "xml" "namespaces" } "Working with XML namespaces"\r
+"The Factor XML parser implements XML namespaces, and provides convenient utilities for working with them. Anywhere in the public API that a name is accepted as an argument, either a string or an XML name is accepted. If a string is used, it is coerced into a name by giving it a null namespace. Names are stored as " { $link name } " tuples, which have slots for the namespace prefix and namespace URL as well as the main part of the tag name." $nl\r
+"To make it easier to create XML names, the parsing word " { $snippet "XML-NS:" } " is provided in the " { $vocab-link "xml.syntax" } " vocabulary." $nl\r
+"When parsing XML, names are automatically augmented with the appropriate namespace URL when the information is available. This does not take into account any XML schema which might allow for such prefixes to be omitted. When generating XML to be written, keep in mind that the XML writer knows only about the literal prefixes and ignores the URLs. It is your job to make sure that they match up correctly, and that there is the appropriate " { $snippet "xmlns" } " declaration." ;\r
+\r
 ARTICLE: "xml" "XML parser"\r
 "The " { $vocab-link "xml" } " vocabulary implements the XML 1.0 and 1.1 standards, converting strings of text into XML and vice versa. The parser checks for well-formedness but is not validating. There is only partial support for processing DTDs."\r
     { $subsection { "xml" "reading" } }\r
     { $subsection { "xml" "events" } }\r
+    { $subsection { "xml" "namespaces" } }\r
     { $vocab-subsection "Writing XML" "xml.writer" }\r
     { $vocab-subsection "XML parsing errors" "xml.errors" }\r
     { $vocab-subsection "XML entities" "xml.entities" }\r
index 073f46cbae3314a7c390ed56f14921f5a00f9830..fba2eafaba84f72f40364c4eca307950a9077cfb 100755 (executable)
@@ -4,7 +4,8 @@ USING: accessors arrays io io.encodings.binary io.files
 io.streams.string kernel namespaces sequences strings io.encodings.utf8
 xml.data xml.errors xml.elements ascii xml.entities
 xml.writer xml.state xml.autoencoding assocs xml.tokenize
-combinators.short-circuit xml.name splitting io.streams.byte-array ;
+combinators.short-circuit xml.name splitting io.streams.byte-array
+combinators ;
 IN: xml
 
 <PRIVATE
@@ -159,6 +160,9 @@ PRIVATE>
         xml-stack get first second
     ] with-state ; inline
 
+: make-xml ( stream quot -- xml )
+    0 read-seq make-xml-doc ; inline
+
 PRIVATE>
 
 : each-element ( stream quot: ( xml-elem -- ) -- )
@@ -169,14 +173,16 @@ PRIVATE>
     ] with-state ; inline
 
 : read-xml ( stream -- xml )
-    [ start-document [ process ] when* ]
-    0 read-seq make-xml-doc ;
+    dup stream-element-type {
+        { +character+ [ [ check ] make-xml ] }
+        { +byte+ [ [ start-document [ process ] when* ] make-xml ] }
+    } case ;
 
 : read-xml-chunk ( stream -- seq )
     [ check ] 1 read-seq <xml-chunk> ;
 
 : string>xml ( string -- xml )
-    <string-reader> [ check ] 0 read-seq make-xml-doc ;
+    <string-reader> read-xml ;
 
 : string>xml-chunk ( string -- xml )
     <string-reader> read-xml-chunk ;
index 241ab7ff75f0b466fc9e640571bbb4761ee52589..8d5db4a6e9b613bbc26dc188a8489905db7dc771 100644 (file)
@@ -18,4 +18,12 @@ kernel io.streams.string xml.writer ;
     <" int x = "hi";
 /* a comment */ "> <string-reader> htmlize-stream
     write-xml
+] unit-test
+
+[ "<span class=\"MARKUP\">: foo</span> <span class=\"MARKUP\">;</span>" ] [
+    { ": foo ;" } "factor" htmlize-lines xml>string
+] unit-test
+
+[ ":foo" ] [
+    { ":foo" } "factor" htmlize-lines xml>string
 ] unit-test
\ No newline at end of file
index 60318e669e7fea9cffb97649a07d07c21a2236d7..d2e1d997216dd73bb161607fabe8768509e8f052 100644 (file)
@@ -10,11 +10,11 @@ IN: xmode.loader.syntax
 : (parse-rule-tag) ( rule-set tag specs class -- )
     new swap init-from-tag swap add-rule ; inline
 
-: RULE:
+SYNTAX: RULE:
     scan scan-word scan-word [
-        parse-definition { } make
+        [ parse-definition call( -- ) ] { } make
         swap [ (parse-rule-tag) ] 2curry
-    ] dip swap define-tag ; parsing
+    ] dip swap define-tag ;
 
 ! Attribute utilities
 : string>boolean ( string -- ? ) "TRUE" = ;
index f584756f33c68f41323d4a4641ef578d84eb317b..b4c1cd6a48dfaf50410a75d1da25adbb5275171e 100755 (executable)
@@ -84,7 +84,7 @@ M: string-matcher text-matches?
     ] keep string>> length and ;
 
 M: regexp text-matches?
-    [ >string ] dip re-contains? ;
+    [ >string ] dip first-match dup [ to>> ] when ;
 
 : rule-start-matches? ( rule -- match-count/f )
     dup start>> tuck swap can-match-here? [
diff --git a/build-support/dlls.txt b/build-support/dlls.txt
deleted file mode 100644 (file)
index 97d0cf6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-libcairo-2.dll
-libgio-2.0-0.dll
-libglib-2.0-0.dll
-libgmodule-2.0-0.dll
-libgobject-2.0-0.dll
-libgthread-2.0-0.dll
-libpango-1.0-0.dll
-libpangocairo-1.0-0.dll
-libpangowin32-1.0-0.dll
-libpng12-0.dll
-libtiff3.dll
-zlib1.dll
index cf6aacb84fe274172577dfb8ab308ea659929fb0..ad64c541fed6a694d40a0daec90ccb1f2b464e5b 100755 (executable)
@@ -139,10 +139,10 @@ check_library_exists() {
 }
 
 check_X11_libraries() {
-    check_library_exists freetype
     check_library_exists GLU
     check_library_exists GL
     check_library_exists X11
+    check_library_exists pango-1.0
 }
 
 check_libraries() {
@@ -445,16 +445,6 @@ get_url() {
     check_ret $DOWNLOADER
 }
 
-maybe_download_dlls() {
-    if [[ $OS == winnt ]] ; then
-       for file in `cat build-support/dlls.txt`; do
-           get_url http://factorcode.org/dlls/$file
-            chmod 777 *.dll
-            check_ret chmod
-       done
-    fi
-}
-
 get_config_info() {
     find_build_info
     check_installed_programs
@@ -472,7 +462,6 @@ install() {
     cd_factor
     make_factor
     get_boot_image
-    maybe_download_dlls
     bootstrap
 }
 
@@ -502,7 +491,7 @@ make_boot_image() {
 }
 
 install_build_system_apt() {
-    sudo apt-get --yes install libc6-dev libpango-1.0-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap gcc make
+    sudo apt-get --yes install libc6-dev libpango1.0-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap gcc make
     check_ret sudo
 }
 
@@ -547,7 +536,6 @@ case "$1" in
     update) update; update_bootstrap ;;
     bootstrap) get_config_info; bootstrap ;;
     report) find_build_info ;;
-    dlls) get_config_info; maybe_download_dlls;;
     net-bootstrap) get_config_info; update_boot_images; bootstrap ;;
     make-target) ECHO=false; find_build_info; echo $MAKE_TARGET ;;
     *) usage ;;
index edac8c09cc6a46dfefbfbb18e6487d751d690688..6bd1d2f53a429f23a034eccfa356d19a2f27e55f 100644 (file)
@@ -1,7 +1,7 @@
 USING: byte-arrays arrays help.syntax help.markup
-alien.syntax compiler definitions math libc
-debugger parser io io.backend system
-alien.accessors eval ;
+alien.syntax compiler definitions math libc eval
+debugger parser io io.backend system alien.accessors
+alien.libraries ;
 IN: alien
 
 HELP: alien
@@ -22,16 +22,6 @@ HELP: <bad-alien>
 { $values  { "alien" c-ptr } }
 { $description "Constructs an invalid alien pointer that has expired." } ;
 
-HELP: <library>
-{ $values
-     { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
-     { "library" library } }
-{ $description "Opens a C library using the path and ABI parameters and outputs a library tuple." }
-{ $notes "User code should use " { $link add-library } " so that the opened library is added to a global hashtable, " { $link libraries } "." } ;
-
-HELP: libraries
-{ $description "A global hashtable that keeps a list of open libraries. Use the " { $link add-library } " word to construct a library and add it with a single call." } ;
-
 HELP: <displaced-alien> ( displacement c-ptr -- alien )
 { $values { "displacement" "an integer" } { "c-ptr" c-ptr } { "alien" "a new alien" } }
 { $description "Creates a new alien address object, wrapping a raw memory address. The alien points to a location in memory which is offset by " { $snippet "displacement" } " from the address of " { $snippet "c-ptr" } "." }
@@ -54,61 +44,6 @@ HELP: <alien>
 HELP: c-ptr
 { $class-description "Class of objects consisting of aliens, byte arrays and " { $link f } ". These objects can convert to pointer C types, which are all aliases of " { $snippet "void*" } "." } ;
 
-HELP: library
-{ $values { "name" "a string" } { "library" "a hashtable" } }
-{ $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
-    { $list
-        { { $snippet "name" } " - the full path of the C library binary" }
-        { { $snippet "abi" } " - the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
-        { { $snippet "dll" } " - an instance of the " { $link dll } " class; only set if the library is loaded" }
-    }
-} ;
-
-HELP: dlopen ( path -- dll )
-{ $values { "path" "a pathname string" } { "dll" "a DLL handle" } }
-{ $description "Opens a native library and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } "." }
-{ $errors "Throws an error if the library could not be found, or if loading fails for some other reason." }
-{ $notes "This is the low-level facility used to implement " { $link load-library } ". Use the latter instead." } ;
-
-HELP: dlsym ( name dll -- alien )
-{ $values { "name" "a C symbol name" } { "dll" "a DLL handle" } { "alien" "an alien pointer" } }
-{ $description "Looks up a symbol in a native library. If " { $snippet "dll" } " is " { $link f } " looks for the symbol in the runtime executable." }
-{ $errors "Throws an error if the symbol could not be found." } ;
-
-HELP: dlclose ( dll -- )
-{ $values { "dll" "a DLL handle" } }
-{ $description "Closes a DLL handle created by " { $link dlopen } ". This word might not be implemented on all platforms." } ;
-
-HELP: load-library
-{ $values { "name" "a string" } { "dll" "a DLL handle" } }
-{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
-
-HELP: add-library
-{ $values { "name" "a string" } { "path" "a string" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
-{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } "and the specified ABI." }
-{ $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " cannot be used in the same file as " { $link POSTPONE: FUNCTION: } " definitions from that library. The " { $link add-library } " call will happen too late, after compilation, and the alien calls will not work."
-$nl
-"Instead, " { $link add-library } " calls must either be placed in different source files from those that use that library, or alternatively, " { $link "syntax-immediate" } " can be used to load the library before compilation." }
-{ $examples "Here is a typical usage of " { $link add-library } ":"
-{ $code
-    "<< \"freetype\" {"
-    "    { [ os macosx? ] [ \"libfreetype.6.dylib\" \"cdecl\" add-library ] }"
-    "    { [ os windows? ] [ \"freetype6.dll\" \"cdecl\" add-library ] }"
-    "    [ drop ]"
-    "} cond >>"
-}
-"Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
-
-HELP: alien-invoke-error
-{ $error-description "Thrown if the word calling " { $link alien-invoke } " was not compiled with the optimizing compiler. This may be a result of one of several failure conditions:"
-    { $list
-        { "This can happen when experimenting with " { $link alien-invoke } " in this listener. To fix the problem, place the " { $link alien-invoke } " call in a word; word definitions are automatically compiled with the optimizing compiler." }
-        { "The return type or parameter list references an unknown C type." }
-        { "The symbol or library could not be found." }
-        { "One of the four inputs to " { $link alien-invoke } " is not a literal value. To call functions which are not known at compile-time, use " { $link alien-indirect } "." }
-    }
-} ;
-
 HELP: alien-invoke
 { $values { "..." "zero or more objects passed to the C function" } { "return" "a C return type" } { "library" "a logical library name" } { "function" "a C function name" } { "parameters" "a sequence of C parameter types" } }
 { $description "Calls a C library function with the given name. Input parameters are taken from the data stack, and the return value is pushed on the data stack after the function returns. A return type of " { $snippet "\"void\"" } " indicates that no value is to be expected." }
@@ -226,6 +161,16 @@ ARTICLE: "alien-invoke" "Calling C from Factor"
 { $subsection alien-indirect }
 "There are some details concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-data" } "." ;
 
+HELP: alien-invoke-error
+{ $error-description "Thrown if the word calling " { $link alien-invoke } " was not compiled with the optimizing compiler. This may be a result of one of several failure conditions:"
+    { $list
+        { "This can happen when experimenting with " { $link alien-invoke } " in this listener. To fix the problem, place the " { $link alien-invoke } " call in a word; word definitions are automatically compiled with the optimizing compiler." }
+        { "The return type or parameter list references an unknown C type." }
+        { "The symbol or library could not be found." }
+        { "One of the four inputs to " { $link alien-invoke } " is not a literal value. To call functions which are not known at compile-time, use " { $link alien-indirect } "." }
+    }
+} ;
+
 ARTICLE: "alien-callback-gc" "Callbacks and code GC"
 "A callback consits of two parts; the callback word, which pushes the address of the callback on the stack when executed, and the callback body itself. If the callback word is redefined, removed from the dictionary using " { $link forget } ", or recompiled, the callback body will not be reclaimed by the garbage collector, since potentially C code may be holding a reference to the callback body."
 $nl
index e4063b733cdd61b6fe42d968ad44f0a3f526e540..d3265f31bbc245779b7fe6265207b7203ce0d5f8 100644 (file)
@@ -1,7 +1,7 @@
-IN: alien.tests
 USING: accessors alien alien.accessors alien.syntax byte-arrays arrays
 kernel kernel.private namespaces tools.test sequences libc math
-system prettyprint layouts ;
+system prettyprint layouts alien.libraries sets ;
+IN: alien.tests
 
 [ t ] [ -1 <alien> alien-address 0 > ] unit-test
 
@@ -85,4 +85,6 @@ f initialize-test set-global
 
 [ ] [ initialize-test get BAD-ALIEN >>alien drop ] unit-test
 
-[ 7575 ] [ initialize-test [ 7575 ] initialize-alien ] unit-test
\ No newline at end of file
+[ 7575 ] [ initialize-test [ 7575 ] initialize-alien ] unit-test
+
+[ V{ BAD-ALIEN } ] [ { BAD-ALIEN BAD-ALIEN BAD-ALIEN } prune ] unit-test
\ No newline at end of file
index 83665778f1aa416d2d02d8788b634bd9b4936555..ec38e3be5b8b5b9ff821339012ff6af25414a446 100644 (file)
@@ -49,22 +49,7 @@ M: alien equal?
         2drop f
     ] if ;
 
-SYMBOL: libraries
-
-libraries [ H{ } clone ] initialize
-
-TUPLE: library path abi dll ;
-
-: library ( name -- library ) libraries get at ;
-
-: <library> ( path abi -- library )
-    over dup [ dlopen ] when \ library boa ;
-
-: load-library ( name -- dll )
-    library dup [ dll>> ] when ;
-
-: add-library ( name path abi -- )
-    <library> swap libraries get set-at ;
+M: simple-alien hashcode* nip dup expired>> [ drop 1234 ] [ alien-address ] if ;
 
 ERROR: alien-callback-error ;
 
@@ -99,4 +84,4 @@ PRIVATE>
 : initialize-alien ( symbol quot -- )
     swap dup get-global dup recompute-value?
     [ drop [ call dup 31337 <alien> expiry-check boa ] dip set-global ]
-    [ 2nip object>> ] if ; inline
\ No newline at end of file
+    [ 2nip object>> ] if ; inline
index 9e064cf99c2fdc0c8e0e86b9ab38a2be82416c3b..4466bd9bfe00aab5e50e3e90cc2e0150da143dde 100644 (file)
@@ -25,7 +25,8 @@ H{ } clone sub-primitives set
     { "linux-ppc" "ppc/linux" }
     { "macosx-ppc" "ppc/macosx" }
     { "arm" "arm" }
-} at "/bootstrap.factor" 3append parse-file
+} ?at [ "Bad architecture: " prepend throw ] unless
+"/bootstrap.factor" 3append parse-file
 
 "vocab:bootstrap/layouts/layouts.factor" parse-file
 
@@ -35,8 +36,8 @@ H{ } clone sub-primitives set
 "syntax" vocab vocab-words bootstrap-syntax set {
     dictionary
     new-classes
-    changed-definitions changed-generics
-    remake-generics forgotten-definitions
+    changed-definitions changed-generics changed-effects
+    outdated-generics forgotten-definitions
     root-cache source-files update-map implementors-map
 } [ H{ } clone swap set ] each
 
@@ -45,13 +46,11 @@ init-caches
 ! Vocabulary for slot accessors
 "accessors" create-vocab drop
 
-! Trivial recompile hook. We don't want to touch the code heap
-! during stage1 bootstrap, it would just waste time.
-[ drop { } ] recompile-hook set
+dummy-compiler compiler-impl set
 
-call
-call
-call
+call( -- )
+call( -- )
+call( -- )
 
 ! After we execute bootstrap/layouts
 num-types get f <array> builtins set
@@ -63,6 +62,7 @@ bootstrapping? on
 {
     "alien"
     "alien.accessors"
+    "alien.libraries"
     "arrays"
     "byte-arrays"
     "classes.private"
@@ -141,9 +141,6 @@ bootstrapping? on
 "word" "words" create register-builtin
 "byte-array" "byte-arrays" create register-builtin
 
-! For predicate classes
-"predicate-instance?" "classes.predicate" create drop
-
 ! We need this before defining c-ptr below
 "f" "syntax" lookup { } define-builtin
 
@@ -244,6 +241,8 @@ bi
 "quotation" "quotations" create {
     { "array" { "array" "arrays" } read-only }
     { "compiled" read-only }
+    "cached-effect"
+    "cache-counter"
 } define-builtin
 
 "dll" "alien" create {
@@ -337,205 +336,205 @@ tuple
 (( quot1 quot2 -- compose )) define-declared
 
 ! Sub-primitive words
-: make-sub-primitive ( word vocab -- )
-    create
-    dup reset-word
-    dup 1quotation define ;
+: make-sub-primitive ( word vocab effect -- )
+    [ create dup 1quotation ] dip define-declared ;
 
 {
-    { "(execute)" "words.private" }
-    { "(call)" "kernel.private" }
-    { "both-fixnums?" "math.private" }
-    { "fixnum+fast" "math.private" }
-    { "fixnum-fast" "math.private" }
-    { "fixnum*fast" "math.private" }
-    { "fixnum-bitand" "math.private" }
-    { "fixnum-bitor" "math.private" }
-    { "fixnum-bitxor" "math.private" }
-    { "fixnum-bitnot" "math.private" }
-    { "fixnum-mod" "math.private" }
-    { "fixnum-shift-fast" "math.private" }
-    { "fixnum/i-fast" "math.private" }
-    { "fixnum/mod-fast" "math.private" }
-    { "fixnum<" "math.private" }
-    { "fixnum<=" "math.private" }
-    { "fixnum>" "math.private" }
-    { "fixnum>=" "math.private" }
-    { "drop" "kernel" }
-    { "2drop" "kernel" }
-    { "3drop" "kernel" }
-    { "dup" "kernel" }
-    { "2dup" "kernel" }
-    { "3dup" "kernel" }
-    { "rot" "kernel" }
-    { "-rot" "kernel" }
-    { "dupd" "kernel" }
-    { "swapd" "kernel" }
-    { "nip" "kernel" }
-    { "2nip" "kernel" }
-    { "tuck" "kernel" }
-    { "over" "kernel" }
-    { "pick" "kernel" }
-    { "swap" "kernel" }
-    { "eq?" "kernel" }
-    { "tag" "kernel.private" }
-    { "slot" "slots.private" }
-    { "get-local" "locals.backend" }
-    { "load-local" "locals.backend" }
-    { "drop-locals" "locals.backend" }
-} [ make-sub-primitive ] assoc-each
+    { "(execute)" "words.private" (( word -- )) }
+    { "(call)" "kernel.private" (( quot -- )) }
+    { "both-fixnums?" "math.private" (( x y -- ? )) }
+    { "fixnum+fast" "math.private" (( x y -- z )) }
+    { "fixnum-fast" "math.private" (( x y -- z )) }
+    { "fixnum*fast" "math.private" (( x y -- z )) }
+    { "fixnum-bitand" "math.private" (( x y -- z )) }
+    { "fixnum-bitor" "math.private" (( x y -- z )) }
+    { "fixnum-bitxor" "math.private" (( x y -- z )) }
+    { "fixnum-bitnot" "math.private" (( x -- y )) }
+    { "fixnum-mod" "math.private" (( x y -- z )) }
+    { "fixnum-shift-fast" "math.private" (( x y -- z )) }
+    { "fixnum/i-fast" "math.private" (( x y -- z )) }
+    { "fixnum/mod-fast" "math.private" (( x y -- z w )) }
+    { "fixnum<" "math.private" (( x y -- ? )) }
+    { "fixnum<=" "math.private" (( x y -- z )) }
+    { "fixnum>" "math.private" (( x y -- ? )) }
+    { "fixnum>=" "math.private" (( x y -- ? )) }
+    { "drop" "kernel" (( x -- )) }
+    { "2drop" "kernel" (( x y -- )) }
+    { "3drop" "kernel" (( x y z -- )) }
+    { "dup" "kernel" (( x -- x x )) }
+    { "2dup" "kernel" (( x y -- x y x y )) }
+    { "3dup" "kernel" (( x y z -- x y z x y z )) }
+    { "rot" "kernel" (( x y z -- y z x )) }
+    { "-rot" "kernel" (( x y z -- z x y )) }
+    { "dupd" "kernel" (( x y -- x x y )) }
+    { "swapd" "kernel" (( x y z -- y x z )) }
+    { "nip" "kernel" (( x y -- y )) }
+    { "2nip" "kernel" (( x y z -- z )) }
+    { "tuck" "kernel" (( x y -- y x y )) }
+    { "over" "kernel" (( x y -- x y x )) }
+    { "pick" "kernel" (( x y z -- x y z x )) }
+    { "swap" "kernel" (( x y -- y x )) }
+    { "eq?" "kernel" (( obj1 obj2 -- ? )) }
+    { "tag" "kernel.private" (( object -- n )) }
+    { "slot" "slots.private" (( obj m -- value )) }
+    { "get-local" "locals.backend" (( n -- obj )) }
+    { "load-local" "locals.backend" (( obj -- )) }
+    { "drop-locals" "locals.backend" (( n -- )) }
+} [ first3 make-sub-primitive ] each
 
 ! Primitive words
-: make-primitive ( word vocab n -- )
-    [ create dup reset-word ] dip
-    [ do-primitive ] curry [ ] like define ;
+: make-primitive ( word vocab n effect -- )
+    [
+        [ create dup reset-word ] dip
+        [ do-primitive ] curry
+    ] dip define-declared ;
 
 {
-    { "bignum>fixnum" "math.private" }
-    { "float>fixnum" "math.private" }
-    { "fixnum>bignum" "math.private" }
-    { "float>bignum" "math.private" }
-    { "fixnum>float" "math.private" }
-    { "bignum>float" "math.private" }
-    { "<ratio>" "math.private" }
-    { "string>float" "math.private" }
-    { "float>string" "math.private" }
-    { "float>bits" "math" }
-    { "double>bits" "math" }
-    { "bits>float" "math" }
-    { "bits>double" "math" }
-    { "<complex>" "math.private" }
-    { "fixnum+" "math.private" }
-    { "fixnum-" "math.private" }
-    { "fixnum*" "math.private" }
-    { "fixnum/i" "math.private" }
-    { "fixnum/mod" "math.private" }
-    { "fixnum-shift" "math.private" }
-    { "bignum=" "math.private" }
-    { "bignum+" "math.private" }
-    { "bignum-" "math.private" }
-    { "bignum*" "math.private" }
-    { "bignum/i" "math.private" }
-    { "bignum-mod" "math.private" }
-    { "bignum/mod" "math.private" }
-    { "bignum-bitand" "math.private" }
-    { "bignum-bitor" "math.private" }
-    { "bignum-bitxor" "math.private" }
-    { "bignum-bitnot" "math.private" }
-    { "bignum-shift" "math.private" }
-    { "bignum<" "math.private" }
-    { "bignum<=" "math.private" }
-    { "bignum>" "math.private" }
-    { "bignum>=" "math.private" }
-    { "bignum-bit?" "math.private" }
-    { "bignum-log2" "math.private" }
-    { "byte-array>bignum" "math" }
-    { "float=" "math.private" }
-    { "float+" "math.private" }
-    { "float-" "math.private" }
-    { "float*" "math.private" }
-    { "float/f" "math.private" }
-    { "float-mod" "math.private" }
-    { "float<" "math.private" }
-    { "float<=" "math.private" }
-    { "float>" "math.private" }
-    { "float>=" "math.private" }
-    { "<word>" "words" }
-    { "word-xt" "words" }
-    { "getenv" "kernel.private" }
-    { "setenv" "kernel.private" }
-    { "(exists?)" "io.files.private" }
-    { "gc" "memory" }
-    { "gc-stats" "memory" }
-    { "save-image" "memory" }
-    { "save-image-and-exit" "memory" }
-    { "datastack" "kernel" }
-    { "retainstack" "kernel" }
-    { "callstack" "kernel" }
-    { "set-datastack" "kernel" }
-    { "set-retainstack" "kernel" }
-    { "set-callstack" "kernel" }
-    { "exit" "system" }
-    { "data-room" "memory" }
-    { "code-room" "memory" }
-    { "micros" "system" }
-    { "modify-code-heap" "compiler.units" }
-    { "dlopen" "alien" }
-    { "dlsym" "alien" }
-    { "dlclose" "alien" }
-    { "<byte-array>" "byte-arrays" }
-    { "(byte-array)" "byte-arrays" }
-    { "<displaced-alien>" "alien" }
-    { "alien-signed-cell" "alien.accessors" }
-    { "set-alien-signed-cell" "alien.accessors" }
-    { "alien-unsigned-cell" "alien.accessors" }
-    { "set-alien-unsigned-cell" "alien.accessors" }
-    { "alien-signed-8" "alien.accessors" }
-    { "set-alien-signed-8" "alien.accessors" }
-    { "alien-unsigned-8" "alien.accessors" }
-    { "set-alien-unsigned-8" "alien.accessors" }
-    { "alien-signed-4" "alien.accessors" }
-    { "set-alien-signed-4" "alien.accessors" }
-    { "alien-unsigned-4" "alien.accessors" }
-    { "set-alien-unsigned-4" "alien.accessors" }
-    { "alien-signed-2" "alien.accessors" }
-    { "set-alien-signed-2" "alien.accessors" }
-    { "alien-unsigned-2" "alien.accessors" }
-    { "set-alien-unsigned-2" "alien.accessors" }
-    { "alien-signed-1" "alien.accessors" }
-    { "set-alien-signed-1" "alien.accessors" }
-    { "alien-unsigned-1" "alien.accessors" }
-    { "set-alien-unsigned-1" "alien.accessors" }
-    { "alien-float" "alien.accessors" }
-    { "set-alien-float" "alien.accessors" }
-    { "alien-double" "alien.accessors" }
-    { "set-alien-double" "alien.accessors" }
-    { "alien-cell" "alien.accessors" }
-    { "set-alien-cell" "alien.accessors" }
-    { "(throw)" "kernel.private" }
-    { "alien-address" "alien" }
-    { "set-slot" "slots.private" }
-    { "string-nth" "strings.private" }
-    { "set-string-nth-fast" "strings.private" }
-    { "set-string-nth-slow" "strings.private" }
-    { "resize-array" "arrays" }
-    { "resize-string" "strings" }
-    { "<array>" "arrays" }
-    { "begin-scan" "memory" }
-    { "next-object" "memory" }
-    { "end-scan" "memory" }
-    { "size" "memory" }
-    { "die" "kernel" }
-    { "fopen" "io.streams.c" }
-    { "fgetc" "io.streams.c" }
-    { "fread" "io.streams.c" }
-    { "fputc" "io.streams.c" }
-    { "fwrite" "io.streams.c" }
-    { "fflush" "io.streams.c" }
-    { "fclose" "io.streams.c" }
-    { "<wrapper>" "kernel" }
-    { "(clone)" "kernel" }
-    { "<string>" "strings" }
-    { "array>quotation" "quotations.private" }
-    { "quotation-xt" "quotations" }
-    { "<tuple>" "classes.tuple.private" }
-    { "profiling" "tools.profiler.private" }
-    { "become" "kernel.private" }
-    { "(sleep)" "threads.private" }
-    { "<tuple-boa>" "classes.tuple.private" }
-    { "callstack>array" "kernel" }
-    { "innermost-frame-quot" "kernel.private" }
-    { "innermost-frame-scan" "kernel.private" }
-    { "set-innermost-frame-quot" "kernel.private" }
-    { "call-clear" "kernel" }
-    { "resize-byte-array" "byte-arrays" }
-    { "dll-valid?" "alien" }
-    { "unimplemented" "kernel.private" }
-    { "gc-reset" "memory" }
-    { "jit-compile" "quotations" }
-    { "load-locals" "locals.backend" }
-}
-[ [ first2 ] dip make-primitive ] each-index
+    { "bignum>fixnum" "math.private" (( x -- y )) }
+    { "float>fixnum" "math.private" (( x -- y )) }
+    { "fixnum>bignum" "math.private" (( x -- y )) }
+    { "float>bignum" "math.private" (( x -- y )) }
+    { "fixnum>float" "math.private" (( x -- y )) }
+    { "bignum>float" "math.private" (( x -- y )) }
+    { "<ratio>" "math.private" (( a b -- a/b )) }
+    { "string>float" "math.private" (( str -- n/f )) }
+    { "float>string" "math.private" (( n -- str )) }
+    { "float>bits" "math" (( x -- n )) }
+    { "double>bits" "math" (( x -- n )) }
+    { "bits>float" "math" (( n -- x )) }
+    { "bits>double" "math" (( n -- x )) }
+    { "<complex>" "math.private" (( x y -- z )) }
+    { "fixnum+" "math.private" (( x y -- z )) }
+    { "fixnum-" "math.private" (( x y -- z )) }
+    { "fixnum*" "math.private" (( x y -- z )) }
+    { "fixnum/i" "math.private" (( x y -- z )) }
+    { "fixnum/mod" "math.private" (( x y -- z w )) }
+    { "fixnum-shift" "math.private" (( x y -- z )) }
+    { "bignum=" "math.private" (( x y -- ? )) }
+    { "bignum+" "math.private" (( x y -- z )) }
+    { "bignum-" "math.private" (( x y -- z )) }
+    { "bignum*" "math.private" (( x y -- z )) }
+    { "bignum/i" "math.private" (( x y -- z )) }
+    { "bignum-mod" "math.private" (( x y -- z )) }
+    { "bignum/mod" "math.private" (( x y -- z w )) }
+    { "bignum-bitand" "math.private" (( x y -- z )) }
+    { "bignum-bitor" "math.private" (( x y -- z )) }
+    { "bignum-bitxor" "math.private" (( x y -- z )) }
+    { "bignum-bitnot" "math.private" (( x -- y )) }
+    { "bignum-shift" "math.private" (( x y -- z )) }
+    { "bignum<" "math.private" (( x y -- ? )) }
+    { "bignum<=" "math.private" (( x y -- ? )) }
+    { "bignum>" "math.private" (( x y -- ? )) }
+    { "bignum>=" "math.private" (( x y -- ? )) }
+    { "bignum-bit?" "math.private" (( n x -- ? )) }
+    { "bignum-log2" "math.private" (( x -- n )) }
+    { "byte-array>bignum" "math" (( x -- y ))  }
+    { "float=" "math.private" (( x y -- ? )) }
+    { "float+" "math.private" (( x y -- z )) }
+    { "float-" "math.private" (( x y -- z )) }
+    { "float*" "math.private" (( x y -- z )) }
+    { "float/f" "math.private" (( x y -- z )) }
+    { "float-mod" "math.private" (( x y -- z )) }
+    { "float<" "math.private" (( x y -- ? )) }
+    { "float<=" "math.private" (( x y -- ? )) }
+    { "float>" "math.private" (( x y -- ? )) }
+    { "float>=" "math.private" (( x y -- ? )) }
+    { "<word>" "words" (( name vocab -- word )) }
+    { "word-xt" "words" (( word -- start end )) }
+    { "getenv" "kernel.private" (( n -- obj )) }
+    { "setenv" "kernel.private" (( obj n -- )) }
+    { "(exists?)" "io.files.private" (( path -- ? )) }
+    { "gc" "memory" (( -- )) }
+    { "gc-stats" "memory" }
+    { "save-image" "memory" (( path -- )) }
+    { "save-image-and-exit" "memory" (( path -- )) }
+    { "datastack" "kernel" (( -- ds )) }
+    { "retainstack" "kernel" (( -- rs )) }
+    { "callstack" "kernel" (( -- cs )) }
+    { "set-datastack" "kernel" (( ds -- )) }
+    { "set-retainstack" "kernel" (( rs -- )) }
+    { "set-callstack" "kernel" (( cs -- )) }
+    { "exit" "system" (( n -- )) }
+    { "data-room" "memory" (( -- cards generations )) }
+    { "code-room" "memory" (( -- code-free code-total )) }
+    { "micros" "system" (( -- us )) }
+    { "modify-code-heap" "compiler.units" (( alist -- )) }
+    { "dlopen" "alien.libraries" (( path -- dll )) }
+    { "dlsym" "alien.libraries" (( name dll -- alien )) }
+    { "dlclose" "alien.libraries" (( dll -- )) }
+    { "<byte-array>" "byte-arrays" (( n -- byte-array )) }
+    { "(byte-array)" "byte-arrays" (( n -- byte-array )) }
+    { "<displaced-alien>" "alien" (( displacement c-ptr -- alien )) }
+    { "alien-signed-cell" "alien.accessors" }
+    { "set-alien-signed-cell" "alien.accessors" }
+    { "alien-unsigned-cell" "alien.accessors" }
+    { "set-alien-unsigned-cell" "alien.accessors" }
+    { "alien-signed-8" "alien.accessors" }
+    { "set-alien-signed-8" "alien.accessors" }
+    { "alien-unsigned-8" "alien.accessors" }
+    { "set-alien-unsigned-8" "alien.accessors" }
+    { "alien-signed-4" "alien.accessors" }
+    { "set-alien-signed-4" "alien.accessors" }
+    { "alien-unsigned-4" "alien.accessors" }
+    { "set-alien-unsigned-4" "alien.accessors" }
+    { "alien-signed-2" "alien.accessors" }
+    { "set-alien-signed-2" "alien.accessors" }
+    { "alien-unsigned-2" "alien.accessors" }
+    { "set-alien-unsigned-2" "alien.accessors" }
+    { "alien-signed-1" "alien.accessors" }
+    { "set-alien-signed-1" "alien.accessors" }
+    { "alien-unsigned-1" "alien.accessors" }
+    { "set-alien-unsigned-1" "alien.accessors" }
+    { "alien-float" "alien.accessors" }
+    { "set-alien-float" "alien.accessors" }
+    { "alien-double" "alien.accessors" }
+    { "set-alien-double" "alien.accessors" }
+    { "alien-cell" "alien.accessors" }
+    { "set-alien-cell" "alien.accessors" }
+    { "alien-address" "alien" (( c-ptr -- addr )) }
+    { "set-slot" "slots.private" (( value obj n -- )) }
+    { "string-nth" "strings.private" (( n string -- ch )) }
+    { "set-string-nth-fast" "strings.private" (( ch n string -- )) }
+    { "set-string-nth-slow" "strings.private" (( ch n string -- )) }
+    { "resize-array" "arrays" (( n array -- newarray )) }
+    { "resize-string" "strings" (( n str -- newstr )) }
+    { "<array>" "arrays" (( n elt -- array )) }
+    { "begin-scan" "memory" (( -- )) }
+    { "next-object" "memory" (( -- obj )) }
+    { "end-scan" "memory" (( -- )) }
+    { "size" "memory" (( obj -- n )) }
+    { "die" "kernel" (( -- )) }
+    { "fopen" "io.streams.c" (( path mode -- alien )) }
+    { "fgetc" "io.streams.c" (( alien -- ch/f )) }
+    { "fread" "io.streams.c" (( n alien -- str/f )) }
+    { "fputc" "io.streams.c" (( ch alien -- )) }
+    { "fwrite" "io.streams.c" (( string alien -- )) }
+    { "fflush" "io.streams.c" (( alien -- )) }
+    { "fseek" "io.streams.c" (( alien offset whence -- )) }
+    { "fclose" "io.streams.c" (( alien -- )) }
+    { "<wrapper>" "kernel" (( obj -- wrapper )) }
+    { "(clone)" "kernel" (( obj -- newobj )) }
+    { "<string>" "strings" (( n ch -- string )) }
+    { "array>quotation" "quotations.private" (( array -- quot )) }
+    { "quotation-xt" "quotations" (( quot -- xt )) }
+    { "<tuple>" "classes.tuple.private" (( layout -- tuple )) }
+    { "profiling" "tools.profiler.private" (( ? -- )) }
+    { "become" "kernel.private" (( old new -- )) }
+    { "(sleep)" "threads.private" (( us -- )) }
+    { "<tuple-boa>" "classes.tuple.private" (( ... layout -- tuple )) }
+    { "callstack>array" "kernel" (( callstack -- array )) }
+    { "innermost-frame-quot" "kernel.private" (( callstack -- quot )) }
+    { "innermost-frame-scan" "kernel.private" (( callstack -- n )) }
+    { "set-innermost-frame-quot" "kernel.private" (( n callstack -- )) }
+    { "call-clear" "kernel" (( quot -- )) }
+    { "resize-byte-array" "byte-arrays" (( n byte-array -- newbyte-array )) }
+    { "dll-valid?" "alien" (( dll -- ? )) }
+    { "unimplemented" "kernel.private" (( -- * )) }
+    { "gc-reset" "memory" (( -- )) }
+    { "jit-compile" "quotations" (( quot -- )) }
+    { "load-locals" "locals.backend" (( ... n -- )) }
+    { "check-datastack" "kernel.private" (( array in# out# -- ? )) }
+} [ [ first3 ] dip swap make-primitive ] each-index
 
 ! Bump build number
 "build" "kernel" create build 1+ [ ] curry (( -- n )) define-declared
index 654a8f5f3468b61f29b1b3b4b601350b9ec43081..a0b349be51b9e2c2731297f450e599d2d8cd29bb 100644 (file)
@@ -57,10 +57,12 @@ IN: bootstrap.syntax
     "EXCLUDE:"
     "RENAME:"
     "ALIAS:"
+    "SYNTAX:"
     "V{"
     "W{"
     "["
     "\\"
+    "M\\"
     "]"
     "delimiter"
     "f"
@@ -68,7 +70,6 @@ IN: bootstrap.syntax
     "foldable"
     "inline"
     "recursive"
-    "parsing"
     "t"
     "{"
     "}"
@@ -78,6 +79,8 @@ IN: bootstrap.syntax
     "call-next-method"
     "initial:"
     "read-only"
+    "call("
+    "execute("
 } [ "syntax" create drop ] each
 
 "t" "syntax" lookup define-symbol
index 0e4a3b56fde4218ae824fa275becf8547b513e39..f95d66fd05c02731d556752b4df57611cd72d3bb 100644 (file)
@@ -55,7 +55,7 @@ M: anonymous-intersection (flatten-class)
     [
         builtins get sift [ (flatten-class) ] each
     ] [
-        unclip [ assoc-intersect ] reduce [ swap set ] assoc-each
+        [ ] [ assoc-intersect ] map-reduce [ swap set ] assoc-each
     ] if-empty ;
 
 M: anonymous-complement (flatten-class)
index 8145730f401f91c9a28ca0ba02c8aa23e5c3fd4f..ab8ba398cda09ad22208424f97005a127b423977 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions assocs kernel kernel.private
 slots.private namespaces make sequences strings words words.symbol
@@ -42,8 +42,11 @@ PREDICATE: class < word "class" word-prop ;
 
 PREDICATE: predicate < word "predicating" word-prop >boolean ;
 
+M: predicate forget*
+    [ call-next-method ] [ f "predicating" set-word-prop ] bi ;
+
 M: predicate reset-word
-    [ call-next-method ] [ { "predicating" } reset-props ] bi ;
+    [ call-next-method ] [ f "predicating" set-word-prop ] bi ;
 
 : define-predicate ( class quot -- )
     [ "predicate" word-prop first ] dip
@@ -123,14 +126,19 @@ M: sequence implementors [ implementors ] gather ;
         } spread
     ] H{ } make-assoc ;
 
+: ?define-symbol ( word -- )
+    dup deferred? [ define-symbol ] [ drop ] if ;
+
 : (define-class) ( word props -- )
     [
-        dup class? [ dup [ implementors-map+ ] [ new-class ] bi ] unless
-        dup reset-class
-        dup deferred? [ dup define-symbol ] when
-        dup redefined
-        dup props>>
-    ] dip assoc-union >>props
+        {
+            [ dup class? [ drop ] [ [ implementors-map+ ] [ new-class ] bi ] if ]
+            [ reset-class ]
+            [ ?define-symbol ]
+            [ redefined ]
+            [ ]
+        } cleave
+    ] dip [ assoc-union ] curry change-props
     dup predicate-word
     [ 1quotation "predicate" set-word-prop ]
     [ swap "predicating" set-word-prop ]
@@ -166,8 +174,7 @@ GENERIC: update-methods ( class seq -- )
         [ forget ] [ drop ] if
     ] [ 2drop ] if ;
 
-: forget-methods ( class -- )
-    [ implementors ] [ [ swap 2array ] curry ] bi map forget-all ;
+GENERIC: forget-methods ( class -- )
 
 GENERIC: class-forgotten ( use class -- )
 
index 9a372e633ecb8cf5b6b2a4fc22c6bf0c0de4b691..376eace4ed5c887ec5017c0dfde6536aae2b16ea 100644 (file)
@@ -109,3 +109,13 @@ TUPLE: flat-mx-2-1 ; INSTANCE: flat-mx-2-1 flat-mx-2
 MIXIN: empty-mixin
 
 [ f ] [ "hi" empty-mixin? ] unit-test
+
+MIXIN: move-instance-declaration-mixin
+
+[ ] [ "IN: classes.mixin.tests.a USE: strings USE: classes.mixin.tests INSTANCE: string move-instance-declaration-mixin" <string-reader> "move-mixin-test-1" parse-stream drop ] unit-test
+
+[ ] [ "IN: classes.mixin.tests.b USE: strings USE: classes.mixin.tests INSTANCE: string move-instance-declaration-mixin" <string-reader> "move-mixin-test-2" parse-stream drop ] unit-test
+
+[ ] [ "IN: classes.mixin.tests.a" <string-reader> "move-mixin-test-1" parse-stream drop ] unit-test
+
+[ { string } ] [ move-instance-declaration-mixin members ] unit-test
\ No newline at end of file
index 1261d44a6984ebea80e5f3989a3eed75d4f8e18f..4bdb893d9adfcc920cfbd27e29419c5be83cab6c 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: classes classes.union words kernel sequences
 definitions combinators arrays assocs generic accessors ;
@@ -21,8 +21,9 @@ M: mixin-class rank-class drop 3 ;
         drop
     ] [
         [ { } redefine-mixin-class ]
+        [ H{ } clone "instances" set-word-prop ]
         [ update-classes ]
-        bi
+        tri
     ] if ;
 
 TUPLE: check-mixin-class class ;
@@ -44,6 +45,11 @@ TUPLE: check-mixin-class class ;
     [ [ update-class ] each ]
     [ implementors [ remake-generic ] each ] bi ;
 
+: (add-mixin-instance) ( class mixin -- )
+    [ [ suffix ] change-mixin-class ]
+    [ [ f ] 2dip "instances" word-prop set-at ]
+    2bi ;
+
 : add-mixin-instance ( class mixin -- )
     #! Note: we call update-classes on the new member, not the
     #! mixin. This ensures that we only have to update the
@@ -53,20 +59,22 @@ TUPLE: check-mixin-class class ;
     #! updated by transitivity; the mixins usages appear in
     #! class-usages of the member, now that it's been added.
     [ 2drop ] [
-        [ [ suffix ] change-mixin-class ] 2keep
-        [ nip ] [ [ new-class? ] either? ] 2bi [
-            update-classes/new
-        ] [
-            update-classes
-        ] if
+        [ (add-mixin-instance) ] 2keep
+        [ nip ] [ [ new-class? ] either? ] 2bi
+        [ update-classes/new ] [ update-classes ] if
     ] if-mixin-member? ;
 
+: (remove-mixin-instance) ( class mixin -- )
+    [ [ swap remove ] change-mixin-class ]
+    [ "instances" word-prop delete-at ]
+    2bi ;
+
 : remove-mixin-instance ( class mixin -- )
     #! The order of the three clauses is important here. The last
     #! one must come after the other two so that the entries it
     #! adds to changed-generics are not overwritten.
     [
-        [ [ swap remove ] change-mixin-class ]
+        [ (remove-mixin-instance) ]
         [ nip update-classes ]
         [ class-usages update-methods ]
         2tri
@@ -76,32 +84,21 @@ M: mixin-class class-forgotten remove-mixin-instance ;
 
 ! Definition protocol implementation ensures that removing an
 ! INSTANCE: declaration from a source file updates the mixin.
-TUPLE: mixin-instance loc class mixin ;
-
-M: mixin-instance equal?
-    {
-        { [ over mixin-instance? not ] [ f ] }
-        { [ 2dup [ class>> ] bi@ = not ] [ f ] }
-        { [ 2dup [ mixin>> ] bi@ = not ] [ f ] }
-        [ t ]
-    } cond 2nip ;
+TUPLE: mixin-instance class mixin ;
 
-M: mixin-instance hashcode*
-    [ class>> ] [ mixin>> ] bi 2array hashcode* ;
+C: <mixin-instance> mixin-instance
 
-: <mixin-instance> ( class mixin -- definition )
-    mixin-instance new
-        swap >>mixin
-        swap >>class ;
+: >mixin-instance< ( mixin-instance -- class mixin )
+    [ class>> ] [ mixin>> ] bi ; inline
 
-M: mixin-instance where loc>> ;
+M: mixin-instance where >mixin-instance< "instances" word-prop at ;
 
-M: mixin-instance set-where (>>loc) ;
+M: mixin-instance set-where >mixin-instance< "instances" word-prop set-at ;
 
 M: mixin-instance definer drop \ INSTANCE: f ;
 
 M: mixin-instance definition drop f ;
 
 M: mixin-instance forget*
-    [ class>> ] [ mixin>> ] bi
+    >mixin-instance<
     dup mixin-class? [ remove-mixin-instance ] [ 2drop ] if ;
index 3de073f774f9806d2b4d7c9979a95ad71445c441..a947b9ddc09af419925ab52d60e65a979fdda998 100644 (file)
@@ -1,4 +1,4 @@
-USING: math tools.test classes.algebra ;
+USING: math tools.test classes.algebra words kernel sequences assocs ;
 IN: classes.predicate
 
 PREDICATE: negative < integer 0 < ;
@@ -18,4 +18,4 @@ M: positive abs ;
 
 [ 10 ] [ -10 abs ] unit-test
 [ 10 ] [ 10 abs ] unit-test
-[ 0 ] [ 0 abs ] unit-test
+[ 0 ] [ 0 abs ] unit-test
\ No newline at end of file
index 4ba93acae46674f284541e0ef34edd8d970c9f64..188a2ed794b6e88b3f9455420d4fcec978b96c53 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: classes classes.algebra kernel namespaces make words
 sequences quotations arrays kernel.private assocs combinators ;
@@ -7,26 +7,12 @@ IN: classes.predicate
 PREDICATE: predicate-class < class
     "metaclass" word-prop predicate-class eq? ;
 
-DEFER: predicate-instance? ( object class -- ? )
-
-: update-predicate-instance ( -- )
-    \ predicate-instance? bootstrap-word
-    classes [ predicate-class? ] filter [
-        [ literalize ]
-        [
-            [ superclass 1array [ declare ] curry ]
-            [ "predicate-definition" word-prop ]
-            bi compose
-        ]
-        bi
-    ] { } map>assoc [ case ] curry
-    define ;
-
 : predicate-quot ( class -- quot )
     [
         \ dup ,
-        dup superclass "predicate" word-prop %
-        "predicate-definition" word-prop , [ drop f ] , \ if ,
+        [ superclass "predicate" word-prop % ]
+        [ "predicate-definition" word-prop , ] bi
+        [ drop f ] , \ if ,
     ] [ ] make ;
 
 : define-predicate-class ( class superclass definition -- )
@@ -37,20 +23,17 @@ DEFER: predicate-instance? ( object class -- ? )
         [ dup predicate-quot define-predicate ]
         [ update-classes ]
         bi
-    ]
-    3tri
-    update-predicate-instance ;
+    ] 3tri ;
 
 M: predicate-class reset-class
-    [ call-next-method ]
-    [ { "predicate-definition" } reset-props ]
-    bi ;
+    [ call-next-method ] [ { "predicate-definition" } reset-props ] bi ;
 
 M: predicate-class rank-class drop 1 ;
 
 M: predicate-class instance?
-    2dup superclass instance?
-    [ predicate-instance? ] [ 2drop f ] if ;
+    2dup superclass instance? [
+        "predicate-definition" word-prop call( object -- ? )
+    ] [ 2drop f ] if ;
 
 M: predicate-class (flatten-class)
     superclass (flatten-class) ;
index d9011ad776b61710d371b83f9bc338df00fbbc57..9d0bb7d16f35ea87e82e4fdf68c143d10699fe5b 100644 (file)
@@ -13,7 +13,7 @@ GENERIC: zammo ( obj -- str )
 
 SINGLETON: word-and-singleton
 
-: word-and-singleton 3 ;
+: word-and-singleton ( -- x ) 3 ;
 
 [ t ] [ \ word-and-singleton word-and-singleton? ] unit-test
 [ 3 ] [ word-and-singleton ] unit-test
index 659195edbf3cc99416dfde3917e6de86daaf1b9e..5e12322a4868cceaee6a96a3864f5dcbe5db44f7 100644 (file)
@@ -30,7 +30,7 @@ ERROR: duplicate-slot-names names ;
 
 ERROR: invalid-slot-name name ;
 
-: parse-long-slot-name ( -- )
+: parse-long-slot-name ( -- spec )
     [ scan , \ } parse-until % ] { } make ;
 
 : parse-slot-name ( string/f -- ? )
@@ -64,7 +64,7 @@ ERROR: bad-literal-tuple ;
 
 : parse-slot-value ( -- )
     scan scan-object 2array , scan {
-        { f [ unexpected-eof ] }
+        { f [ \ } unexpected-eof ] }
         { "}" [ ] }
         [ bad-literal-tuple ]
     } case ;
@@ -72,13 +72,13 @@ ERROR: bad-literal-tuple ;
 : (parse-slot-values) ( -- )
     parse-slot-value
     scan {
-        { f [ unexpected-eof ] }
+        { f [ \ } unexpected-eof ] }
         { "{" [ (parse-slot-values) ] }
         { "}" [ ] }
         [ bad-literal-tuple ]
     } case ;
 
-: parse-slot-values ( -- )
+: parse-slot-values ( -- values )
     [ (parse-slot-values) ] { } make ;
 
 : boa>tuple ( class slots -- tuple )
index 32cab6590446182decc73d11e81472cd75c3d39e..d76faddf15fdd9537e1eb9b16a00a1af7cbead90 100644 (file)
@@ -92,7 +92,7 @@ ARTICLE: "tuple-constructors" "Tuple constructors"
 $nl
 "Constructors play a part in enforcing the invariant that slot values must always match slot declarations. The " { $link new } " word fills in the tuple with initial values, and " { $link boa } " ensures that the values on the stack match the corresponding slot declarations. See " { $link "tuple-declarations" } "."
 $nl
-"All tuple construction should be done through constructor words, and construction primitives should be encapsulated and never called outside of the vocabulary where the class is defined, because this encourages looser coupling. For example, a constructor word could be changed to use memoization instead of always constructing a new instance, or it could be changed to construt a different class, without breaking callers."
+"All tuple construction should be done through constructor words, and construction primitives should be encapsulated and never called outside of the vocabulary where the class is defined, because this encourages looser coupling. For example, a constructor word could be changed to use memoization instead of always constructing a new instance, or it could be changed to construct a different class, without breaking callers."
 $nl
 "Examples of constructors:"
 { $code
@@ -220,13 +220,13 @@ ARTICLE: "tuple-examples" "Tuple examples"
     "    <employee> \"project manager\" >>position ;" }
 "An alternative strategy is to define the most general BOA constructor first:"
 { $code
-    ": <employee> ( name position -- person )"
+    ": <employee> ( name position -- employee )"
     "    40000 employee boa ;"
 }
 "Now we can define more specific constructors:"
 { $code
-    ": <manager> ( name -- person )"
-    "    \"manager\" <person> ;" }
+    ": <manager> ( name -- employee )"
+    "    \"manager\" <employee> ;" }
 "An example using reader words:"
 { $code
     "TUPLE: check to amount number ;"
@@ -256,7 +256,7 @@ ARTICLE: "tuple-examples" "Tuple examples"
     ": next-position ( role -- newrole )"
     "    positions [ index 1+ ] keep nth ;"
     ""
-    ": promote ( person -- person )"
+    ": promote ( employee -- employee )"
     "    [ 1.2 * ] change-salary"
     "    [ next-position ] change-position ;"
 }
index f27d24e39dfeb04daabf67e23d0e0c7e20940e40..75d733b213213c7d22e35224a62a35c4bd13943c 100644 (file)
@@ -4,7 +4,8 @@ namespaces quotations sequences.private classes continuations
 generic.standard effects classes.tuple classes.tuple.private
 arrays vectors strings compiler.units accessors classes.algebra
 calendar prettyprint io.streams.string splitting summary
-columns math.order classes.private slots slots.private eval see ;
+columns math.order classes.private slots slots.private eval see
+words.symbol ;
 IN: classes.tuple.tests
 
 TUPLE: rect x y w h ;
@@ -62,7 +63,7 @@ TUPLE: predicate-test ;
 
 C: <predicate-test> predicate-test
 
-: predicate-test drop f ;
+: predicate-test ( a -- ? ) drop f ;
 
 [ t ] [ <predicate-test> predicate-test? ] unit-test
 
@@ -97,7 +98,7 @@ TUPLE: size-test a b c d ;
     size-test tuple-layout second =
 ] unit-test
 
-GENERIC: <yo-momma>
+GENERIC: <yo-momma> ( a -- b )
 
 TUPLE: yo-momma ;
 
@@ -123,7 +124,7 @@ TUPLE: loc-recording ;
 
 TUPLE: forget-robustness ;
 
-GENERIC: forget-robustness-generic
+GENERIC: forget-robustness-generic ( a -- b )
 
 M: forget-robustness forget-robustness-generic ;
 
@@ -132,7 +133,7 @@ M: integer forget-robustness-generic ;
 [
     [ ] [ \ forget-robustness-generic forget ] unit-test
     [ ] [ \ forget-robustness forget ] unit-test
-    [ ] [ { forget-robustness forget-robustness-generic } forget ] unit-test
+    [ ] [ M\ forget-robustness forget-robustness-generic forget ] unit-test
 ] with-compilation-unit
 
 ! rapido found this one
@@ -493,7 +494,7 @@ must-fail-with
 [ t ] [ "z" accessor-exists? ] unit-test
 
 [ [ ] ] [
-    "IN: classes.tuple.tests GENERIC: forget-accessors-test"
+    "IN: classes.tuple.tests GENERIC: forget-accessors-test ( a -- b )"
     <string-reader>
     "forget-accessors-test" parse-stream
 ] unit-test
@@ -508,7 +509,7 @@ TUPLE: another-forget-accessors-test ;
 
 
 [ [ ] ] [
-    "IN: classes.tuple.tests GENERIC: another-forget-accessors-test"
+    "IN: classes.tuple.tests GENERIC: another-forget-accessors-test ( a -- b )"
     <string-reader>
     "another-forget-accessors-test" parse-stream
 ] unit-test
@@ -558,7 +559,7 @@ DEFER: subclass-reset-test-3
 
 GENERIC: break-me ( obj -- )
 
-[ ] [ [ { integer break-me } forget ] with-compilation-unit ] unit-test
+[ ] [ [ M\ integer break-me forget ] with-compilation-unit ] unit-test
 
 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-1 < subclass-reset-test ;" eval ] unit-test
@@ -567,7 +568,7 @@ GENERIC: break-me ( obj -- )
 
 [ ] [ "IN: classes.tuple.tests USE: kernel M: subclass-reset-test-1 break-me drop ;" eval ] unit-test
 
-[ ] [ "IN: classes.tuple.tests : subclass-reset-test ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
+[ ] [ "IN: classes.tuple.tests : subclass-reset-test ( -- ) ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
 
 [ f ] [ subclass-reset-test-1 tuple-class? ] unit-test
 [ f ] [ subclass-reset-test-2 tuple-class? ] unit-test
@@ -666,7 +667,7 @@ DEFER: error-y
 
 [ ] [ [ \ error-y dup class? [ forget-class ] [ drop ] if ] with-compilation-unit ] unit-test
 
-[ ] [ "IN: classes.tuple.tests GENERIC: error-y" eval ] unit-test
+[ ] [ "IN: classes.tuple.tests GENERIC: error-y ( a -- b )" eval ] unit-test
 
 [ f ] [ \ error-y tuple-class? ] unit-test
 
@@ -730,4 +731,18 @@ SLOT: kex
 ] unit-test
 
 [ t ] [ \ change-slot-test \ kex>> method >boolean ] unit-test
-[ f ] [ \ change-slot-test \ kex>> method "reading" word-prop ] unit-test
\ No newline at end of file
+[ f ] [ \ change-slot-test \ kex>> method "reading" word-prop ] unit-test
+
+DEFER: redefine-tuple-twice
+
+[ ] [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval ] unit-test
+
+[ t ] [ \ redefine-tuple-twice symbol? ] unit-test
+
+[ ] [ "IN: classes.tuple.tests DEFER: redefine-tuple-twice" eval ] unit-test
+
+[ t ] [ \ redefine-tuple-twice deferred? ] unit-test
+
+[ ] [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval ] unit-test
+
+[ t ] [ \ redefine-tuple-twice symbol? ] unit-test
\ No newline at end of file
index b13bc1bfa256ae5d6accb74c37bce36bf70ad281..fb7a0732050d4640ba5aaf26f4d6564edd36f6a4 100755 (executable)
@@ -4,7 +4,7 @@ USING: arrays definitions hashtables kernel kernel.private math
 namespaces make sequences sequences.private strings vectors
 words quotations memory combinators generic classes
 classes.algebra classes.builtin classes.private slots.private
-slots compiler.units math.private accessors assocs effects ;
+slots math.private accessors assocs effects ;
 IN: classes.tuple
 
 PREDICATE: tuple-class < class
@@ -188,6 +188,8 @@ ERROR: bad-superclass class ;
 : apply-slot-permutation ( old-values triples -- new-values )
     [ first3 update-slot ] with map ;
 
+SYMBOL: outdated-tuples
+
 : permute-slots ( old-values layout -- new-values )
     [ first all-slots ] [ outdated-tuples get at ] bi
     compute-slot-permutation
@@ -212,8 +214,6 @@ ERROR: bad-superclass class ;
         dup [ update-tuple ] map become
     ] if ;
 
-[ update-tuples ] update-tuples-hook set-global
-
 : update-tuples-after ( class -- )
     [ all-slots ] [ tuple-layout ] bi outdated-tuples get set-at ;
 
@@ -247,8 +247,7 @@ M: tuple-class update-class
             bi
         ] each-subclass
     ]
-    [ define-new-tuple-class ]
-    3bi ;
+    [ define-new-tuple-class ] 3bi ;
 
 : tuple-class-unchanged? ( class superclass slots -- ? )
     [ [ superclass ] [ bootstrap-word ] bi* = ]
@@ -275,7 +274,7 @@ M: word (define-tuple-class)
 
 M: tuple-class (define-tuple-class)
     3dup tuple-class-unchanged?
-    [ 3drop ] [ redefine-tuple-class ] if ;
+    [ 2drop ?define-symbol ] [ redefine-tuple-class ] if ;
 
 : thrower-effect ( slots -- effect )
     [ dup array? [ first ] when ] map { "*" } <effect> ;
index 0802c0a2d9d0d28d31b1dbdce6d8a17bd69d437d..57b742595ffcc7f5ef06d4787a960cf9bf0e7d94 100644 (file)
@@ -70,10 +70,14 @@ UNION: redefine-bug-2 redefine-bug-1 quotation ;
 
 [ t ] [ "blah" "classes.union.tests" lookup union-class? ] unit-test
 
+[ t ] [ "foo?" "classes.union.tests" lookup predicate? ] unit-test
+
 [ ] [ "IN: classes.union.tests USE: math UNION: blah integer ;" <string-reader> "union-reset-test" parse-stream drop ] unit-test
 
 [ t ] [ "blah" "classes.union.tests" lookup union-class? ] unit-test
 
+[ f ] [ "foo?" "classes.union.tests" lookup predicate? ] unit-test
+
 GENERIC: test-generic ( x -- y )
 
 TUPLE: a-tuple ;
index 1901f27a24507e2512d93a1f956aaaa0d2f05714..a44f8d7f8d462129605979ca2bec95cc98dc3a48 100644 (file)
@@ -1 +1,2 @@
 Slava Pestov
+Daniel Ehrenberg
index a26c2fbe5d1db84517d0a4af7ab758ef0c782274..9c96fe34c9d1f75badaba22d20e92676198237c9 100644 (file)
 USING: arrays help.markup help.syntax strings sbufs vectors
 kernel quotations generic generic.standard classes
-math assocs sequences sequences.private ;
+math assocs sequences sequences.private combinators.private
+effects words ;
 IN: combinators
 
-ARTICLE: "combinators-quot" "Quotation construction utilities"
-"Some words for creating quotations which can be useful for implementing method combinations and compiler transforms:"
-{ $subsection cond>quot }
-{ $subsection case>quot }
-{ $subsection alist>quot } ;
+ARTICLE: "cleave-shuffle-equivalence" "Expressing shuffle words with cleave combinators"
+"Cleave combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to cleave combinators are discussed in the documentation for " { $link bi } ", " { $link 2bi } ", " { $link 3bi } ", " { $link tri } ", " { $link 2tri } " and " { $link 3tri } "."
+$nl
+"Certain shuffle words can also be expressed in terms of the cleave combinators. Internalizing such identities can help with understanding and writing code using cleave combinators:"
+{ $code
+    ": keep  [ ] bi ;"
+    ": 2keep [ ] 2bi ;"
+    ": 3keep [ ] 3bi ;"
+    ""
+    ": dup   [ ] [ ] bi ;"
+    ": 2dup  [ ] [ ] 2bi ;"
+    ": 3dup  [ ] [ ] 3bi ;"
+    ""
+    ": tuck  [ nip ] [ ] 2bi ;"
+    ": swap  [ nip ] [ drop ] 2bi ;"
+    ""
+    ": over  [ ] [ drop ] 2bi ;"
+    ": pick  [ ] [ 2drop ] 3bi ;"
+    ": 2over [ ] [ drop ] 3bi ;"
+} ;
 
-ARTICLE: "combinators" "Additional combinators"
-"The " { $vocab-link "combinators" } " vocabulary provides a few useful combinators."
+ARTICLE: "cleave-combinators" "Cleave combinators"
+"The cleave combinators apply multiple quotations to a single value."
 $nl
-"Generalization of " { $link bi } " and " { $link tri } ":"
+"Two quotations:"
+{ $subsection bi }
+{ $subsection 2bi }
+{ $subsection 3bi }
+"Three quotations:"
+{ $subsection tri }
+{ $subsection 2tri }
+{ $subsection 3tri }
+"An array of quotations:"
 { $subsection cleave }
-"Generalization of " { $link 2bi } " and " { $link 2tri } ":"
 { $subsection 2cleave }
-"Generalization of " { $link 3bi } " and " { $link 3tri }  ":"
 { $subsection 3cleave }
-"Generalization of " { $link bi* } " and " { $link tri* } ":"
+"Technically, the cleave combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on the top of the stack can be written in one of two ways:"
+{ $code
+    "! First alternative; uses keep"
+    "[ 1 + ] keep"
+    "[ 1 - ] keep"
+    "2 *"
+    "! Second alternative: uses tri"
+    "[ 1 + ]"
+    "[ 1 - ]"
+    "[ 2 * ] tri"
+}
+"The latter is more aesthetically pleasing than the former."
+{ $subsection "cleave-shuffle-equivalence" } ;
+
+ARTICLE: "spread-shuffle-equivalence" "Expressing shuffle words with spread combinators"
+"Spread combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to spread combinators are discussed in the documentation for " { $link bi* } ", " { $link 2bi* } ", " { $link tri* } ", and " { $link 2tri* } "."
+$nl
+"Certain shuffle words can also be expressed in terms of the spread combinators. Internalizing such identities can help with understanding and writing code using spread combinators:"
+{ $code
+    ": dip   [ ] bi* ;"
+    ": 2dip  [ ] [ ] tri* ;"
+    ""
+    ": slip  [ call ] [ ] bi* ;"
+    ": 2slip [ call ] [ ] [ ] tri* ;"
+    ""
+    ": nip   [ drop ] [ ] bi* ;"
+    ": 2nip  [ drop ] [ drop ] [ ] tri* ;"
+    ""
+    ": rot"
+    "    [ [ drop ] [      ] [ drop ] tri* ]"
+    "    [ [ drop ] [ drop ] [      ] tri* ]"
+    "    [ [      ] [ drop ] [ drop ] tri* ]"
+    "    3tri ;"
+    ""
+    ": -rot"
+    "    [ [ drop ] [ drop ] [      ] tri* ]"
+    "    [ [      ] [ drop ] [ drop ] tri* ]"
+    "    [ [ drop ] [      ] [ drop ] tri* ]"
+    "    3tri ;"
+    ""
+    ": spin"
+    "    [ [ drop ] [ drop ] [      ] tri* ]"
+    "    [ [ drop ] [      ] [ drop ] tri* ]"
+    "    [ [      ] [ drop ] [ drop ] tri* ]"
+    "    3tri ;"
+} ;
+
+ARTICLE: "spread-combinators" "Spread combinators"
+"The spread combinators apply multiple quotations to multiple values. The " { $snippet "*" } " suffix signifies spreading."
+$nl
+"Two quotations:"
+{ $subsection bi* }
+{ $subsection 2bi* }
+"Three quotations:"
+{ $subsection tri* }
+{ $subsection 2tri* }
+"An array of quotations:"
 { $subsection spread }
+"Technically, the spread combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on three related values can be written in one of two ways:"
+{ $code
+    "! First alternative; uses dip"
+    "[ [ 1 + ] dip 1 - ] dip 2 *"
+    "! Second alternative: uses tri*"
+    "[ 1 + ] [ 1 - ] [ 2 * ] tri*"
+}
+"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
+{ $subsection "spread-shuffle-equivalence" } ;
+
+ARTICLE: "apply-combinators" "Apply combinators"
+"The apply combinators apply a single quotation to multiple values. The " { $snippet "@" } " suffix signifies application."
+$nl
+"Two quotations:"
+{ $subsection bi@ }
+{ $subsection 2bi@ }
+"Three quotations:"
+{ $subsection tri@ }
+{ $subsection 2tri@ }
+"A pair of utility words built from " { $link bi@ } ":"
+{ $subsection both? }
+{ $subsection either? } ;
+
+ARTICLE: "slip-keep-combinators" "Retain stack combinators"
+"Sometimes an additional storage area is needed to hold objects. The " { $emphasis "retain stack" } " is an auxilliary stack for this purpose. Objects can be moved between the data and retain stacks using a set of combinators."
+$nl
+"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
+{ $subsection dip }
+{ $subsection 2dip }
+{ $subsection 3dip }
+{ $subsection 4dip }
+"The slip combinators invoke a quotation further down on the stack. They are most useful for implementing other combinators:"
+{ $subsection slip }
+{ $subsection 2slip }
+{ $subsection 3slip }
+"The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
+{ $subsection keep }
+{ $subsection 2keep }
+{ $subsection 3keep } ;
+
+ARTICLE: "curried-dataflow" "Curried dataflow combinators"
+"Curried cleave combinators:"
+{ $subsection bi-curry }
+{ $subsection tri-curry }
+"Curried spread combinators:"
+{ $subsection bi-curry* }
+{ $subsection tri-curry* }
+"Curried apply combinators:"
+{ $subsection bi-curry@ }
+{ $subsection tri-curry@ }
+{ $see-also "dataflow-combinators" } ;
+
+ARTICLE: "compositional-examples" "Examples of compositional combinator usage"
+"Consider printing the same message ten times:"
+{ $code ": print-10 ( -- ) 10 [ \"Hello, world.\" print ] times ;" }
+"if we wanted to abstract out the message into a parameter, we could keep it on the stack between iterations:"
+{ $code ": print-10 ( message -- ) 10 [ dup print ] times drop ;" }
+"However, keeping loop-invariant values on the stack doesn't always work out nicely. For example, a word to subtract a value from each element of a sequence:"
+{ $code ": subtract-n ( seq n -- seq' ) swap [ over - ] map nip ;" }
+"Three shuffle words are required to pass the value around. Instead, the loop-invariant value can be partially applied to a quotation using " { $link curry } ", yielding a new quotation that is passed to " { $link map } ":"
+{ $example
+  "USING: kernel math prettyprint sequences ;"
+  ": subtract-n ( seq n -- seq' ) [ - ] curry map ;"
+  "{ 10 20 30 } 5 subtract-n ."
+  "{ 5 15 25 }"
+}
+"Now consider the word that is dual to the one above; instead of subtracting " { $snippet "n" } " from each stack element, it subtracts each element from " { $snippet "n" } "."
+$nl
+"One way to write this is with a pair of " { $link swap } "s:"
+{ $code ": n-subtract ( n seq -- seq' ) swap [ swap - ] curry map ;" }
+"Since this pattern comes up often, " { $link with } " encapsulates it:"
+{ $example
+  "USING: kernel math prettyprint sequences ;"
+  ": n-subtract ( n seq -- seq' ) [ - ] with map ;"
+  "30 { 10 20 30 } n-subtract ."
+  "{ 20 10 0 }"
+}
+{ $see-also "fry.examples" } ;
+
+ARTICLE: "compositional-combinators" "Compositional combinators"
+"Certain combinators transform quotations to produce a new quotation."
+{ $subsection "compositional-examples" }
+"Fundamental operations:"
+{ $subsection curry }
+{ $subsection compose }
+"Derived operations:"
+{ $subsection 2curry }
+{ $subsection 3curry }
+{ $subsection with }
+{ $subsection prepose }
+"These operations run in constant time, and in many cases are optimized out altogether by the " { $link "compiler" } ". " { $link "fry" } " are an abstraction built on top of these operations, and code that uses this abstraction is often clearer than direct calls to the below words."
+$nl
+"Curried dataflow combinators can be used to build more complex dataflow by combining cleave, spread and apply patterns in various ways."
+{ $subsection "curried-dataflow" }
+"Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } ". However, such runtime quotation manipulation will not be optimized by the optimizing compiler." ;
+
+ARTICLE: "booleans" "Booleans"
+"In Factor, any object that is not " { $link f } " has a true value, and " { $link f } " has a false value. The " { $link t } " object is the canonical true value."
+{ $subsection f }
+{ $subsection t }
+"There are some logical operations on booleans:"
+{ $subsection >boolean }
+{ $subsection not }
+{ $subsection and }
+{ $subsection or }
+{ $subsection xor }
+"Boolean values are most frequently used for " { $link "conditionals" } "."
+{ $heading "The f object and f class" }
+"The " { $link f } " object is the unique instance of the " { $link f } " class; the two are distinct objects. The latter is also a parsing word which adds the " { $link f } " object to the parse tree at parse time. To refer to the class itself you must use " { $link POSTPONE: POSTPONE: } " or " { $link POSTPONE: \ } " to prevent the parsing word from executing."
+$nl
+"Here is the " { $link f } " object:"
+{ $example "f ." "f" }
+"Here is the " { $link f } " class:"
+{ $example "\\ f ." "POSTPONE: f" }
+"They are not equal:"
+{ $example "f \\ f = ." "f" }
+"Here is an array containing the " { $link f } " object:"
+{ $example "{ f } ." "{ f }" }
+"Here is an array containing the " { $link f } " class:"
+{ $example "{ POSTPONE: f } ." "{ POSTPONE: f }" }
+"The " { $link f } " object is an instance of the " { $link f } " class:"
+{ $example "USE: classes" "f class ." "POSTPONE: f" }
+"The " { $link f } " class is an instance of " { $link word } ":"
+{ $example "USE: classes" "\\ f class ." "word" }
+"On the other hand, " { $link t } " is just a word, and there is no class which it is a unique instance of."
+{ $example "t \\ t eq? ." "t" }
+"Many words which search collections confuse the case of no element being present with an element being found equal to " { $link f } ". If this distinction is imporant, there is usually an alternative word which can be used; for example, compare " { $link at } " with " { $link at* } "." ;
+
+ARTICLE: "conditionals-boolean-equivalence" "Expressing conditionals with boolean logic"
+"Certain simple conditional forms can be expressed in a simpler manner using boolean logic."
+$nl
+"The following two lines are equivalent:"
+{ $code "[ drop f ] unless" "swap and" }
+"The following two lines are equivalent:"
+{ $code "[ ] [ ] ?if" "swap or" }
+"The following two lines are equivalent, where " { $snippet "L" } " is a literal:"
+{ $code "[ L ] unless*" "L or" } ;
+
+ARTICLE: "conditionals" "Conditional combinators"
+"The basic conditionals:"
+{ $subsection if }
+{ $subsection when }
+{ $subsection unless }
+"Forms abstracting a common stack shuffle pattern:"
+{ $subsection if* }
+{ $subsection when* }
+{ $subsection unless* }
+"Another form abstracting a common stack shuffle pattern:"
+{ $subsection ?if }
+"Sometimes instead of branching, you just need to pick one of two values:"
+{ $subsection ? }
 "Two combinators which abstract out nested chains of " { $link if } ":"
 { $subsection cond }
 { $subsection case }
-"The " { $vocab-link "combinators" } " also provides some less frequently-used features."
+{ $subsection "conditionals-boolean-equivalence" }
+{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
+
+ARTICLE: "dataflow-combinators" "Data flow combinators"
+"Data flow combinators pass values between quotations:"
+{ $subsection "slip-keep-combinators" }
+{ $subsection "cleave-combinators" }
+{ $subsection "spread-combinators" }
+{ $subsection "apply-combinators" }
+{ $see-also "curried-dataflow" } ;
+
+ARTICLE: "combinators-quot" "Quotation construction utilities"
+"Some words for creating quotations which can be useful for implementing method combinations and compiler transforms:"
+{ $subsection cond>quot }
+{ $subsection case>quot }
+{ $subsection alist>quot } ;
+
+ARTICLE: "call" "Fundamental combinators"
+"The most basic combinators are those that take either a quotation or word, and invoke it immediately. There are two sets of combinators; they differe in whether or not the stack effect of the expected code is declared."
+$nl
+"The simplest combinators do not take an effect declaration:"
+{ $subsection call }
+{ $subsection execute }
+"These combinators only get optimized by the compiler if the quotation or word parameter is a literal; otherwise a compiler warning will result. Definitions of combinators which require literal parameters must be followed by the " { $link POSTPONE: inline } " declaration. For example:"
+{ $code
+    ": keep ( x quot -- x )"
+    "    over [ call ] dip ; inline"
+}
+"See " { $link "declarations" } " and " { $link "compiler-errors" } " for details."
+$nl
+"The other set of combinators allow arbitrary quotations and words to be called from optimized code. This is done by specifying the stack effect of the quotation literally. It is checked at runtime that the stack effect is accurate."
+{ $subsection call-effect }
+{ $subsection execute-effect }
+"A simple layer of syntax sugar is defined on top:"
+{ $subsection POSTPONE: call( }
+{ $subsection POSTPONE: execute( }
+"Unsafe calls declare an effect statically without any runtime checking:"
+{ $subsection call-effect-unsafe }
+{ $subsection execute-effect-unsafe }
+{ $see-also "effects" "inference" } ;
+
+ARTICLE: "combinators" "Combinators"
+"A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
+{ $subsection "call" }
+{ $subsection "dataflow-combinators" }
+{ $subsection "conditionals" }
+{ $subsection "looping-combinators" }
+{ $subsection "compositional-combinators" }
+{ $subsection "combinators.short-circuit" }
+{ $subsection "combinators.smart" }
+"More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
+$nl
+"The " { $vocab-link "combinators" } " provides some less frequently-used features."
 $nl
 "A combinator which can help with implementing methods on " { $link hashcode* } ":"
 { $subsection recursive-hashcode }
 { $subsection "combinators-quot" }
-{ $see-also "quotations" "dataflow" } ;
+"Advanced topics:"
+{ $see-also "quotations" } ;
 
 ABOUT: "combinators"
 
+HELP: call-effect
+{ $values { "quot" quotation } { "effect" effect } }
+{ $description "Given a quotation and a stack effect, calls the quotation, asserting at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary quotation which is not required at compile time." } ;
+
+HELP: execute-effect
+{ $values { "word" word } { "effect" effect } }
+{ $description "Given a word and a stack effect, executes the word, asserting at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary word which is not required at compile time." } ;
+
+HELP: execute-effect-unsafe
+{ $values { "word" word } { "effect" effect } }
+{ $description "Given a word and a stack effect, executes the word, blindly declaring at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary word which is not required at compile time." }
+{ $warning "If the word being executed has an incorrect stack effect, undefined behavior will result. User code should use " { $link POSTPONE: execute( } " instead." } ;
+    
+{ call-effect call-effect-unsafe execute-effect execute-effect-unsafe } related-words
+
 HELP: cleave
 { $values { "x" object } { "seq" "a sequence of quotations with stack effect " { $snippet "( x -- ... )" } } }
 { $description "Applies each quotation to the object in turn." }
index 1ee3a4e3ed9c15b981625c2b9d4f6f391f4609e9..76f9f63c49be13be25f66bd60a7e08af227d05c4 100644 (file)
@@ -3,6 +3,38 @@ namespaces combinators words classes sequences accessors
 math.functions arrays ;
 IN: combinators.tests
 
+[ 3 ] [ 1 2 [ + ] call( x y -- z ) ] unit-test
+[ 1 2 [ + ] call( -- z ) ] must-fail
+[ 1 2 [ + ] call( x y -- z a ) ] must-fail
+[ 1 2 3 { 1 2 3 4 } ] [ 1 2 3 4 [ datastack nip ] call( x -- y ) ] unit-test
+[ [ + ] call( x y -- z ) ] must-infer
+
+[ 3 ] [ 1 2 \ + execute( x y -- z ) ] unit-test
+[ 1 2 \ + execute( -- z ) ] must-fail
+[ 1 2 \ + execute( x y -- z a ) ] must-fail
+[ \ + execute( x y -- z ) ] must-infer
+
+: compile-execute(-test-1 ( a b -- c ) \ + execute( a b -- c ) ;
+
+[ t ] [ \ compile-execute(-test-1 optimized>> ] unit-test
+[ 4 ] [ 1 3 compile-execute(-test-1 ] unit-test
+
+: compile-execute(-test-2 ( a b w -- c ) execute( a b -- c ) ;
+
+[ t ] [ \ compile-execute(-test-2 optimized>> ] unit-test
+[ 4 ] [ 1 3 \ + compile-execute(-test-2 ] unit-test
+[ 5 ] [ 1 4 \ + compile-execute(-test-2 ] unit-test
+[ -3 ] [ 1 4 \ - compile-execute(-test-2 ] unit-test
+[ 5 ] [ 1 4 \ + compile-execute(-test-2 ] unit-test
+
+: compile-call(-test-1 ( a b q -- c ) call( a b -- c ) ;
+
+[ t ] [ \ compile-call(-test-1 optimized>> ] unit-test
+[ 4 ] [ 1 3 [ + ] compile-call(-test-1 ] unit-test
+[ 7 ] [ 1 3 2 [ * + ] curry compile-call(-test-1 ] unit-test
+[ 7 ] [ 1 3 [ 2 * ] [ + ] compose compile-call(-test-1 ] unit-test
+[ 4 ] [ 1 3 [ { + } [ ] like call ] compile-call(-test-1 ] unit-test
+
 ! Compiled
 : cond-test-1 ( obj -- str )
     {
@@ -256,7 +288,7 @@ CONSTANT: case-const-2 2
     } case
 ] unit-test
 
-: do-not-call "do not call" throw ;
+: do-not-call ( -- * ) "do not call" throw ;
 
 : test-case-6 ( obj -- value )
     {
index daf247d678b438b9e0c24c54daace8d17a642451..4c600e06ca76bee4ed4c2e683e589c0176431489 100755 (executable)
@@ -1,10 +1,34 @@
-! Copyright (C) 2006, 2008 Slava Pestov.
+! Copyright (C) 2006, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays sequences sequences.private math.private
 kernel kernel.private math assocs quotations vectors
 hashtables sorting words sets math.order make ;
 IN: combinators
 
+<PRIVATE
+
+: call-effect-unsafe ( quot effect -- ) drop call ;
+
+: execute-effect-unsafe ( word effect -- ) drop execute ;
+
+M: object throw 5 getenv [ die ] or (( error -- * )) call-effect-unsafe ;
+
+PRIVATE>
+
+ERROR: wrong-values effect ;
+
+! We can't USE: effects here so we forward reference slots instead
+SLOT: in
+SLOT: out
+
+: call-effect ( quot effect -- )
+    [ [ datastack ] dip dip ] dip
+    [ in>> length ] [ out>> length ] [ ] tri [ check-datastack ] dip
+    [ wrong-values ] curry unless ;
+
+: execute-effect ( word effect -- )
+    [ [ execute ] curry ] dip call-effect ;
+
 ! cleave
 : cleave ( x seq -- )
     [ call ] with each ;
index 46d3dbc33f59220f1702a5e357c69320784b06e8..bf3b4a7171be5137fe819a3b2fd85c6fd4536d41 100644 (file)
@@ -17,7 +17,7 @@ $nl
 "Forward reference checking (see " { $link "definition-checking" } "):"
 { $subsection forward-reference? }
 "A hook to be called at the end of the compilation unit. If the optimizing compiler is loaded, this compiles new words with the " { $link "compiler" } ":"
-{ $subsection recompile-hook }
+{ $subsection recompile }
 "Low-level compiler interface exported by the Factor VM:"
 { $subsection modify-code-heap } ;
 
@@ -47,8 +47,9 @@ $nl
 $nl
 "Since compilation is relatively expensive, you should try to batch up as many definitions into one compilation unit as possible." } ;
 
-HELP: recompile-hook
-{ $var-description "Quotation with stack effect " { $snippet "( words -- )" } ", called at the end of " { $link with-compilation-unit } "." } ;
+HELP: recompile
+{ $values { "words" "a sequence of words" } { "alist" "an association list mapping words to compiled definitions" } }
+{ $contract "Internal word which compiles words. Called at the end of " { $link with-compilation-unit } "." } ;
 
 HELP: no-compilation-unit
 { $values { "word" word } }
index 5eafcef94e2168ac2fd0a2bfb85de6fdad6b6e1c..d84b377f361d92256d69b0bcc455f08dfeaf5f20 100644 (file)
@@ -2,6 +2,9 @@ IN: compiler.units.tests
 USING: definitions compiler.units tools.test arrays sequences words kernel
 accessors namespaces fry ;
 
+[ [ [ ] define-temp ] with-compilation-unit ] must-infer
+[ [ [ ] define-temp ] with-nested-compilation-unit ] must-infer
+
 [ flushed-dependency ] [ f flushed-dependency strongest-dependency ] unit-test
 [ flushed-dependency ] [ flushed-dependency f strongest-dependency ] unit-test
 [ inlined-dependency ] [ flushed-dependency inlined-dependency strongest-dependency ] unit-test
index 178e29fd9317958407d66a3f3041ab27aa4a5dcf..afa05f94426e20657ff84a932902518a27e08e22 100644 (file)
@@ -1,8 +1,9 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel continuations assocs namespaces
 sequences words vocabs definitions hashtables init sets
-math math.order classes classes.algebra ;
+math math.order classes classes.algebra classes.tuple
+classes.tuple.private generic ;
 IN: compiler.units
 
 SYMBOL: old-definitions
@@ -35,7 +36,18 @@ TUPLE: redefine-error def ;
     [ new-definitions get assoc-stack not ]
     [ drop f ] if ;
 
-SYMBOL: recompile-hook
+SYMBOL: compiler-impl
+
+HOOK: recompile compiler-impl ( words -- alist )
+
+! Non-optimizing compiler
+M: f recompile [ f ] { } map>assoc ;
+
+! Trivial compiler. We don't want to touch the code heap
+! during stage1 bootstrap, it would just waste time.
+SINGLETON: dummy-compiler
+
+M: dummy-compiler recompile drop { } ;
 
 : <definitions> ( -- pair ) { H{ } H{ } } [ clone ] map ;
 
@@ -68,12 +80,7 @@ GENERIC: definitions-changed ( assoc obj -- )
     dup changed-definitions get update
     dup dup changed-vocabs update ;
 
-: compile ( words -- )
-    recompile-hook get call modify-code-heap ;
-
-SYMBOL: outdated-tuples
-SYMBOL: update-tuples-hook
-SYMBOL: remake-generics-hook
+: compile ( words -- ) recompile modify-code-heap ;
 
 : index>= ( obj1 obj2 seq -- ? )
     [ index ] curry bi@ >= ;
@@ -125,24 +132,15 @@ SYMBOL: remake-generics-hook
     changed-generics get compiled-generic-usages
     append assoc-combine keys ;
 
-: call-recompile-hook ( -- )
-    to-recompile recompile-hook get call ;
-
-: call-remake-generics-hook ( -- )
-    remake-generics-hook get call ;
-
-: call-update-tuples-hook ( -- )
-    update-tuples-hook get call ;
-
 : unxref-forgotten-definitions ( -- )
     forgotten-definitions get
     keys [ word? ] filter
     [ delete-compiled-xref ] each ;
 
 : finish-compilation-unit ( -- )
-    call-remake-generics-hook
-    call-recompile-hook
-    call-update-tuples-hook
+    remake-generics
+    to-recompile recompile
+    update-tuples
     unxref-forgotten-definitions
     modify-code-heap ;
 
@@ -150,7 +148,8 @@ SYMBOL: remake-generics-hook
     [
         H{ } clone changed-definitions set
         H{ } clone changed-generics set
-        H{ } clone remake-generics set
+        H{ } clone changed-effects set
+        H{ } clone outdated-generics set
         H{ } clone outdated-tuples set
         H{ } clone new-classes set
         [ finish-compilation-unit ] [ ] cleanup
@@ -160,7 +159,8 @@ SYMBOL: remake-generics-hook
     [
         H{ } clone changed-definitions set
         H{ } clone changed-generics set
-        H{ } clone remake-generics set
+        H{ } clone changed-effects set
+        H{ } clone outdated-generics set
         H{ } clone forgotten-definitions set
         H{ } clone outdated-tuples set
         H{ } clone new-classes set
@@ -172,8 +172,3 @@ SYMBOL: remake-generics-hook
             notify-definition-observers
         ] [ ] cleanup
     ] with-scope ; inline
-
-: default-recompile-hook ( words -- alist )
-    [ f ] { } map>assoc ;
-
-recompile-hook [ [ default-recompile-hook ] ] initialize
index 0d66829898dc2f3762b3aa32b9d8cff712ac5380..0627ed5265dc78ebc614d872170f35e7adb74827 100644 (file)
@@ -83,7 +83,6 @@ $nl
 { $subsection with-return }
 "Reflecting the datastack:"
 { $subsection with-datastack }
-{ $subsection assert-depth }
 "Continuations serve as the building block for a number of higher-level abstractions, such as " { $link "errors" } " and " { $link "threads" } "."
 { $subsection "continuations.private" } ;
 
@@ -217,10 +216,6 @@ HELP: with-datastack
     { $example "USING: continuations math prettyprint ;" "{ 3 7 } [ + ] with-datastack ." "{ 10 }" }
 } ;
 
-HELP: assert-depth
-{ $values { "quot" "a quotation" } }
-{ $description "Runs a quotation. Throws an error if the quotation attempts to take input values from the stack, or leave outputs on the stack." } ;
-
 HELP: attempt-all
 { $values
      { "seq" sequence } { "quot" quotation }
index d5bd0da663b5b2e581657f0e632c914f5413583b..34a4ed28794c7b5d32f41902a0c0b74955c43cc9 100644 (file)
@@ -3,7 +3,7 @@ continuations debugger parser memory arrays words
 kernel.private accessors eval ;
 IN: continuations.tests
 
-: (callcc1-test)
+: (callcc1-test) ( -- )
     [ 1- dup ] dip ?push
     over 0 = [ "test-cc" get continue-with ] when
     (callcc1-test) ;
@@ -59,10 +59,10 @@ IN: continuations.tests
 ! : callstack-overflow callstack-overflow f ;
 ! [ callstack-overflow ] must-fail
 
-: don't-compile-me { } [ ] each ;
+: don't-compile-me ( -- ) { } [ ] each ;
 
-: foo callstack "c" set 3 don't-compile-me ;
-: bar 1 foo 2 ;
+: foo ( -- ) callstack "c" set 3 don't-compile-me ;
+: bar ( -- a b ) 1 foo 2 ;
 
 [ 1 3 2 ] [ bar ] unit-test
 
index 37418b85f5adc672319e45338a94d380e8f6991b..051d28d8c23eeca8a60a31c5343c60e641927987 100644 (file)
@@ -1,8 +1,8 @@
-! Copyright (C) 2003, 2008 Slava Pestov.
+! Copyright (C) 2003, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays vectors kernel kernel.private sequences
 namespaces make math splitting sorting quotations assocs
-combinators accessors ;
+combinators combinators.private accessors ;
 IN: continuations
 
 SYMBOL: error
@@ -73,7 +73,7 @@ C: <continuation> continuation
 
 <PRIVATE
 
-: (continue) ( continuation -- )
+: (continue) ( continuation -- )
     >continuation<
     set-catchstack
     set-namestack
@@ -81,19 +81,18 @@ C: <continuation> continuation
     [ set-datastack ] dip
     set-callstack ;
 
-: (continue-with) ( obj continuation -- )
-    swap 4 setenv
-    >continuation<
-    set-catchstack
-    set-namestack
-    set-retainstack
-    [ set-datastack drop 4 getenv f 4 setenv f ] dip
-    set-callstack ;
-
 PRIVATE>
 
 : continue-with ( obj continuation -- * )
-    [ (continue-with) ] 2 (throw) ;
+    [
+        swap 4 setenv
+        >continuation<
+        set-catchstack
+        set-namestack
+        set-retainstack
+        [ set-datastack drop 4 getenv f 4 setenv f ] dip
+        set-callstack
+    ] (( obj continuation -- * )) call-effect-unsafe ;
 
 : continue ( continuation -- * )
     f swap continue-with ;
@@ -111,12 +110,9 @@ SYMBOL: return-continuation
         [
             [ [ { } like set-datastack ] dip call datastack ] dip
             continue-with
-        ] 3 (throw)
+        ] (( stack quot continuation -- * )) call-effect-unsafe
     ] callcc1 2nip ;
 
-: assert-depth ( quot -- )
-    { } swap with-datastack { } assert= ; inline
-
 GENERIC: compute-restarts ( error -- seq )
 
 <PRIVATE
@@ -133,7 +129,7 @@ SYMBOL: thread-error-hook
     dup save-error
     catchstack* empty? [
         thread-error-hook get-global
-        [ 1 (throw) ] [ die ] if*
+        [ (( error -- * )) call-effect-unsafe ] [ die ] if*
     ] when
     c> continue-with ;
 
index 80da7daa31216b79162b4d4546b1270f90e18440..9d49cf62c64231379d7e99762675b9c92bfa7d0a 100644 (file)
@@ -13,9 +13,9 @@ $nl
 "Definitions can answer a sequence of definitions they directly depend on:"
 { $subsection uses }
 "Definitions must implement a few operations used for printing them in source form:"
-{ $subsection synopsis* }
 { $subsection definer }
-{ $subsection definition } ;
+{ $subsection definition }
+{ $see-also "see" } ;
 
 ARTICLE: "definition-crossref" "Definition cross referencing"
 "A common cross-referencing system is used to track definition usages:"
@@ -56,11 +56,24 @@ $nl
 { $subsection redefine-error } ;
 
 ARTICLE: "definitions" "Definitions"
-"A " { $emphasis "definition" } " is an artifact read from a source file. This includes words, methods, help articles, and path names (which represent the source file at that location). Words for working with definitions are found in the " { $vocab-link "definitions" } " vocabulary."
+"A " { $emphasis "definition" } " is an artifact read from a source file. Words for working with definitions are found in the " { $vocab-link "definitions" } " vocabulary."
+$nl
+"Definitions are defined using parsing words. Examples of definitions together with their defining parsing words are words (" { $link POSTPONE: : } "), methods (" { $link POSTPONE: M: } "), and vocabularies (" { $link POSTPONE: IN: } ")."
+$nl
+"All definitions share some common traits:"
+{ $list
+  "There is a word to list all definitions of a given type"
+  "There is a parsing word for creating new definitions"
+  "There is an ordinary word which is the runtime equivalent of the parsing word, for introspection"
+  "Instances of the definition may be introspected and modified with the definition protocol"
+}
+"For every source file loaded into the system, a list of definitions is maintained. Pathname objects implement the definition protocol, acting over the definitions their source files contain. See " { $link "source-files" } " for details."
 { $subsection "definition-protocol" }
 { $subsection "definition-crossref" }
 { $subsection "definition-checking" }
 { $subsection "compilation-units" }
+"A parsing word to remove definitions:"
+{ $subsection POSTPONE: FORGET: }
 { $see-also "see" "parser" "source-files" "words" "generic" "help-impl" } ;
 
 ABOUT: "definitions"
index b2d265a2e3cf3a43032f048171b36086109f8f5a..558b25910343dc4025009e6e19203dde138adb3e 100644 (file)
@@ -20,14 +20,11 @@ TUPLE: some-class ;
 
 M: some-class some-generic ;
 
-TUPLE: another-class some-generic ;
-
 [ ] [
     [
-        {
-            some-generic
-            some-class
-            { another-class some-generic }
-        } forget-all
+        \ some-generic
+        \ some-class
+        2array
+        forget-all
     ] with-compilation-unit
 ] unit-test
index db99d7e3a3f17911105cf89da35cb050671bb39c..7463a863e5b466201ee47163c95db9c10ef4f607 100644 (file)
@@ -1,13 +1,13 @@
-! Copyright (C) 2006, 2008 Slava Pestov.
+! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-IN: definitions
 USING: kernel sequences namespaces assocs graphs math math.order ;
+IN: definitions
+
+MIXIN: definition
 
 ERROR: no-compilation-unit definition ;
 
-SYMBOL: inlined-dependency
-SYMBOL: flushed-dependency
-SYMBOL: called-dependency
+SYMBOLS: inlined-dependency flushed-dependency called-dependency ;
 
 : set-in-unit ( value key assoc -- )
     [ set-at ] [ no-compilation-unit ] if* ;
@@ -17,9 +17,14 @@ SYMBOL: changed-definitions
 : changed-definition ( defspec -- )
     inlined-dependency swap changed-definitions get set-in-unit ;
 
+SYMBOL: changed-effects
+
+: changed-effect ( word -- )
+    dup changed-effects get set-in-unit ;
+
 SYMBOL: changed-generics
 
-SYMBOL: remake-generics
+SYMBOL: outdated-generics
 
 SYMBOL: new-classes
 
@@ -37,7 +42,7 @@ GENERIC: set-where ( loc defspec -- )
 
 GENERIC: forget* ( defspec -- )
 
-M: object forget* drop ;
+M: f forget* drop ;
 
 SYMBOL: forgotten-definitions
 
@@ -48,8 +53,6 @@ SYMBOL: forgotten-definitions
 
 : forget-all ( definitions -- ) [ forget ] each ;
 
-GENERIC: synopsis* ( defspec -- )
-
 GENERIC: definer ( defspec -- start end )
 
 GENERIC: definition ( defspec -- seq )
index e09a88aee4ba7acef0643b612f5fd1b45158597e..f9d0770d0238f4605b0b93786e8260add302db95 100644 (file)
@@ -21,7 +21,7 @@ T{ dispose-dummy } "b" set
 
 TUPLE: dummy-obj destroyed? ;
 
-: <dummy-obj> dummy-obj new ;
+: <dummy-obj> ( -- obj ) dummy-obj new ;
 
 TUPLE: dummy-destructor obj ;
 
@@ -30,10 +30,10 @@ C: <dummy-destructor> dummy-destructor
 M: dummy-destructor dispose ( obj -- )
     obj>> t >>destroyed? drop ;
 
-: destroy-always
+: destroy-always ( obj -- )
     <dummy-destructor> &dispose drop ;
 
-: destroy-later
+: destroy-later ( obj -- )
     <dummy-destructor> |dispose drop ;
 
 [ t ] [
index b209dcf259eaf149b1a1bcc52074200cdbb48842..20709ca8075fa5cc1b711fe9e201423d8757e594 100644 (file)
@@ -1,4 +1,4 @@
-USING: help.markup help.syntax math strings words kernel ;
+USING: help.markup help.syntax math strings words kernel combinators ;
 IN: effects
 
 ARTICLE: "effect-declaration" "Stack effect declaration"
@@ -29,14 +29,11 @@ $nl
 "The stack effect inferencer verifies stack effect comments to ensure the correct number of inputs and outputs is listed. Value names are ignored; only their number matters. An error is thrown if a word's declared stack effect does not match its inferred stack effect. See " { $link "inference" } "." ;
 
 ARTICLE: "effects" "Stack effects"
-"A " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that an operation takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output."
+"A " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that an operation takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output. Stack effects are first-class, and words for working with them are found in the " { $vocab-link "effects" } " vocabulary."
 $nl
-"Stack effects of words can be declared."
+"Stack effects of words must be declared, and the " { $link "compiler" } " checks that these declarations are correct. Invalid declarations are reported as " { $link "compiler-errors" } ". The " { $link "inference" } " tool can be used to check stack effects interactively."
 { $subsection "effect-declaration" }
-"Stack effects are first-class, and words for working with them are found in the " { $vocab-link "effects" } " vocabulary."
-{ $subsection effect }
-{ $subsection effect? }
-"There is a literal syntax for stack objects. It is most often used with " { $link define-declared } "."
+"There is a literal syntax for stack objects. It is most often used with " { $link define-declared } ", " { $link call-effect } " and " { $link execute-effect } "."
 { $subsection POSTPONE: (( }
 "Getting a word's declared stack effect:"
 { $subsection stack-effect }
@@ -45,7 +42,9 @@ $nl
 "Comparing effects:"
 { $subsection effect-height }
 { $subsection effect<= }
-{ $see-also "inference" } ;
+"The class of stack effects:"
+{ $subsection effect }
+{ $subsection effect? } ;
 
 ABOUT: "effects"
 
index d21132aebb7b9e37c7dcb5f84f535792fba000dd..142b9120a8d5c3692846013348dac3641b6c7904 100644 (file)
@@ -63,3 +63,6 @@ M: effect clone
 
 : shuffle ( stack shuffle -- newstack )
     shuffle-mapping swap nths ;
+
+: add-effect-input ( effect -- effect' )
+    [ in>> "obj" suffix ] [ out>> ] [ terminated?>> ] tri effect boa ;
index a009db76b1245e3186265d57db274dd3d96f4f3b..c8ed6da2aa3ce77cbcc906e255f1a7baec8e404c 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: lexer sets sequences kernel splitting effects
-combinators arrays parser ;
+combinators arrays ;
 IN: effects.parser
 
 DEFER: parse-effect
@@ -12,9 +12,10 @@ ERROR: bad-effect ;
     scan [ nip ] [ = ] 2bi [ drop f ] [
         dup { f "(" "((" } member? [ bad-effect ] [
             ":" ?tail [
-                scan-word {
-                    { \ ( [ ")" parse-effect ] }
-                    [ ]
+                scan {
+                    { "(" [ ")" parse-effect ] }
+                    { f [ ")" unexpected-eof ] }
+                    [ bad-effect ]
                 } case 2array
             ] when
         ] if
@@ -26,3 +27,9 @@ ERROR: bad-effect ;
 : parse-effect ( end -- effect )
     parse-effect-tokens { "--" } split1 dup
     [ <effect> ] [ "Stack effect declaration must contain --" throw ] if ;
+
+: complete-effect ( -- effect )
+    "(" expect ")" parse-effect ;
+
+: parse-call( ( accum word -- accum )
+    [ ")" parse-effect ] dip 2array over push-all ;
index 613dbf72a4a191ae420d528974e936514c96d059..7017ef8a087928d93bb777d7cb38170050696a63 100644 (file)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax words classes classes.algebra
 definitions kernel alien sequences math quotations
-generic.standard generic.math combinators prettyprint ;
+generic.standard generic.math combinators prettyprint effects ;
 IN: generic
 
 ARTICLE: "method-order" "Method precedence"
@@ -45,8 +45,8 @@ $nl
 { $subsection make-generic }
 "Low-level method constructor:"
 { $subsection <method> }
-"A " { $emphasis "method specifier" } " refers to a method and implements the " { $link "definition-protocol" } ":"
-{ $subsection method-spec }
+"Methods may be pushed on the stack with a literal syntax:"
+{ $subsection POSTPONE: M\ }
 { $see-also "see" } ;
 
 ARTICLE: "method-combination" "Custom method combination"
@@ -62,7 +62,7 @@ ARTICLE: "method-combination" "Custom method combination"
     { { $link POSTPONE: HOOK: } { $link hook-combination } }
     { { $link POSTPONE: MATH: } { $link math-combination } }
 }
-"Developing a custom method combination requires that a parsing word calling " { $link define-generic } " be defined; additionally, it is a good idea to implement the definition protocol words " { $link definer } " and " { $link synopsis* } " on the class of words having this method combination, to properly support developer tools."
+"Developing a custom method combination requires that a parsing word calling " { $link define-generic } " be defined; additionally, it is a good idea to implement the " { $link "definition-protocol" } " on the class of words having this method combination, to properly support developer tools."
 $nl
 "The combination quotation passed to " { $link define-generic } " has stack effect " { $snippet "( word -- quot )" } ". It's job is to call various introspection words, including at least obtaining the set of methods defined on the generic word, then combining these methods in some way to produce a quotation."
 { $see-also "generic-introspection" } ;
@@ -98,8 +98,8 @@ $nl
 "Generic words must declare their stack effect in order to compile. See " { $link "effect-declaration" } "."
 { $subsection "method-order" }
 { $subsection "call-next-method" }
-{ $subsection "generic-introspection" }
 { $subsection "method-combination" }
+{ $subsection "generic-introspection" }
 "Generic words specialize behavior based on the class of an object; sometimes behavior needs to be specialized on the object's " { $emphasis "structure" } "; this is known as " { $emphasis "pattern matching" } " and is implemented in the " { $vocab-link "match" } " vocabulary." ;
 
 ABOUT: "generic"
@@ -115,13 +115,14 @@ HELP: make-generic
 $low-level-note ;
 
 HELP: define-generic
-{ $values { "word" word } { "combination" "a method combination" } }
+{ $values { "word" word } { "effect" effect } { "combination" "a method combination" } }
 { $description "Defines a generic word. A method combination is an object which responds to the " { $link perform-combination } " generic word." }
 { $contract "The method combination quotation is called each time the generic word has to be updated (for example, when a method is added), and thus must be side-effect free." } ;
 
-HELP: method-spec
-{ $class-description "The class of method specifiers, which are two-element arrays consisting of a class word followed by a generic word." }
-{ $examples { $code "{ fixnum + }" "{ editor draw-gadget* }" } } ;
+HELP: M\
+{ $syntax "M\\ class generic" }
+{ $class-description "Pushes a method on the stack." }
+{ $examples { $code "M\\ fixnum + see" } { $code "USING: ui.gadgets ui.gadgets.editors ;" "M\\ editor draw-gadget* edit" } } ;
 
 HELP: method-body
 { $class-description "The class of method bodies, which are words with special word properties set." } ;
index 5465ee1b27c5341a0bada1142892eaa34c477b0e..f28332353e66de182023887fcf5920d327e58919 100755 (executable)
@@ -2,7 +2,8 @@ USING: accessors alien arrays definitions generic generic.standard
 generic.math assocs hashtables io kernel math namespaces parser
 prettyprint sequences strings tools.test vectors words
 quotations classes classes.algebra classes.tuple continuations
-layouts classes.union sorting compiler.units eval multiline ;
+layouts classes.union sorting compiler.units eval multiline
+io.streams.string ;
 IN: generic.tests
 
 GENERIC: foobar ( x -- y )
@@ -104,9 +105,6 @@ M: shit big-generic-test "shit" ;
 [ float ] [ \ real \ float math-class-max ] unit-test
 [ fixnum ] [ \ fixnum \ null math-class-max ] unit-test
 
-[ t ] [ { hashtable equal? } method-spec? ] unit-test
-[ f ] [ { word = } method-spec? ] unit-test
-
 ! Regression
 TUPLE: first-one ;
 TUPLE: second-one ;
@@ -163,7 +161,7 @@ M: sequence generic-forget-test-2 = ;
 ] unit-test
 
 [ ] [
-    [ { sequence generic-forget-test-2 } forget ] with-compilation-unit
+    [ M\ sequence generic-forget-test-2 forget ] with-compilation-unit
 ] unit-test
 
 [ f ] [
@@ -185,7 +183,7 @@ M: f generic-forget-test-3 ;
 
 [ f ] [ f generic-forget-test-3 ] unit-test
 
-: a-word ;
+: a-word ( -- ) ;
 
 GENERIC: a-generic ( a -- b )
 
@@ -195,7 +193,7 @@ M: integer a-generic a-word ;
 
 [ t ] [ "m" get \ a-word usage memq? ] unit-test
 
-[ ] [ "IN: generic.tests : a-generic ;" eval ] unit-test
+[ ] [ "IN: generic.tests : a-generic ( -- ) ;" eval ] unit-test
 
 [ f ] [ "m" get \ a-word usage memq? ] unit-test
 
@@ -233,6 +231,17 @@ M: number c-n-m-cache ;
 
 [ 3 ] [ 2 c-n-m-cache ] unit-test
 
-[ ] [ [ { integer c-n-m-cache } forget ] with-compilation-unit ] unit-test
+[ ] [ [ M\ integer c-n-m-cache forget ] with-compilation-unit ] unit-test
 
 [ 2 ] [ 2 c-n-m-cache ] unit-test
+
+! Moving a method from one vocab to another doesn't always work
+GENERIC: move-method-generic ( a -- b )
+
+[ ] [ "IN: generic.tests.a USE: strings USE: generic.tests M: string move-method-generic ;" <string-reader> "move-method-test-1" parse-stream drop ] unit-test
+
+[ ] [ "IN: generic.tests.b USE: strings USE: generic.tests M: string move-method-generic ;" <string-reader> "move-method-test-2" parse-stream drop ] unit-test
+
+[ ] [ "IN: generic.tests.a" <string-reader> "move-method-test-1" parse-stream drop ] unit-test
+
+[ { string } ] [ \ move-method-generic order ] unit-test
\ No newline at end of file
index 351a8f98fd5fc5b35b886ad58489f13646e3d5d6..65a802dc2dd3c968a85e96fe66292abee698848a 100644 (file)
@@ -1,9 +1,9 @@
-! Copyright (C) 2006, 2008 Slava Pestov.
+! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors words kernel sequences namespaces make assocs
 hashtables definitions kernel.private classes classes.private
 classes.algebra quotations arrays vocabs effects combinators
-sets compiler.units ;
+sets ;
 IN: generic
 
 ! Method combination protocol
@@ -21,17 +21,9 @@ M: generic definition drop f ;
     [ dup "combination" word-prop perform-combination ]
     bi ;
 
-[
-    remake-generics get keys
-    [ generic? ] filter [ make-generic ] each
-] remake-generics-hook set-global
-
 : method ( class generic -- method/f )
     "methods" word-prop at ;
 
-PREDICATE: method-spec < pair
-    first2 generic? swap class? and ;
-
 : order ( generic -- seq )
     "methods" word-prop keys sort-classes ;
 
@@ -76,7 +68,10 @@ TUPLE: check-method class generic ;
     [ [ [ class-or ] when* ] change-at ] [ no-compilation-unit ] if* ;
 
 : remake-generic ( generic -- )
-    dup remake-generics get set-in-unit ;
+    dup outdated-generics get set-in-unit ;
+
+: remake-generics ( -- )
+    outdated-generics get keys [ generic? ] filter [ make-generic ] each ;
 
 : with-methods ( class generic quot -- )
     [ drop changed-generic ]
@@ -90,9 +85,6 @@ TUPLE: check-method class generic ;
 PREDICATE: method-body < word
     "method-generic" word-prop >boolean ;
 
-M: method-spec stack-effect
-    first2 method stack-effect ;
-
 M: method-body stack-effect
     "method-generic" word-prop stack-effect ;
 
@@ -139,24 +131,6 @@ M: default-method irrelevant? drop t ;
     dupd <default-method> "default-method" set-word-prop ;
 
 ! Definition protocol
-M: method-spec where
-    dup first2 method [ ] [ second ] ?if where ;
-
-M: method-spec set-where
-    first2 method set-where ;
-
-M: method-spec definer
-    first2 method definer ;
-
-M: method-spec definition
-    first2 method definition ;
-
-M: method-spec forget*
-    first2 method [ forgotten-definition ] [ forget* ] bi ;
-
-M: method-spec smart-usage
-    second smart-usage ;
-
 M: method-body definer
     drop \ M: \ ; ;
 
@@ -187,13 +161,21 @@ M: sequence update-methods ( class seq -- )
         [ changed-generic ] [ remake-generic drop ] 2bi
     ] with each ;
 
-: define-generic ( word combination -- )
-    over "combination" word-prop over = [ drop ] [
-        2dup "combination" set-word-prop
-        over "methods" word-prop values forget-all
-        over H{ } clone "methods" set-word-prop
-        dupd define-default-method
-    ] if remake-generic ;
+: define-generic ( word combination effect -- )
+    [ nip swap set-stack-effect ]
+    [
+        drop
+        2dup [ "combination" word-prop ] dip = [ 2drop ] [
+            {
+                [ "combination" set-word-prop ]
+                [ drop "methods" word-prop values forget-all ]
+                [ drop H{ } clone "methods" set-word-prop ]
+                [ define-default-method ]
+            }
+            2cleave
+        ] if
+    ]
+    [ 2drop remake-generic ] 3tri ;
 
 M: generic subwords
     [
@@ -206,5 +188,8 @@ M: generic subwords
 M: generic forget*
     [ subwords forget-all ] [ call-next-method ] bi ;
 
+M: class forget-methods
+    [ implementors ] [ [ swap method ] curry ] bi map forget-all ;
+
 : xref-generics ( -- )
     all-words [ subwords [ xref ] each ] each ;
index 4323f91bc3dfe46659c3b6d8058af21b9c8f065c..60fa7453394f53b43a00e0f2ab7a8eae796d9295 100644 (file)
@@ -15,7 +15,7 @@ HELP: no-math-method
 HELP: math-method
 { $values { "word" generic } { "class1" class } { "class2" class } { "quot" quotation } }
 { $description "Generates a definition for " { $snippet "word" } " when the two inputs are instances of " { $snippet "class1" } " and " { $snippet "class2" } ", respectively." }
-{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip float=>+ ]" } } ;
+{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip M\\ float + ]" } } ;
 
 HELP: math-class
 { $class-description "The class of subtypes of " { $link number } " which are not " { $link null } "." } ;
index 738c011a48586225161e8de283fb725a885cd41c..8d4610dabed96986dd781ea81fbd507431b752a5 100644 (file)
@@ -72,7 +72,7 @@ SYMBOL: picker
         \ dispatch ,
     ] [ ] make ; inline
 
-TUPLE: math-combination ;
+SINGLETON: math-combination
 
 M: math-combination make-default-method
     drop default-math-method ;
index 0852459c34101c26cf1f891af5b9e49a64cd4f16..ce048c41dafd8fa45c87375ec956eb5613221f49 100644 (file)
@@ -1,12 +1,15 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser kernel words generic namespaces ;
+USING: parser kernel words generic namespaces effects.parser ;
 IN: generic.parser
 
 ERROR: not-in-a-method-error ;
 
 : CREATE-GENERIC ( -- word ) CREATE dup reset-word ;
 
+: (GENERIC:) ( quot -- )
+    [ CREATE-GENERIC ] dip call complete-effect define-generic ; inline
+
 : create-method-in ( class generic -- method )
     create-method dup set-word dup save-location ;
 
@@ -18,6 +21,6 @@ SYMBOL: current-method
 : with-method-definition ( method quot -- )
     over current-method set call current-method off ; inline
 
-: (M:) ( method def -- )
+: (M:) ( -- method def )
     CREATE-METHOD [ parse-definition ] with-method-definition ;
 
index ec2e78c48d17c8bf33f9cd64342ff7e2137f025e..6e788eb947e26984a203189a3d1a8e0dc21e4ea7 100644 (file)
@@ -1,5 +1,5 @@
 USING: generic help.markup help.syntax sequences math
-math.parser ;
+math.parser effects ;
 IN: generic.standard
 
 HELP: no-method
@@ -28,7 +28,7 @@ HELP: hook-combination
 } ;
 
 HELP: define-simple-generic
-{ $values { "word" "a word" } }
+{ $values { "word" "a word" } { "effect" effect } }
 { $description "Defines a generic word with the " { $link standard-combination } " method combination and a dispatch position of 0." } ;
 
 { standard-combination hook-combination } related-words
index 2cd64ac9f4f7b06c06408c057fd83db4f7472a7d..a6269135f4193db65ebe15788d2ecdef1f1c6a46 100644 (file)
@@ -280,16 +280,6 @@ M: growable call-next-hooker call-next-method "growable " prepend ;
     V{ } my-var [ call-next-hooker ] with-variable
 ] unit-test
 
-GENERIC: no-stack-effect-decl
-
-M: hashtable no-stack-effect-decl ;
-M: vector no-stack-effect-decl ;
-M: sbuf no-stack-effect-decl ;
-
-[ ] [ \ no-stack-effect-decl see ] unit-test
-
-[ ] [ \ no-stack-effect-decl def>> . ] unit-test
-
 ! Cross-referencing with generic words
 TUPLE: xref-tuple-1 ;
 TUPLE: xref-tuple-2 < xref-tuple-1 ;
index f9fe3a6e9e347a8473e252746fee2dd9dd65b0e0..5dbc0d17a1284993180d83bde72b4f7193369550 100644 (file)
@@ -24,7 +24,7 @@ M: quotation engine>quot
 ERROR: no-method object generic ;
 
 : error-method ( word -- quot )
-    picker swap [ no-method ] curry append ;
+    [ picker ] dip [ no-method ] curry append ;
 
 : push-method ( method specializer atomic assoc -- )
     [
@@ -56,7 +56,7 @@ ERROR: no-method object generic ;
 
 : find-default ( methods -- quot )
     #! Side-effects methods.
-    object bootstrap-word swap delete-at* [
+    [ object bootstrap-word ] dip delete-at* [
         drop generic get "default-method" word-prop mangle-method
     ] unless ;
 
@@ -104,8 +104,10 @@ PREDICATE: standard-generic < generic
 PREDICATE: simple-generic < standard-generic
     "combination" word-prop #>> zero? ;
 
-: define-simple-generic ( word -- )
-    T{ standard-combination f 0 } define-generic ;
+CONSTANT: simple-combination T{ standard-combination f 0 }
+
+: define-simple-generic ( word effect -- )
+    [ simple-combination ] dip define-generic ;
 
 : with-standard ( combination quot -- quot' )
     [ #>> (dispatch#) ] dip with-variable ; inline
index 8aa13a5f5eeb09c2f150aadbef0f630f440db4d3..f95a7a7e67014796ab4122aa7e251775c87acad0 100644 (file)
@@ -79,7 +79,7 @@ TUPLE: hashtable
 : grow-hash ( hash -- )
     [ [ >alist ] [ assoc-size 1+ ] bi ] keep
     [ reset-hash ] keep
-    swap (rehash) ; inline
+    swap (rehash) ;
 
 : ?grow-hash ( hash -- )
     dup hash-large? [
@@ -95,7 +95,7 @@ TUPLE: hashtable
 PRIVATE>
 
 : <hashtable> ( n -- hash )
-    hashtable new [ reset-hash ] keep ;
+    hashtable new [ reset-hash ] keep ; inline
 
 M: hashtable at* ( key hash -- value ? )
     key@ [ 3 fixnum+fast slot t ] [ 2drop f f ] if ;
index 953340b985a5c064ece12fbc4516ba5e7b50e22d..5d8e88b85f5b2ee4a78109e618f868d8773cf913 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: continuations continuations.private kernel
 kernel.private sequences assocs namespaces namespaces.private ;
@@ -9,10 +9,10 @@ SYMBOL: init-hooks
 init-hooks global [ drop V{ } clone ] cache drop
 
 : do-init-hooks ( -- )
-    init-hooks get [ nip call ] assoc-each ;
+    init-hooks get [ nip call( -- ) ] assoc-each ;
 
 : add-init-hook ( quot name -- )
-    dup init-hooks get at [ over call ] unless
+    dup init-hooks get at [ over call( -- ) ] unless
     init-hooks get set-at ;
 
 : boot ( -- ) init-namespaces init-catchstack init-error-handler ;
index 2f0bb1063f80d4d7b46c7dcfc7efc17a1fe8e49c..4c91a519c6c93624710e77ec3991a0baf8d4118f 100644 (file)
@@ -39,7 +39,7 @@ M: object normalize-directory normalize-path ;
 
 : set-io-backend ( io-backend -- )
     io-backend set-global init-io init-stdio
-    "io.files" init-hooks get at call ;
+    "io.files" init-hooks get at call( -- ) ;
 
 ! Note that we have 'alien' in our using list so that the alien
 ! init hook runs before this one.
index e13e05bf403a4e312ed70dc94648b6072c62fa47..d0f968a791d528a41f8ed5f4e017eef6a0329354 100644 (file)
@@ -80,12 +80,12 @@ ARTICLE: "encodings-descriptors" "Encoding descriptors"
 "An encoding descriptor is something which can be used with binary input or output streams to encode or decode bytes stored in a certain representation. It must conform to the " { $link "encodings-protocol" } ". Encodings which you can use are defined in the following vocabularies:"
 { $subsection "io.encodings.binary" }
 { $subsection "io.encodings.utf8" }
-{ $subsection "io.encodings.utf16" }
+{ $vocab-subsection "UTF-16 encoding" "io.encodings.utf16" }
 { $vocab-subsection "UTF-32 encoding" "io.encodings.utf32" }
 { $vocab-subsection "Strict encodings" "io.encodings.strict" }
 "Legacy encodings:"
 { $vocab-subsection "8-bit encodings" "io.encodings.8-bit" }
-{ $vocab-subsection "ASCII" "io.encodings.ascii" }
+{ $vocab-subsection "ASCII encoding" "io.encodings.ascii" }
 { $see-also "encodings-introduction" } ;
 
 ARTICLE: "encodings-protocol" "Encoding protocol"
@@ -124,6 +124,6 @@ ARTICLE: "io.encodings" "I/O encodings"
 "Combinators to change the encoding:"
 { $subsection with-encoded-output }
 { $subsection with-decoded-input }
-{ $see-also "encodings-introduction" "stream-elements" } ;
+{ $see-also "encodings-introduction" } ;
 
 ABOUT: "io.encodings"
index d8ad1274f219bd909355d6663df407ac2d83bf43..696de9af69678932e58daa531fddd2b54bf8f7df 100644 (file)
@@ -47,6 +47,9 @@ M: object <decoder> f decoder boa ;
         ] when
     ] when nip ; inline
 
+M: decoder stream-element-type
+    drop +character+ ;
+
 M: decoder stream-read1
     dup >decoder< decode-char fix-read1 ;
 
@@ -121,6 +124,9 @@ M: object <encoder> encoder boa ;
 : >encoder< ( encoder -- stream encoding )
     [ stream>> ] [ code>> ] bi ; inline
 
+M: encoder stream-element-type
+    drop +character+ ;
+
 M: encoder stream-write1
     >encoder< encode-char ;
 
index e30e9be0d0e9c0d2f36ab53d60bc4a4310ae1bfb..6cd3ee803305efbb5aa9c2759b0ef1ab9c460c19 100755 (executable)
@@ -1,5 +1,5 @@
 USING: io.encodings.utf8 tools.test io.encodings.string strings arrays
-bootstrap.unicode ;
+bootstrap.unicode kernel sequences ;
 IN: io.encodings.utf8.tests
 
 : decode-utf8-w/stream ( array -- newarray )
@@ -25,3 +25,7 @@ IN: io.encodings.utf8.tests
 
 [ 3 ] [ 1 "日本語" >utf8-index ] unit-test
 [ 3 ] [ 9 "日本語" utf8-index> ] unit-test
+
+[ 3 ] [ 2 "lápis" >utf8-index ] unit-test
+
+[ V{ } ] [ 100000 [ [ code-point-length ] [ 1string utf8 encode length ] bi = not ] filter ] unit-test
index aca36c8551bfa7df9dd715e2c4fafaa3f8b651d2..4846b06f32d29023bbf2d257a24c2554d3852b61 100755 (executable)
@@ -73,12 +73,14 @@ M: utf8 encode-char
 PRIVATE>
 
 : code-point-length ( n -- x )
-    log2 {
-        { [ dup 0 7 between? ] [ 1 ] }
-        { [ dup 8 11 between? ] [ 2 ] }
-        { [ dup 12 16 between? ] [ 3 ] }
-        { [ dup 17 21 between? ] [ 4 ] }
-    } cond nip ;
+    dup zero? [ drop 1 ] [
+        log2 {
+            { [ dup 0 6 between? ] [ 1 ] }
+            { [ dup 7 10 between? ] [ 2 ] }
+            { [ dup 11 15 between? ] [ 3 ] }
+            { [ dup 16 20 between? ] [ 4 ] }
+        } cond nip
+    ] if ;
 
 : code-point-offsets ( string -- indices )
     0 [ code-point-length + ] accumulate swap suffix ;
@@ -87,4 +89,4 @@ PRIVATE>
     code-point-offsets [ <= ] with find drop ;
 
 : >utf8-index ( n string -- n' )
-    code-point-offsets nth ;
\ No newline at end of file
+    code-point-offsets nth ;
index 489cac6703c5b8e285c16742feb456efde71cc93..ebc248bbbf8adf9995cc8cfdff9180252dc0feb4 100644 (file)
@@ -2,6 +2,24 @@ USING: help.markup help.syntax quotations hashtables kernel
 classes strings continuations destructors math byte-arrays ;
 IN: io
 
+HELP: +byte+
+{ $description "A stream element type. See " { $link stream-element-type } " for explanation." } ;
+
+HELP: +character+
+{ $description "A stream element type. See " { $link stream-element-type } " for explanation." } ;
+
+HELP: stream-element-type
+{ $values { "stream" "a stream" } { "type" { $link +byte+ } " or " { $link +character+ } } }
+{ $description
+  "Outputs one of the following two values:"
+  { $list
+    { { $link +byte+ } " - indicates that stream elements are integers in the range " { $snippet "[0,255]" } "; they represent bytes. Reading a sequence of elements produces a " { $link byte-array } "." }
+    { { $link +character+ } " - indicates that stream elements are non-negative integers, representing Unicode code points. Reading a sequence of elements produces a " { $link string } "." }
+  }
+  "Most external streams are binary streams, and can be wrapped in string streams once a suitable encoding has been provided; see " { $link "io.encodings" } "."
+  
+} ;
+
 HELP: stream-readln
 { $values { "stream" "an input stream" } { "str/f" "a string or " { $link f } } }
 { $contract "Reads a line of input from the stream. Outputs " { $link f } " on stream exhaustion." }
@@ -68,7 +86,6 @@ HELP: stream-copy
 { $description "Copies the contents of one stream into another, closing both streams when done." } 
 $io-error ;
 
-
 HELP: stream-seek
 { $values
      { "n" integer } { "seek-type" "a seek singleton" } { "stream" "a stream" }
@@ -228,6 +245,8 @@ $nl
 $nl
 "All streams must implement the " { $link dispose } " word in addition to the stream protocol."
 $nl
+"The following word is required for all input and output streams:"
+{ $subsection stream-element-type }
 "These words are required for binary and string input streams:"
 { $subsection stream-read1 }
 { $subsection stream-read }
@@ -243,7 +262,6 @@ $nl
 { $subsection stream-nl }
 "This word is for streams that allow seeking:"
 { $subsection stream-seek }
-"For a discussion of the distinction between binary and string streams, see " { $link "stream-elements" } "."
 { $see-also "io.timeouts" } ;
 
 ARTICLE: "stdio-motivation" "Motivation for default streams"
@@ -294,7 +312,7 @@ $nl
 { $subsection read }
 { $subsection read-until }
 { $subsection read-partial }
-"If the default input stream is a string stream (" { $link "stream-elements" } "), lines of text can be read:"
+"If the default input stream is a character stream (" { $link stream-element-type } " outputs " { $link +character+ } "), lines of text can be read:"
 { $subsection readln }
 "Seeking on the default input stream:"
 { $subsection seek-input }
@@ -309,7 +327,7 @@ $nl
 { $subsection flush }
 { $subsection write1 }
 { $subsection write }
-"If the default output stream is a string stream (" { $link "stream-elements" } "), lines of text can be written:"
+"If the default output stream is a character stream (" { $link stream-element-type } " outputs " { $link +character+ } "), lines of text can be written:"
 { $subsection readln }
 { $subsection print }
 { $subsection nl }
@@ -337,17 +355,9 @@ $nl
 "Copying the contents of one stream to another:"
 { $subsection stream-copy } ;
 
-ARTICLE: "stream-elements" "Stream elements"
-"There are two types of streams:"
-{ $list
-  { { $strong "Binary streams" } " - the elements are integers between 0 and 255, inclusive; they represent bytes. Reading a sequence of elements produces a " { $link byte-array } "." }
-  { { $strong "String streams" } " - the elements are non-negative integers, representing Unicode code points. Reading a sequence of elements produces a " { $link string } "." }
-}
-"Most external streams are binary streams, and can be wrapped in string streams once a suitable encoding has been provided; see " { $link "io.encodings" } "." ;
-
 ARTICLE: "streams" "Streams"
-"Input and output centers on the concept of a " { $emphasis "stream" } ", which is a source or sink of elements."
-{ $subsection "stream-elements" }
+"Input and output centers on the concept of a " { $emphasis "stream" } ", which is a source or sink of " { $emphasis "elements" } "."
+$nl
 "A stream can either be passed around on the stack or bound to a dynamic variable and used as one of the two implicit " { $emphasis "default streams" } "."
 { $subsection "stream-protocol" }
 { $subsection "stdio" }
index cb68b1c4fefb5ca95a1737f2ae22145286410630..74bba7769ee48f6203c835cd7342672ed09fae53 100644 (file)
@@ -4,6 +4,10 @@ USING: hashtables generic kernel math namespaces make sequences
 continuations destructors assocs ;
 IN: io
 
+SYMBOLS: +byte+ +character+ ;
+
+GENERIC: stream-element-type ( stream -- type )
+
 GENERIC: stream-read1 ( stream -- elt )
 GENERIC: stream-read ( n stream -- seq )
 GENERIC: stream-read-until ( seps stream -- seq sep/f )
index a93602533d8dbbc3f81f7ee4e6880def86b3a277..bec3bdc6bfab34682137fd8dde38c79514f8234d 100755 (executable)
@@ -1,43 +1,46 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel kernel.private namespaces make io io.encodings
 sequences math generic threads.private classes io.backend
-io.files continuations destructors byte-arrays accessors ;
+io.files continuations destructors byte-arrays accessors
+combinators ;
 IN: io.streams.c
 
-TUPLE: c-writer handle disposed ;
+TUPLE: c-stream handle disposed ;
+
+M: c-stream dispose* handle>> fclose ;
+
+M: c-stream stream-seek
+    handle>> swap {
+        { seek-absolute [ 0 ] }
+        { seek-relative [ 1 ] }
+        { seek-end [ 2 ] }
+        [ bad-seek-type ]
+    } case fseek ;
+
+TUPLE: c-writer < c-stream ;
 
 : <c-writer> ( handle -- stream ) f c-writer boa ;
 
-M: c-writer stream-write1
-    dup check-disposed
-    handle>> fputc ;
+M: c-writer stream-element-type drop +byte+ ;
 
-M: c-writer stream-write
-    dup check-disposed
-    handle>> fwrite ;
+M: c-writer stream-write1 dup check-disposed handle>> fputc ;
 
-M: c-writer stream-flush
-    dup check-disposed
-    handle>> fflush ;
+M: c-writer stream-write dup check-disposed handle>> fwrite ;
 
-M: c-writer dispose*
-    handle>> fclose ;
+M: c-writer stream-flush dup check-disposed handle>> fflush ;
 
-TUPLE: c-reader handle disposed ;
+TUPLE: c-reader < c-stream ;
 
 : <c-reader> ( handle -- stream ) f c-reader boa ;
 
-M: c-reader stream-read
-    dup check-disposed
-    handle>> fread ;
+M: c-reader stream-element-type drop +byte+ ;
 
-M: c-reader stream-read-partial
-    stream-read ;
+M: c-reader stream-read dup check-disposed handle>> fread ;
 
-M: c-reader stream-read1
-    dup check-disposed
-    handle>> fgetc ;
+M: c-reader stream-read-partial stream-read ;
+
+M: c-reader stream-read1 dup check-disposed handle>> fgetc ;
 
 : read-until-loop ( stream delim -- ch )
     over stream-read1 dup [
@@ -51,9 +54,6 @@ M: c-reader stream-read-until
     [ swap read-until-loop ] B{ } make swap
     over empty? over not and [ 2drop f f ] when ;
 
-M: c-reader dispose*
-    handle>> fclose ;
-
 M: c-io-backend init-io ;
 
 : stdin-handle ( -- alien ) 11 getenv ;
index 98729c7abdefd80a8e63c4cdd0b211334c26da64..2b62ec938a4b5598a9e4bf22e5eb2e51c8813544 100644 (file)
@@ -9,11 +9,13 @@ INSTANCE: null-writer plain-writer
 
 M: null-stream dispose drop ;
 
+M: null-reader stream-element-type drop +byte+ ;
 M: null-reader stream-readln drop f ;
 M: null-reader stream-read1 drop f ;
 M: null-reader stream-read-until 2drop f f ;
 M: null-reader stream-read 2drop f ;
 
+M: null-writer stream-element-type drop +byte+ ;
 M: null-writer stream-write1 2drop ;
 M: null-writer stream-write 2drop ;
 M: null-writer stream-flush drop ;
index 7933dd86ca7f8664aa0f009ec571bed57d9249c7..0f922a37cc6421d4b264a4a93f77e0c522150518 100644 (file)
@@ -1,8 +1,10 @@
 ! Copyright (C) 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences io kernel accessors math math.order ;
+USING: sequences io io.streams.plain kernel accessors math math.order
+growable destructors ;
 IN: io.streams.sequence
 
+! Readers
 SLOT: underlying
 SLOT: i
 
@@ -13,11 +15,10 @@ SLOT: i
     [ 1+ ] change-i drop ; inline
 
 : sequence-read1 ( stream -- elt/f )
-    [ >sequence-stream< ?nth ]
-    [ next ] bi ; inline
+    [ >sequence-stream< ?nth ] [ next ] bi ; inline
 
 : add-length ( n stream -- i+n )
-    [ i>> + ] [ underlying>> length ] bi min  ; inline
+    [ i>> + ] [ underlying>> length ] bi min ; inline
 
 : (sequence-read) ( n stream -- seq/f )
     [ add-length ] keep
@@ -30,9 +31,18 @@ SLOT: i
     [ (sequence-read) ] [ 2drop f ] if ; inline
 
 : find-sep ( seps stream -- sep/f n )
-    swap [ >sequence-stream< ] dip
-    [ memq? ] curry find-from swap ; inline
+    swap [ >sequence-stream< swap tail-slice ] dip
+    [ memq? ] curry find swap ; inline
 
 : sequence-read-until ( separators stream -- seq sep/f )
     [ find-sep ] keep
     [ sequence-read ] [ next ] bi swap ; inline
+
+! Writers
+M: growable dispose drop ;
+
+M: growable stream-write1 push ;
+M: growable stream-write push-all ;
+M: growable stream-flush drop ;
+
+INSTANCE: growable plain-writer
\ No newline at end of file
index 959f145bf53f75f63191a3b0d1cb814f16af3667..e6ac5760aaa2a4dcfdb58c2b768cd24113e33e2f 100644 (file)
@@ -1,4 +1,4 @@
 IN: io.tests
 USE: math
-: foo 2 2 + ;
+: foo ( -- x ) 2 2 + ;
 FORGET: foo
\ No newline at end of file
index c178573a0a4d9390d78f343989800df26a01e05d..36d04f1437eabe8176f5e9b8783fb17a163efab7 100644 (file)
@@ -841,260 +841,6 @@ $nl
 { $subsection roll }
 { $subsection -roll } ;
 
-ARTICLE: "cleave-shuffle-equivalence" "Expressing shuffle words with cleave combinators"
-"Cleave combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to cleave combinators are discussed in the documentation for " { $link bi } ", " { $link 2bi } ", " { $link 3bi } ", " { $link tri } ", " { $link 2tri } " and " { $link 3tri } "."
-$nl
-"Certain shuffle words can also be expressed in terms of the cleave combinators. Internalizing such identities can help with understanding and writing code using cleave combinators:"
-{ $code
-    ": keep  [ ] bi ;"
-    ": 2keep [ ] 2bi ;"
-    ": 3keep [ ] 3bi ;"
-    ""
-    ": dup   [ ] [ ] bi ;"
-    ": 2dup  [ ] [ ] 2bi ;"
-    ": 3dup  [ ] [ ] 3bi ;"
-    ""
-    ": tuck  [ nip ] [ ] 2bi ;"
-    ": swap  [ nip ] [ drop ] 2bi ;"
-    ""
-    ": over  [ ] [ drop ] 2bi ;"
-    ": pick  [ ] [ 2drop ] 3bi ;"
-    ": 2over [ ] [ drop ] 3bi ;"
-} ;
-
-ARTICLE: "cleave-combinators" "Cleave combinators"
-"The cleave combinators apply multiple quotations to a single value."
-$nl
-"Two quotations:"
-{ $subsection bi }
-{ $subsection 2bi }
-{ $subsection 3bi }
-"Three quotations:"
-{ $subsection tri }
-{ $subsection 2tri }
-{ $subsection 3tri }
-"Technically, the cleave combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on the top of the stack can be written in one of two ways:"
-{ $code
-    "! First alternative; uses keep"
-    "[ 1 + ] keep"
-    "[ 1 - ] keep"
-    "2 *"
-    "! Second alternative: uses tri"
-    "[ 1 + ]"
-    "[ 1 - ]"
-    "[ 2 * ] tri"
-}
-"The latter is more aesthetically pleasing than the former."
-$nl
-"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
-{ $subsection "cleave-shuffle-equivalence" } ;
-
-ARTICLE: "spread-shuffle-equivalence" "Expressing shuffle words with spread combinators"
-"Spread combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to spread combinators are discussed in the documentation for " { $link bi* } ", " { $link 2bi* } ", " { $link tri* } ", and " { $link 2tri* } "."
-$nl
-"Certain shuffle words can also be expressed in terms of the spread combinators. Internalizing such identities can help with understanding and writing code using spread combinators:"
-{ $code
-    ": dip   [ ] bi* ;"
-    ": 2dip  [ ] [ ] tri* ;"
-    ""
-    ": slip  [ call ] [ ] bi* ;"
-    ": 2slip [ call ] [ ] [ ] tri* ;"
-    ""
-    ": nip   [ drop ] [ ] bi* ;"
-    ": 2nip  [ drop ] [ drop ] [ ] tri* ;"
-    ""
-    ": rot"
-    "    [ [ drop ] [      ] [ drop ] tri* ]"
-    "    [ [ drop ] [ drop ] [      ] tri* ]"
-    "    [ [      ] [ drop ] [ drop ] tri* ]"
-    "    3tri ;"
-    ""
-    ": -rot"
-    "    [ [ drop ] [ drop ] [      ] tri* ]"
-    "    [ [      ] [ drop ] [ drop ] tri* ]"
-    "    [ [ drop ] [      ] [ drop ] tri* ]"
-    "    3tri ;"
-    ""
-    ": spin"
-    "    [ [ drop ] [ drop ] [      ] tri* ]"
-    "    [ [ drop ] [      ] [ drop ] tri* ]"
-    "    [ [      ] [ drop ] [ drop ] tri* ]"
-    "    3tri ;"
-} ;
-
-ARTICLE: "spread-combinators" "Spread combinators"
-"The spread combinators apply multiple quotations to multiple values. The " { $snippet "*" } " suffix signifies spreading."
-$nl
-"Two quotations:"
-{ $subsection bi* }
-{ $subsection 2bi* }
-"Three quotations:"
-{ $subsection tri* }
-{ $subsection 2tri* }
-"Technically, the spread combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on three related values can be written in one of two ways:"
-{ $code
-    "! First alternative; uses dip"
-    "[ [ 1 + ] dip 1 - ] dip 2 *"
-    "! Second alternative: uses tri*"
-    "[ 1 + ] [ 1 - ] [ 2 * ] tri*"
-}
-"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
-{ $subsection "spread-shuffle-equivalence" } ;
-
-ARTICLE: "apply-combinators" "Apply combinators"
-"The apply combinators apply a single quotation to multiple values. The " { $snippet "@" } " suffix signifies application."
-$nl
-"Two quotations:"
-{ $subsection bi@ }
-{ $subsection 2bi@ }
-"Three quotations:"
-{ $subsection tri@ }
-{ $subsection 2tri@ }
-"A pair of utility words built from " { $link bi@ } ":"
-{ $subsection both? }
-{ $subsection either? } ;
-
-ARTICLE: "slip-keep-combinators" "Retain stack combinators"
-"Sometimes an additional storage area is needed to hold objects. The " { $emphasis "retain stack" } " is an auxilliary stack for this purpose. Objects can be moved between the data and retain stacks using a set of combinators."
-$nl
-"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
-{ $subsection dip }
-{ $subsection 2dip }
-{ $subsection 3dip }
-{ $subsection 4dip }
-"The slip combinators invoke a quotation further down on the stack. They are most useful for implementing other combinators:"
-{ $subsection slip }
-{ $subsection 2slip }
-{ $subsection 3slip }
-"The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
-{ $subsection keep }
-{ $subsection 2keep }
-{ $subsection 3keep } ;
-
-ARTICLE: "curried-dataflow" "Curried dataflow combinators"
-"Curried cleave combinators:"
-{ $subsection bi-curry }
-{ $subsection tri-curry }
-"Curried spread combinators:"
-{ $subsection bi-curry* }
-{ $subsection tri-curry* }
-"Curried apply combinators:"
-{ $subsection bi-curry@ }
-{ $subsection tri-curry@ }
-{ $see-also "dataflow-combinators" } ;
-
-ARTICLE: "compositional-examples" "Examples of compositional combinator usage"
-"Consider printing the same message ten times:"
-{ $code ": print-10 ( -- ) 10 [ \"Hello, world.\" print ] times ;" }
-"if we wanted to abstract out the message into a parameter, we could keep it on the stack between iterations:"
-{ $code ": print-10 ( message -- ) 10 [ dup print ] times drop ;" }
-"However, keeping loop-invariant values on the stack doesn't always work out nicely. For example, a word to subtract a value from each element of a sequence:"
-{ $code ": subtract-n ( seq n -- seq' ) swap [ over - ] map nip ;" }
-"Three shuffle words are required to pass the value around. Instead, the loop-invariant value can be partially applied to a quotation using " { $link curry } ", yielding a new quotation that is passed to " { $link map } ":"
-{ $example
-  "USING: kernel math prettyprint sequences ;"
-  ": subtract-n ( seq n -- seq' ) [ - ] curry map ;"
-  "{ 10 20 30 } 5 subtract-n ."
-  "{ 5 15 25 }"
-}
-"Now consider the word that is dual to the one above; instead of subtracting " { $snippet "n" } " from each stack element, it subtracts each element from " { $snippet "n" } "."
-$nl
-"One way to write this is with a pair of " { $link swap } "s:"
-{ $code ": n-subtract ( n seq -- seq' ) swap [ swap - ] curry map ;" }
-"Since this pattern comes up often, " { $link with } " encapsulates it:"
-{ $example
-  "USING: kernel math prettyprint sequences ;"
-  ": n-subtract ( n seq -- seq' ) [ - ] with map ;"
-  "30 { 10 20 30 } n-subtract ."
-  "{ 20 10 0 }"
-}
-{ $see-also "fry.examples" } ;
-
-ARTICLE: "compositional-combinators" "Compositional combinators"
-"Certain combinators transform quotations to produce a new quotation."
-{ $subsection "compositional-examples" }
-"Fundamental operations:"
-{ $subsection curry }
-{ $subsection compose }
-"Derived operations:"
-{ $subsection 2curry }
-{ $subsection 3curry }
-{ $subsection with }
-{ $subsection prepose }
-"These operations run in constant time, and in many cases are optimized out altogether by the " { $link "compiler" } ". " { $link "fry" } " are an abstraction built on top of these operations, and code that uses this abstraction is often clearer than direct calls to the below words."
-$nl
-"Curried dataflow combinators can be used to build more complex dataflow by combining cleave, spread and apply patterns in various ways."
-{ $subsection "curried-dataflow" }
-"Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } ". However, such runtime quotation manipulation will not be optimized by the optimizing compiler." ;
-
-ARTICLE: "implementing-combinators" "Implementing combinators"
-"The following pair of words invoke words and quotations reflectively:"
-{ $subsection call }
-{ $subsection execute }
-"These words are used to implement combinators. Note that combinator definitions must be followed by the " { $link POSTPONE: inline } " declaration in order to compile in the optimizing compiler; for example:"
-{ $code
-    ": keep ( x quot -- x )"
-    "    over [ call ] dip ; inline"
-}
-"Word inlining is documented in " { $link "declarations" } "." ;
-
-ARTICLE: "booleans" "Booleans"
-"In Factor, any object that is not " { $link f } " has a true value, and " { $link f } " has a false value. The " { $link t } " object is the canonical true value."
-{ $subsection f }
-{ $subsection t }
-"The " { $link f } " object is the unique instance of the " { $link f } " class; the two are distinct objects. The latter is also a parsing word which adds the " { $link f } " object to the parse tree at parse time. To refer to the class itself you must use " { $link POSTPONE: POSTPONE: } " or " { $link POSTPONE: \ } " to prevent the parsing word from executing."
-$nl
-"Here is the " { $link f } " object:"
-{ $example "f ." "f" }
-"Here is the " { $link f } " class:"
-{ $example "\\ f ." "POSTPONE: f" }
-"They are not equal:"
-{ $example "f \\ f = ." "f" }
-"Here is an array containing the " { $link f } " object:"
-{ $example "{ f } ." "{ f }" }
-"Here is an array containing the " { $link f } " class:"
-{ $example "{ POSTPONE: f } ." "{ POSTPONE: f }" }
-"The " { $link f } " object is an instance of the " { $link f } " class:"
-{ $example "USE: classes" "f class ." "POSTPONE: f" }
-"The " { $link f } " class is an instance of " { $link word } ":"
-{ $example "USE: classes" "\\ f class ." "word" }
-"On the other hand, " { $link t } " is just a word, and there is no class which it is a unique instance of."
-{ $example "t \\ t eq? ." "t" }
-"Many words which search collections confuse the case of no element being present with an element being found equal to " { $link f } ". If this distinction is imporant, there is usually an alternative word which can be used; for example, compare " { $link at } " with " { $link at* } "." ;
-
-ARTICLE: "conditionals-boolean-equivalence" "Expressing conditionals with boolean logic"
-"Certain simple conditional forms can be expressed in a simpler manner using boolean logic."
-$nl
-"The following two lines are equivalent:"
-{ $code "[ drop f ] unless" "swap and" }
-"The following two lines are equivalent:"
-{ $code "[ ] [ ] ?if" "swap or" }
-"The following two lines are equivalent, where " { $snippet "L" } " is a literal:"
-{ $code "[ L ] unless*" "L or" } ;
-
-ARTICLE: "conditionals" "Conditionals and logic"
-"The basic conditionals:"
-{ $subsection if }
-{ $subsection when }
-{ $subsection unless }
-"Forms abstracting a common stack shuffle pattern:"
-{ $subsection if* }
-{ $subsection when* }
-{ $subsection unless* }
-"Another form abstracting a common stack shuffle pattern:"
-{ $subsection ?if }
-"Sometimes instead of branching, you just need to pick one of two values:"
-{ $subsection ? }
-"There are some logical operations on booleans:"
-{ $subsection >boolean }
-{ $subsection not }
-{ $subsection and }
-{ $subsection or }
-{ $subsection xor }
-{ $subsection "conditionals-boolean-equivalence" }
-"See " { $link "combinators" } " for forms which abstract away common patterns involving multiple nested branches."
-{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
-
 ARTICLE: "equality" "Equality"
 "There are two distinct notions of “sameness” when it comes to objects."
 $nl
@@ -1116,34 +862,3 @@ ARTICLE: "assertions" "Assertions"
 { $subsection assert }
 { $subsection assert= } ;
 
-ARTICLE: "dataflow-combinators" "Data flow combinators"
-"Data flow combinators pass values between quotations:"
-{ $subsection "slip-keep-combinators" }
-{ $subsection "cleave-combinators" }
-{ $subsection "spread-combinators" }
-{ $subsection "apply-combinators" }
-{ $see-also "curried-dataflow" } ;
-
-ARTICLE: "dataflow" "Data and control flow"
-{ $subsection "evaluator" }
-{ $subsection "words" }
-{ $subsection "effects" }
-{ $subsection "booleans" }
-{ $subsection "shuffle-words" }
-"A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
-{ $subsection "dataflow-combinators" }
-{ $subsection "conditionals" }
-{ $subsection "looping-combinators" }
-{ $subsection "compositional-combinators" }
-{ $subsection "combinators" }
-"More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
-$nl
-"Advanced topics:"
-{ $subsection "assertions" }
-{ $subsection "implementing-combinators" }
-{ $subsection "macros" }
-{ $subsection "errors" }
-{ $subsection "continuations" } ;
-
-ABOUT: "dataflow"
-
index 4d725e57f892c3b150a992c63b838d5573d2545b..63346f4701fecfea0a490c394377aa83be4408c3 100644 (file)
@@ -21,21 +21,21 @@ IN: kernel.tests
 
 [ ] [ :c ] unit-test
 
-: overflow-d 3 overflow-d ;
+: overflow-d ( -- ) 3 overflow-d ;
 
 [ overflow-d ] [ { "kernel-error" 12 f f } = ] must-fail-with
 
 [ ] [ :c ] unit-test
 
-: (overflow-d-alt) 3 ;
+: (overflow-d-alt) ( -- ) 3 ;
 
-: overflow-d-alt (overflow-d-alt) overflow-d-alt ;
+: overflow-d-alt ( -- ) (overflow-d-alt) overflow-d-alt ;
 
 [ overflow-d-alt ] [ { "kernel-error" 12 f f } = ] must-fail-with
 
 [ ] [ [ :c ] with-string-writer drop ] unit-test
 
-: overflow-r 3 load-local overflow-r ;
+: overflow-r ( -- ) 3 load-local overflow-r ;
 
 [ overflow-r ] [ { "kernel-error" 14 f f } = ] must-fail-with
 
@@ -99,7 +99,7 @@ IN: kernel.tests
 [ ] [ :c ] unit-test
 
 ! Doesn't compile; important
-: foo 5 + 0 [ ] each ;
+: foo ( a -- b ) 5 + 0 [ ] each ;
 
 [ drop foo ] must-fail
 [ ] [ :c ] unit-test
@@ -115,7 +115,7 @@ IN: kernel.tests
 [ loop ] must-fail
 
 ! Discovered on Windows
-: total-failure-1 "" [ ] map unimplemented ;
+: total-failure-1 ( -- ) "" [ ] map unimplemented ;
 
 [ total-failure-1 ] must-fail
 
index cf4bf95db96afeff4a604aaccd53a2a18664cf9e..baccf5605946a10f2c4a4906ec915683e45002e6 100644 (file)
@@ -1,7 +1,6 @@
 ! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel.private slots.private math.private
-classes.tuple.private ;
+USING: kernel.private slots.private math.private ;
 IN: kernel
 
 DEFER: dip
@@ -22,6 +21,12 @@ DEFER: 3dip
 ! Combinators
 GENERIC: call ( callable -- )
 
+GENERIC: execute ( word -- )
+
+GENERIC: ?execute ( word -- value )
+
+M: object ?execute ;
+
 DEFER: if
 
 : ? ( ? true false -- true/false )
@@ -235,7 +240,7 @@ GENERIC: boa ( ... class -- tuple )
 
 ! Error handling -- defined early so that other files can
 ! throw errors before continuations are loaded
-: throw ( error -- * ) 5 getenv [ die ] or 1 (throw) ;
+GENERIC: throw ( error -- * )
 
 ERROR: assert got expect ;
 
index 101557d0cf80b353186a370e6f42c834a8c5344f..c28bf062c1954abd705f692fcf5c0bb1adf694da 100644 (file)
@@ -307,7 +307,7 @@ HELP: find-last-integer
 { $notes "This word is used to implement " { $link find-last } "." } ;
 
 HELP: byte-array>bignum
-{ $values { "byte-array" byte-array } { "n" integer } }
+{ $values { "x" byte-array } { "y" bignum } }
 { $description "Converts a byte-array, interpreted as little-endian, into a bignum integer. User code should call " { $link le> } " or " { $link be> } " instead." } ;
 
 ARTICLE: "division-by-zero" "Division by zero"
@@ -355,8 +355,9 @@ ARTICLE: "bitwise-arithmetic" "Bitwise arithmetic"
 { $subsection 2/ }
 { $subsection 2^ }
 { $subsection bit? }
-"The " { $vocab-link "math.bitwise" } " vocabulary implements additional bitwise integer operations."
-{ $see-also "conditionals" } ;
+{ $subsection "math.bitwise" }
+{ $subsection "math.bits" }
+{ $see-also "booleans" } ;
 
 ARTICLE: "arithmetic" "Arithmetic"
 "Factor attempts to preserve natural mathematical semantics for numbers. Multiplying two large integers never results in overflow, and dividing two integers yields an exact ratio. Floating point numbers are also supported, along with complex numbers."
index 1bdd1009e9c77c7b03504554de13b22973285ac6..8b2200aa6710fdbb14425acbc5a5e2f0e333c735 100644 (file)
@@ -87,7 +87,14 @@ ARTICLE: "order-specifiers" "Ordering specifiers"
 { $subsection +lt+ }
 { $subsection +eq+ }
 { $subsection +gt+ } ;
-    
+
+ARTICLE: "math.order.example" "Linear order example"
+"A tuple class which defines an ordering among instances by comparing the values of the " { $snippet "id" } " slot:"
+{ $code
+  "TUPLE: sprite id name bitmap ;"
+  "M: sprite <=> [ id>> ] compare ;"
+} ;
+
 ARTICLE: "math.order" "Linear order protocol"
 "Some classes have an intrinsic order amongst instances:"
 { $subsection <=> }
@@ -101,6 +108,8 @@ ARTICLE: "math.order" "Linear order protocol"
 { $subsection before? }
 { $subsection after=? }
 { $subsection before=? }
+"Out of the above generic words, it suffices to implement " { $link <=> } " alone. The others may be provided as an optimization."
+{ $subsection "math.order.example" }
 { $see-also "sequences-sorting" } ;
 
 ABOUT: "math.order"
index 11a6a9d8a991a1247219bf8ebb20b64a9739c9c0..995c7e6064677498d9a7fee3ed1c8b6c274508ba 100644 (file)
@@ -15,9 +15,9 @@ IN: memory.tests
 [ [ ] instances ] must-infer
 
 ! Code GC wasn't kicking in when needed
-: leak-step 800000 f <array> 1quotation call drop ;
+: leak-step ( -- ) 800000 f <array> 1quotation call drop ;
 
-: leak-loop 100 [ leak-step ] times ;
+: leak-loop ( -- ) 100 [ leak-step ] times ;
 
 [ ] [ leak-loop ] unit-test
 
index ff0542a7b87da8b877c0c7f326033d9d48f6b60f..74d7c58963807d4c8552a6612c6b693b48a3a90e 100644 (file)
@@ -32,7 +32,7 @@ ARTICLE: "namespaces.private" "Namespace implementation details"
 { $subsection >n }
 { $subsection ndrop } ;
 
-ARTICLE: "namespaces" "Variables and namespaces"
+ARTICLE: "namespaces" "Dynamic variables and namespaces"
 "The " { $vocab-link "namespaces" } " vocabulary implements simple dynamically-scoped variables."
 $nl
 "A variable is an entry in an assoc of bindings, where the assoc is implicit rather than passed on the stack. These assocs are termed " { $emphasis "namespaces" } ". Nesting of scopes is implemented with a search order on namespaces, defined by a " { $emphasis "namestack" } ". Since namespaces are just assoc, any object can be used as a variable, however by convention, variables are keyed by symbols (see " { $link "words.symbol" } ")."
@@ -43,7 +43,6 @@ $nl
 "Various utility words abstract away common variable access patterns:"
 { $subsection "namespaces-change" }
 { $subsection "namespaces-combinators" }
-{ $subsection "namespaces-global" }
 "Implementation details your code probably does not care about:"
 { $subsection "namespaces.private" }
 "An alternative to dynamic scope is lexical scope. Lexically-scoped values and closures are implemented in the " { $vocab-link "locals" } " vocabulary." ;
index 623e2ddcda9a07c08a1918ed86cb0cbd18ce0c9d..b0e764c94d96244a31a45c71a6c0a7bd03fb8bc0 100644 (file)
@@ -30,6 +30,6 @@ PRIVATE>
 : bind ( ns quot -- ) swap >n call ndrop ; inline
 : counter ( variable -- n ) global [ 0 or 1+ dup ] change-at ;
 : make-assoc ( quot exemplar -- hash ) 20 swap new-assoc [ swap bind ] keep ; inline
-: with-scope ( quot -- ) H{ } clone swap bind ; inline
+: with-scope ( quot -- ) 5 <hashtable> swap bind ; inline
 : with-variable ( value key quot -- ) [ associate ] dip bind ; inline
 : initialize ( variable quot -- ) [ global ] dip [ unless* ] curry change-at ; inline
\ No newline at end of file
index 23bc41a1bb30f2b320d00be0877ee5760ca3938d..be4b345f4f05db887bcc8410c4790d10d1e3341f 100644 (file)
@@ -54,8 +54,10 @@ $nl
 ARTICLE: "parsing-words" "Parsing words"
 "The Factor parser follows a simple recursive-descent design. The parser reads successive tokens from the input; if the token identifies a number or an ordinary word, it is added to an accumulator vector. Otherwise if the token identifies a parsing word, the parsing word is executed immediately."
 $nl
-"Parsing words are marked by suffixing the definition with a " { $link POSTPONE: parsing } " declaration. Here is the simplest possible parsing word; it prints a greeting at parse time:"
-{ $code ": hello \"Hello world\" print ; parsing" }
+"Parsing words are defined using the a defining word:"
+{ $subsection POSTPONE: SYNTAX: }
+"Parsing words have uppercase names by convention. Here is the simplest possible parsing word; it prints a greeting at parse time:"
+{ $code "SYNTAX: HELLO \"Hello world\" print ;" }
 "Parsing words must not pop or push items from the stack; however, they are permitted to access the accumulator vector supplied by the parser at the top of the stack. That is, parsing words must have stack effect " { $snippet "( accum -- accum )" } ", where " { $snippet "accum" } " is the accumulator vector supplied by the parser."
 $nl
 "Parsing words can read input, add word definitions to the dictionary, and do anything an ordinary word can."
@@ -90,9 +92,7 @@ ARTICLE: "parser" "The parser"
 "This parser is a general facility for reading textual representations of objects and definitions. The parser is implemented in the " { $vocab-link "parser" } " and " { $vocab-link "syntax" } " vocabularies."
 $nl
 "This section concerns itself with usage and extension of the parser. Standard syntax is described in " { $link "syntax" } "."
-{ $subsection "vocabulary-search" }
 { $subsection "parser-files" }
-{ $subsection "top-level-forms" }
 "The parser can be extended."
 { $subsection "parsing-words" }
 { $subsection "parser-lexer" }
index 5ec9ea9b3c09c9513eeaf86cea3c779a99fc6698..3ba414fe6beb9304cbd6ff56def0e823ddd92697 100644 (file)
@@ -3,7 +3,7 @@ io.streams.string namespaces classes effects source-files assocs
 sequences strings io.files io.pathnames definitions
 continuations sorting classes.tuple compiler.units debugger
 vocabs vocabs.loader accessors eval combinators lexer
-vocabs.parser words.symbol ;
+vocabs.parser words.symbol multiline ;
 IN: parser.tests
 
 \ run-file must-infer
@@ -27,7 +27,7 @@ IN: parser.tests
 
     [ "hello world" ]
     [
-        "IN: parser.tests : hello \"hello world\" ;"
+        "IN: parser.tests : hello ( -- str ) \"hello world\" ;"
         eval "USE: parser.tests hello" eval
     ] unit-test
 
@@ -78,12 +78,8 @@ IN: parser.tests
     [ T{ effect f { "a" "b" } { "d" } f } ]
     [ \ effect-parsing-test "declared-effect" word-prop ] unit-test
 
-    [ ] [ "IN: parser.tests : effect-parsing-test ;" eval ] unit-test
-
-    [ f ] [ \ effect-parsing-test "declared-effect" word-prop ] unit-test
-
     ! Funny bug
-    [ 2 ] [ "IN: parser.tests : \0. 2 ; \0." eval ] unit-test
+    [ 2 ] [ "IN: parser.tests : \0. ( -- x ) 2 ; \0." eval ] unit-test
 
     [ "IN: parser.tests : missing-- ( a b ) ;" eval ] must-fail
 
@@ -106,11 +102,11 @@ IN: parser.tests
     ] unit-test
     DEFER: foo
 
-    "IN: parser.tests USING: math prettyprint ; : foo 2 2 + . ; parsing" eval
+    "IN: parser.tests USING: math prettyprint ; SYNTAX: foo 2 2 + . ;" eval
 
     [ ] [ "USE: parser.tests foo" eval ] unit-test
 
-    "IN: parser.tests USING: math prettyprint ; : foo 2 2 + . ;" eval
+    "IN: parser.tests USING: math prettyprint ; : foo ( -- ) 2 2 + . ;" eval
 
     [ t ] [
         "USE: parser.tests \\ foo" eval
@@ -120,7 +116,7 @@ IN: parser.tests
     ! Test smudging
 
     [ 1 ] [
-        "IN: parser.tests : smudge-me ;" <string-reader> "foo"
+        "IN: parser.tests : smudge-me ( -- ) ;" <string-reader> "foo"
         parse-stream drop
 
         "foo" source-file definitions>> first assoc-size
@@ -129,7 +125,7 @@ IN: parser.tests
     [ t ] [ "smudge-me" "parser.tests" lookup >boolean ] unit-test
 
     [ ] [
-        "IN: parser.tests : smudge-me-more ;" <string-reader> "foo"
+        "IN: parser.tests : smudge-me-more ( -- ) ;" <string-reader> "foo"
         parse-stream drop
     ] unit-test
 
@@ -137,7 +133,7 @@ IN: parser.tests
     [ f ] [ "smudge-me" "parser.tests" lookup >boolean ] unit-test
 
     [ 3 ] [
-        "IN: parser.tests USING: math strings ; GENERIC: smudge-me M: integer smudge-me ; M: string smudge-me ;" <string-reader> "foo"
+        "IN: parser.tests USING: math strings ; GENERIC: smudge-me ( a -- b ) M: integer smudge-me ; M: string smudge-me ;" <string-reader> "foo"
         parse-stream drop
 
         "foo" source-file definitions>> first assoc-size
@@ -151,7 +147,7 @@ IN: parser.tests
     ] unit-test
 
     [ 2 ] [
-        "IN: parser.tests USING: math strings ; GENERIC: smudge-me M: integer smudge-me ;" <string-reader> "foo"
+        "IN: parser.tests USING: math strings ; GENERIC: smudge-me ( a -- b ) M: integer smudge-me ;" <string-reader> "foo"
         parse-stream drop
 
         "foo" source-file definitions>> first assoc-size
@@ -190,7 +186,7 @@ IN: parser.tests
     [ ] [
         "a" source-files get delete-at
         2 [
-            "IN: parser.tests DEFER: x : y x ; : x y ;"
+            "IN: parser.tests DEFER: x : y ( -- ) x ; : x ( -- ) y ;"
             <string-reader> "a" parse-stream drop
         ] times
     ] unit-test
@@ -198,7 +194,7 @@ IN: parser.tests
     "a" source-files get delete-at
 
     [
-        "IN: parser.tests : x ; : y 3 throw ; this is an error"
+        "IN: parser.tests : x ( -- ) ; : y ( -- * ) 3 throw ; this is an error"
         <string-reader> "a" parse-stream
     ] [ source-file-error? ] must-fail-with
 
@@ -207,7 +203,7 @@ IN: parser.tests
     ] unit-test
 
     [ f ] [
-        "IN: parser.tests : x ;"
+        "IN: parser.tests : x ( -- ) ;"
         <string-reader> "a" parse-stream drop
         
         "y" "parser.tests" lookup
@@ -215,18 +211,18 @@ IN: parser.tests
 
     ! Test new forward definition logic
     [ ] [
-        "IN: axx : axx ;"
+        "IN: axx : axx ( -- ) ;"
         <string-reader> "axx" parse-stream drop
     ] unit-test
 
     [ ] [
-        "USE: axx IN: bxx : bxx ; : cxx axx bxx ;"
+        "USE: axx IN: bxx : bxx ( -- ) ; : cxx ( -- ) axx bxx ;"
         <string-reader> "bxx" parse-stream drop
     ] unit-test
 
     ! So we move the bxx word to axx...
     [ ] [
-        "IN: axx : axx ; : bxx ;"
+        "IN: axx : axx ( -- ) ; : bxx ( -- ) ;"
         <string-reader> "axx" parse-stream drop
     ] unit-test
 
@@ -234,7 +230,7 @@ IN: parser.tests
 
     ! And reload the file that uses it...
     [ ] [
-        "USE: axx IN: bxx : cxx axx bxx ;"
+        "USE: axx IN: bxx ( -- ) : cxx ( -- ) axx bxx ;"
         <string-reader> "bxx" parse-stream drop
     ] unit-test
     
@@ -243,17 +239,17 @@ IN: parser.tests
     ! Turning a generic into a non-generic could cause all
     ! kinds of funnyness
     [ ] [
-        "IN: ayy USE: kernel GENERIC: ayy M: object ayy ;"
+        "IN: ayy USE: kernel GENERIC: ayy ( a -- b ) M: object ayy ;"
         <string-reader> "ayy" parse-stream drop
     ] unit-test
 
     [ ] [
-        "IN: ayy USE: kernel : ayy ;"
+        "IN: ayy USE: kernel : ayy ( -- ) ;"
         <string-reader> "ayy" parse-stream drop
     ] unit-test
 
     [ ] [
-        "IN: azz TUPLE: my-class ; GENERIC: a-generic"
+        "IN: azz TUPLE: my-class ; GENERIC: a-generic ( a -- b )"
         <string-reader> "azz" parse-stream drop
     ] unit-test
 
@@ -263,7 +259,7 @@ IN: parser.tests
     ] unit-test
 
     [ ] [
-        "IN: azz GENERIC: a-generic"
+        "IN: azz GENERIC: a-generic ( a -- b )"
         <string-reader> "azz" parse-stream drop
     ] unit-test
 
@@ -273,12 +269,12 @@ IN: parser.tests
     ] unit-test
 
     [ ] [
-        "IN: parser.tests : <bogus-error> ; : bogus <bogus-error> ;"
+        "IN: parser.tests : <bogus-error> ( -- ) ; : bogus ( -- ) <bogus-error> ;"
         <string-reader> "bogus-error" parse-stream drop
     ] unit-test
 
     [ ] [
-        "IN: parser.tests TUPLE: bogus-error ; C: <bogus-error> bogus-error : bogus <bogus-error> ;"
+        "IN: parser.tests TUPLE: bogus-error ; C: <bogus-error> bogus-error : bogus ( -- ) <bogus-error> ;"
         <string-reader> "bogus-error" parse-stream drop
     ] unit-test
 
@@ -298,7 +294,7 @@ IN: parser.tests
     ] unit-test
 
     [
-        "IN: parser.tests TUPLE: another-pred-test ; GENERIC: another-pred-test?"
+        "IN: parser.tests TUPLE: another-pred-test ; GENERIC: another-pred-test? ( a -- b )"
         <string-reader> "removing-the-predicate" parse-stream
     ] [ error>> error>> error>> redefine-error? ] must-fail-with
 
@@ -313,7 +309,7 @@ IN: parser.tests
     ] unit-test
 
     [
-        "IN: parser.tests TUPLE: class-redef-test ; SYMBOL: class-redef-test : class-redef-test ;"
+        "IN: parser.tests TUPLE: class-redef-test ; SYMBOL: class-redef-test : class-redef-test ( -- ) ;"
         <string-reader> "redefining-a-class-3" parse-stream drop
     ] [ error>> error>> error>> redefine-error? ] must-fail-with
 
@@ -338,7 +334,7 @@ IN: parser.tests
     ] [ error>> error>> error>> no-word-error? ] must-fail-with
 
     [
-        "IN: parser.tests : foo ; TUPLE: foo ;"
+        "IN: parser.tests : foo ( -- ) ; TUPLE: foo ;"
         <string-reader> "redefining-a-class-4" parse-stream drop
     ] [ error>> error>> error>> redefine-error? ] must-fail-with
 
@@ -369,7 +365,7 @@ IN: parser.tests
 
 2 [
     [ ] [
-        "IN: parser.tests TUPLE: foo ; GENERIC: foo"
+        "IN: parser.tests TUPLE: foo ; GENERIC: foo ( a -- b )"
         <string-reader> "redefining-a-class-5" parse-stream drop
     ] unit-test
 
@@ -381,14 +377,14 @@ IN: parser.tests
     [ f ] [ f "foo" "parser.tests" lookup execute ] unit-test
 
     [ ] [
-        "IN: parser.tests TUPLE: foo ; GENERIC: foo"
+        "IN: parser.tests TUPLE: foo ; GENERIC: foo ( a -- b )"
         <string-reader> "redefining-a-class-5" parse-stream drop
     ] unit-test
 
     [ f ] [ f "foo" "parser.tests" lookup execute ] unit-test
 
     [ ] [
-        "IN: parser.tests TUPLE: foo ; GENERIC: foo"
+        "IN: parser.tests TUPLE: foo ; GENERIC: foo ( a -- b )"
     <string-reader> "redefining-a-class-7" parse-stream drop
     ] unit-test
 
@@ -402,9 +398,7 @@ IN: parser.tests
     [ t ] [ "foo" "parser.tests" lookup symbol? ] unit-test
 ] times
 
-[ "vocab:parser/test/assert-depth.factor" run-file ]
-[ got>> { 1 2 3 } sequence= ]
-must-fail-with
+[ "vocab:parser/test/assert-depth.factor" run-file ] must-fail
 
 2 [
     [ ] [
@@ -440,7 +434,7 @@ must-fail-with
     {
         "IN: parser.tests"
         "USING: math arrays ;"
-        "GENERIC: change-combination"
+        "GENERIC: change-combination ( a -- b )"
         "M: integer change-combination 1 ;"
         "M: array change-combination 2 ;"
     } "\n" join <string-reader> "change-combination-test" parse-stream drop
@@ -450,7 +444,7 @@ must-fail-with
     {
         "IN: parser.tests"
         "USING: math arrays ;"
-        "GENERIC# change-combination 1"
+        "GENERIC# change-combination 1 ( a -- b )"
         "M: integer change-combination 1 ;"
         "M: array change-combination 2 ;"
     } "\n" join <string-reader> "change-combination-test" parse-stream drop
@@ -469,7 +463,7 @@ must-fail-with
 ] unit-test
 
 [ [ ] ] [
-    "IN: parser.tests : staging-problem-test-1 1 ; : staging-problem-test-2 staging-problem-test-1 ;"
+    "IN: parser.tests : staging-problem-test-1 ( -- ) 1 ; : staging-problem-test-2 ( -- ) staging-problem-test-1 ;"
     <string-reader> "staging-problem-test" parse-stream
 ] unit-test
 
@@ -478,7 +472,7 @@ must-fail-with
 [ t ] [ "staging-problem-test-2" "parser.tests" lookup >boolean ] unit-test
 
 [ [ ] ] [
-    "IN: parser.tests << : staging-problem-test-1 1 ; >> : staging-problem-test-2 staging-problem-test-1 ;"
+    "IN: parser.tests << : staging-problem-test-1 ( -- ) 1 ; >> : staging-problem-test-2 ( -- ) staging-problem-test-1 ;"
     <string-reader> "staging-problem-test" parse-stream
 ] unit-test
 
@@ -489,7 +483,7 @@ must-fail-with
 [ "DEFER: blahy" eval ] [ error>> error>> no-current-vocab? ] must-fail-with
 
 [
-    "IN: parser.tests : blahy ; parsing FORGET: blahy" eval
+    "IN: parser.tests SYNTAX: blahy ; FORGET: blahy" eval
 ] [
     error>> staging-violation?
 ] must-fail-with
@@ -497,7 +491,7 @@ must-fail-with
 ! Bogus error message
 DEFER: blahy
 
-[ "IN: parser.tests USE: kernel TUPLE: blahy < tuple ; : blahy ; TUPLE: blahy < tuple ; : blahy ;" eval ]
+[ "IN: parser.tests USE: kernel TUPLE: blahy < tuple ; : blahy ( -- ) ; TUPLE: blahy < tuple ; : blahy ( -- ) ;" eval ]
 [ error>> error>> def>> \ blahy eq? ] must-fail-with
 
 [ ] [ f lexer set f file set "Hello world" note. ] unit-test
@@ -512,7 +506,7 @@ SYMBOLS: a b c ;
 
 DEFER: blah
 
-[ ] [ "IN: parser.tests GENERIC: blah" eval ] unit-test
+[ ] [ "IN: parser.tests GENERIC: blah ( -- )" eval ] unit-test
 [ ] [ "IN: parser.tests SYMBOLS: blah ;" eval ] unit-test
 
 [ f ] [ \ blah generic? ] unit-test
@@ -525,13 +519,13 @@ DEFER: blah1
 must-fail-with
 
 IN: qualified.tests.foo
-: x 1 ;
-: y 5 ;
+: x ( -- a ) 1 ;
+: y ( -- a ) 5 ;
 IN: qualified.tests.bar
-: x 2 ;
-: y 4 ;
+: x ( -- a ) 2 ;
+: y ( -- a ) 4 ;
 IN: qualified.tests.baz
-: x 3 ;
+: x ( -- a ) 3 ;
 
 QUALIFIED: qualified.tests.foo
 QUALIFIED: qualified.tests.bar
@@ -560,7 +554,7 @@ EXCLUDE: qualified.tests.bar => x ;
 ! Two similar bugs
 
 ! Replace : def with something in << >>
-[ [ ] ] [
+/* [ [ ] ] [
     "IN: parser.tests : was-once-a-word-bug ( -- ) ;"
     <string-reader> "was-once-a-word-test" parse-stream
 ] unit-test
@@ -572,7 +566,7 @@ EXCLUDE: qualified.tests.bar => x ;
     <string-reader> "was-once-a-word-test" parse-stream
 ] unit-test
 
-[ t ] [ "was-once-a-word-bug" "parser.tests" lookup >boolean ] unit-test
+[ t ] [ "was-once-a-word-bug" "parser.tests" lookup >boolean ] unit-test */
 
 ! Replace : def with DEFER:
 [ [ ] ] [
index c68d453b154b8f0554aecf00584c75a121e42a9f..6d613a8b2459e30340bc3a46ec36a3845ba2f3da 100644 (file)
@@ -1,11 +1,10 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays definitions generic assocs kernel math namespaces
-sequences strings vectors words words.symbol quotations io
-combinators sorting splitting math.parser effects continuations
-io.files vocabs io.encodings.utf8 source-files
-classes hashtables compiler.errors compiler.units accessors sets
-lexer vocabs.parser slots ;
+sequences strings vectors words words.symbol quotations io combinators
+sorting splitting math.parser effects continuations io.files vocabs
+io.encodings.utf8 source-files classes hashtables compiler.errors
+compiler.units accessors sets lexer vocabs.parser effects.parser slots ;
 IN: parser
 
 : location ( -- loc )
@@ -90,9 +89,9 @@ SYMBOL: auto-use?
 
 ERROR: staging-violation word ;
 
-: execute-parsing ( word -- )
+: execute-parsing ( accum word -- accum )
     dup changed-definitions get key? [ staging-violation ] when
-    execute ;
+    execute( accum -- accum ) ;
 
 : scan-object ( -- object )
     scan-word dup parsing-word?
@@ -125,7 +124,7 @@ M: f parse-quotation \ ] parse-until >quotation ;
     [ f parse-until >quotation ] with-lexer ;
 
 : parse-lines ( lines -- quot )
-    lexer-factory get call (parse-lines) ;
+    lexer-factory get call( lines -- lexer ) (parse-lines) ;
 
 : parse-literal ( accum end quot -- accum )
     [ parse-until ] dip call parsed ; inline
@@ -133,7 +132,10 @@ M: f parse-quotation \ ] parse-until >quotation ;
 : parse-definition ( -- quot )
     \ ; parse-until >quotation ;
 
-: (:) ( -- word def ) CREATE-WORD parse-definition ;
+: (:) ( -- word def effect )
+    CREATE-WORD
+    complete-effect
+    parse-definition swap ;
 
 ERROR: bad-number ;
 
@@ -164,7 +166,9 @@ SYMBOL: interactive-vocabs
     "definitions"
     "editors"
     "help"
+    "help.apropos"
     "help.lint"
+    "help.vocabs"
     "inspector"
     "io"
     "io.files"
@@ -184,7 +188,6 @@ SYMBOL: interactive-vocabs
     "strings"
     "syntax"
     "tools.annotations"
-    "tools.apropos"
     "tools.crossref"
     "tools.disassembler"
     "tools.memory"
@@ -214,7 +217,7 @@ print-use-hook [ [ ] ] initialize
     [
         V{ } clone amended-use set
         parse-lines
-        amended-use get empty? [ print-use-hook get call ] unless
+        amended-use get empty? [ print-use-hook get call( -- ) ] unless
     ] with-file-vocabs ;
 
 : parsing-file ( file -- )
@@ -288,7 +291,7 @@ print-use-hook [ [ ] ] initialize
     ] recover ;
 
 : run-file ( file -- )
-    [ parse-file call ] curry assert-depth ;
+    parse-file call( -- ) ;
 
 : ?run-file ( path -- )
     dup exists? [ run-file ] [ drop ] if ;
index 2a03b7c74f6bca70dd24916390a81d475c68d82b..a72f4adf8805b30e8390baf7aefc543220e0fd4d 100644 (file)
@@ -24,7 +24,7 @@ ARTICLE: "wrappers" "Wrappers"
 "Wrappers are used to push words on the data stack; they evaluate to the object being wrapped:"
 { $subsection wrapper }
 { $subsection literalize }
-{ $see-also "dataflow" "combinators" } ;
+{ $see-also "combinators" } ;
 
 ABOUT: "quotations"
 
index c171555737eddf6895eab8753cf1bd09a3044d62..556e41249e24032abdb00d79ae423b8e57c39f0b 100755 (executable)
@@ -311,7 +311,7 @@ HELP: each-index
 
 HELP: map-index
 { $values
-     { "seq" sequence } { "quot" quotation } }
+  { "seq" sequence } { "quot" quotation } { "newseq" sequence } }
 { $description "Calls the quotation with the element of the sequence and its index on the stack, with the index on the top of the stack. Collects the outputs of the quotation and outputs them in a sequence of the same type as the input sequence." }
 { $examples { $example "USING: sequences prettyprint math ;"
 "{ 10 20 30 } [ + ] map-index ."
@@ -1354,14 +1354,16 @@ ARTICLE: "virtual-sequences" "Virtual sequences"
 "Virtual sequences allow different ways of accessing a sequence without having to create a new sequence or a new data structure altogether. To do this, they translate the virtual index into a normal index into an underlying sequence using the " { $link "virtual-sequences-protocol" } "."
 { $subsection "virtual-sequences-protocol" } ;
 
-ARTICLE: "sequences-integers" "Integer sequences and counted loops"
+ARTICLE: "sequences-integers" "Counted loops"
 "Integers support the sequence protocol in a trivial fashion; a non-negative integer presents its non-negative predecessors as elements. For example, the integer 3, when viewed as a sequence, contains the elements 0, 1, and 2. This is very useful for performing counted loops."
 $nl
 "For example, the " { $link each } " combinator, given an integer, simply calls a quotation that number of times, pushing a counter on each iteration that ranges from 0 up to that integer:"
 { $example "3 [ . ] each" "0\n1\n2" }
 "A common idiom is to iterate over a sequence, while also maintaining a loop counter. This can be done using " { $link each-index } ", " { $link map-index } " and " { $link reduce-index } "."
 $nl
-"Combinators that produce new sequences, such as " { $link map } ", will output an array if the input is an integer." ;
+"Combinators that produce new sequences, such as " { $link map } ", will output an array if the input is an integer."
+$nl
+"More elaborate counted loops can be performed with " { $link "math.ranges" } "." ;
 
 ARTICLE: "sequences-access" "Accessing sequence elements"
 { $subsection ?nth }
@@ -1593,7 +1595,6 @@ $nl
 "Sequences implement a protocol:"
 { $subsection "sequence-protocol" }
 { $subsection "sequences-f" }
-{ $subsection "sequences-integers" }
 "Sequence utility words can operate on any object whose class implements the sequence protocol. Most implementations are backed by storage. Some implementations obtain their elements from an underlying sequence, or compute them on the fly. These are known as " { $link "virtual-sequences" } "."
 { $subsection "sequences-access" }
 { $subsection "sequences-combinators" }
@@ -1612,6 +1613,10 @@ $nl
 { $subsection "binary-search" }
 { $subsection "sets" }
 { $subsection "sequences-trimming" }
+{ $subsection "sequences.deep" }
+"Using sequences for looping:"
+{ $subsection "sequences-integers" }
+{ $subsection "math.ranges" }
 "For inner loops:"
 { $subsection "sequences-unsafe" } ;
 
index dbbf49ef36f022ed2381651efb6fdeee590b0bc6..da495f410fb62ae0a23adf304553a330b1e472dc 100644 (file)
@@ -13,6 +13,10 @@ IN: sequences.tests
 [ V{ 4 5 } ] [ { 1 2 3 4 5 } 2 tail-slice* >vector ] unit-test
 [ V{ 3 4 } ] [ 2 4 1 10 dup <slice> subseq >vector ] unit-test
 [ V{ 3 4 } ] [ 0 2 2 4 1 10 dup <slice> <slice> subseq >vector ] unit-test
+[ 0 10 "hello" <slice> ] must-fail
+[ -10 3 "hello" <slice> ] must-fail
+[ 2 1 "hello" <slice> ] must-fail
+
 [ "cba" ] [ "abcdef" 3 head-slice reverse ] unit-test
 
 [ 5040 ] [ [ 1 2 3 4 5 6 7 ] 1 [ * ] reduce ] unit-test
index c5ff787768b4dd97913b9104b29139d55b9c592b..564309a6fb5c4e9aed549a92ac5c3df17f297eaa 100755 (executable)
@@ -176,7 +176,7 @@ PRIVATE>
     3 swap bounds-check nip first4-unsafe ; flushable
 
 : ?nth ( n seq -- elt/f )
-    2dup bounds-check? [ nth-unsafe ] [ 2drop f ] if ; flushable
+    2dup bounds-check? [ nth-unsafe ] [ 2drop f ] if ; inline
 
 MIXIN: virtual-sequence
 GENERIC: virtual-seq ( seq -- seq' )
@@ -221,8 +221,9 @@ TUPLE: slice-error from to seq reason ;
 : check-slice ( from to seq -- from to seq )
     3dup
     [ 2drop 0 < "start < 0" slice-error ]
-    [ nip length > "end > sequence" slice-error ]
-    [ drop > "start > end" slice-error ] 3tri ; inline
+    [ [ drop ] 2dip length > "end > sequence" slice-error ]
+    [ drop > "start > end" slice-error ]
+    3tri ; inline
 
 : <slice> ( from to seq -- slice )
     dup slice? [ collapse-slice ] when
@@ -505,7 +506,7 @@ PRIVATE>
     [ [ 0 = ] 2dip if ] 2curry
     each-index ; inline
 
-: map-index ( seq quot -- )
+: map-index ( seq quot -- newseq )
     prepare-index 2map ; inline
 
 : reduce-index ( seq identity quot -- )
index 840fe628e0a52dbba67707b277bb459a1ce467ac..1e5f9bf1ddbf4e7fcc4e4547724c7f4817be690e 100644 (file)
@@ -83,7 +83,7 @@ $nl
 "A word can be used to check if a class has an initial value or not:"
 { $subsection initial-value } ;
 
-ARTICLE: "slots" "Slots"
+ARTICLE: "slots" "Low-level slot operations"
 "The " { $vocab-link "slots" } " vocabulary contains words for introspecting the slots of an object. A " { $emphasis "slot" } " is a component of an object which can store a value."
 $nl
 { $link "tuples" } " are composed entirely of slots, and instances of " { $link "builtin-classes" } " consist of slots together with intrinsic data."
@@ -104,6 +104,9 @@ $nl
 { $subsection define-changer }
 { $subsection define-slot-methods }
 { $subsection define-accessors }
+"Unsafe slot access:"
+{ $subsection slot }
+{ $subsection set-slot }
 { $see-also "accessors" "mirrors" } ;
 
 ABOUT: "slots"
index 71c2bdcc900b6848cd44fbfe1e43dbbce0d0d75a..a353f5094736da78b96f07ec3cdd928870bbb0c8 100755 (executable)
@@ -21,7 +21,7 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
         object bootstrap-word >>class ;
 
 : define-typecheck ( class generic quot props -- )
-    [ dup define-simple-generic create-method ] 2dip
+    [ create-method ] 2dip
     [ [ props>> ] [ drop ] [ ] tri* update ]
     [ drop define ]
     3bi ;
@@ -36,7 +36,6 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
 
 : reader-word ( name -- word )
     ">>" append "accessors" create
-    dup (( object -- value )) "declared-effect" set-word-prop
     dup t "reader" set-word-prop ;
 
 : reader-props ( slot-spec -- assoc )
@@ -46,13 +45,18 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
         t "flushable" set
     ] H{ } make-assoc ;
 
+: define-reader-generic ( name -- )
+    reader-word (( object -- value )) define-simple-generic ;
+
 : define-reader ( class slot-spec -- )
-    [ name>> reader-word ] [ reader-quot ] [ reader-props ] tri
-    define-typecheck ;
+    [ nip name>> define-reader-generic ]
+    [
+        [ name>> reader-word ] [ reader-quot ] [ reader-props ] tri
+        define-typecheck
+    ] 2bi ;
 
 : writer-word ( name -- word )
     "(>>" ")" surround "accessors" create
-    dup (( value object -- )) "declared-effect" set-word-prop
     dup t "writer" set-word-prop ;
 
 ERROR: bad-slot-value value class ;
@@ -92,9 +96,14 @@ ERROR: bad-slot-value value class ;
 : writer-props ( slot-spec -- assoc )
     "writing" associate ;
 
+: define-writer-generic ( name -- )
+    writer-word (( value object -- )) define-simple-generic ;
+
 : define-writer ( class slot-spec -- )
-    [ name>> writer-word ] [ writer-quot ] [ writer-props ] tri
-    define-typecheck ;
+    [ nip name>> define-writer-generic ] [
+        [ name>> writer-word ] [ writer-quot ] [ writer-props ] tri
+        define-typecheck
+    ] 2bi ;
 
 : setter-word ( name -- word )
     ">>" prepend "accessors" create ;
@@ -134,8 +143,8 @@ ERROR: bad-slot-value value class ;
 
 : define-protocol-slot ( name -- )
     {
-        [ reader-word define-simple-generic ]
-        [ writer-word define-simple-generic ]
+        [ define-reader-generic ]
+        [ define-writer-generic ]
         [ define-setter ]
         [ define-changer ]
     } cleave ;
index 8c9d0b555794faa169b47962953c0db2e1bf2343..c6e58f659a5bd6e1d53d908d1135fd32590de84e 100644 (file)
@@ -29,7 +29,7 @@ name>char-hook [
 : unicode-escape ( str -- ch str' )
     "{" ?head-slice [
         CHAR: } over index cut-slice
-        [ >string name>char-hook get call ] dip
+        [ >string name>char-hook get call( name -- char ) ] dip
         rest-slice
     ] [
         6 cut-slice [ hex> ] dip
@@ -45,10 +45,10 @@ name>char-hook [
 : (parse-string) ( str -- m )
     dup [ "\"\\" member? ] find dup [
         [ cut-slice [ % ] dip rest-slice ] dip
-        dup CHAR: " = [
-            drop from>>
+        CHAR: " = [
+            from>>
         ] [
-            drop next-escape [ , ] dip (parse-string)
+            next-escape [ , ] dip (parse-string)
         ] if
     ] [
         "Unterminated string" throw
@@ -59,8 +59,8 @@ name>char-hook [
         [ swap tail-slice (parse-string) ] "" make swap
     ] change-lexer-column ;
 
-: (unescape-string) ( str -- str' )
-    dup [ CHAR: \\ = ] find [
+: (unescape-string) ( str -- )
+    CHAR: \\ over index dup [
         cut-slice [ % ] dip rest-slice
         next-escape [ , ] dip
         (unescape-string)
index c5ca2b129f7f1befe266373d39b2af35fd9cc3a9..22e8bfcb62a5361af6dc81b36255e389afeaa186 100644 (file)
@@ -1,6 +1,6 @@
 USING: arrays byte-arrays help.markup help.syntax
 kernel kernel.private strings.private sequences vectors
-sbufs math tools.vocabs.browser ;
+sbufs math help.vocabs ;
 IN: strings
 
 ARTICLE: "strings" "Strings"
@@ -26,17 +26,17 @@ ABOUT: "strings"
 HELP: string
 { $description "The class of fixed-length character strings. See " { $link "syntax-strings" } " for syntax and " { $link "strings" } " for general information." } ;
 
-HELP: string-nth ( n string -- ch )
+HELP: string-nth
 { $values { "n" fixnum } { "string" string } { "ch" "the character at the " { $snippet "n" } "th index" } }
 { $description "Unsafe string accessor, used to define " { $link nth } " on strings." }
 { $warning "This word is in the " { $vocab-link "strings.private" } " vocabulary because it does not perform type or bounds checking. User code should call " { $link nth } " instead." } ;
 
-HELP: set-string-nth ( ch n string -- )
+HELP: set-string-nth
 { $values { "ch" "a character" } { "n" fixnum } { "string" string }  }
 { $description "Unsafe string mutator, used to define " { $link set-nth } " on strings." }
 { $warning "This word is in the " { $vocab-link "strings.private" } " vocabulary because it does not perform type or bounds checking. User code should call " { $link set-nth } " instead." } ;
 
-HELP: <string> ( n ch -- string )
+HELP: <string>
 { $values { "n" "a positive integer specifying string length" } { "ch" "an initial character" } { "string" string } }
 { $description "Creates a new string with the given length and all characters initially set to " { $snippet "ch" } "." } ;
 
index 7e4c80d4aeb2198681819be450310fbc6609313e..ffcefab78be4604309064e86112f9f9848b6f51f 100644 (file)
@@ -17,7 +17,7 @@ IN: strings
 : rehash-string ( str -- )
     1 over sequence-hashcode swap set-string-hashcode ; inline
 
-: set-string-nth ( ch n str -- )
+: set-string-nth ( ch n string -- )
     pick HEX: 7f fixnum<=
     [ set-string-nth-fast ] [ set-string-nth-slow ] if ; inline
 
index 25b963c574331bd53b05c661ffbdbeef96bde2d5..bb8791df97ef4ed319834be8823bf092097764f6 100644 (file)
@@ -167,6 +167,8 @@ $nl
 ARTICLE: "syntax" "Syntax"
 "Factor has two main forms of syntax: " { $emphasis "definition" } " syntax and " { $emphasis "literal" } " syntax. Code is data, so the syntax for code is a special case of object literal syntax. This section documents literal syntax. Definition syntax is covered in " { $link "words" } ". Extending the parser is the main topic of " { $link "parser" } "."
 { $subsection "parser-algorithm" }
+{ $subsection "vocabulary-search" }
+{ $subsection "top-level-forms" }
 { $subsection "syntax-comments" }
 { $subsection "syntax-literals" }
 { $subsection "syntax-immediate" } ;
@@ -177,10 +179,10 @@ HELP: delimiter
 { $syntax ": foo ... ; delimiter" }
 { $description "Declares the most recently defined word as a delimiter. Delimiters are words which are only ever valid as the end of a nested block to be read by " { $link parse-until } ". An unpaired occurrence of a delimiter is a parse error." } ;
 
-HELP: parsing
-{ $syntax ": foo ... ; parsing" }
-{ $description "Declares the most recently defined word as a parsing word." }
-{ $examples "In the below example, the " { $snippet "world" } " word is never called, however its body references a parsing word which executes immediately:" { $example "USE: io" "IN: scratchpad" "<< : hello \"Hello parser!\" print ; parsing >>\n: world hello ;" "Hello parser!" } } ;
+HELP: SYNTAX:
+{ $syntax "SYNTAX: foo ... ;" }
+{ $description "Defines a parsing word." }
+{ $examples "In the below example, the " { $snippet "world" } " word is never called, however its body references a parsing word which executes immediately:" { $example "USE: io" "IN: scratchpad" "<< SYNTAX: HELLO \"Hello parser!\" print ; >>\n: world ( -- ) HELLO ;" "Hello parser!" } } ;
 
 HELP: inline
 { $syntax ": foo ... ; inline" }
@@ -508,8 +510,8 @@ HELP: P"
 HELP: (
 { $syntax "( inputs -- outputs )" }
 { $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
-{ $description "Declares the stack effect of the most recently defined word, storing a new " { $link effect } " instance in the " { $snippet "\"declared-effect\"" } " word property." }
-{ $notes "All words except those only pushing literals on the stack must have a stack effect declaration. See " { $link "effect-declaration" } " for details." } ;
+{ $description "A stack effect declaration. This is treated as a comment unless it appears inside a word definition." }
+{ $see-also "effect-declaration" } ;
 
 HELP: ((
 { $syntax "(( inputs -- outputs ))" }
@@ -556,18 +558,18 @@ HELP: BIN:
 { $examples { $example "USE: prettyprint" "BIN: 100 ." "4" } } ;
 
 HELP: GENERIC:
-{ $syntax "GENERIC: word" "GENERIC: word ( stack -- effect )" }
+{ $syntax "GENERIC: word ( stack -- effect )" }
 { $values { "word" "a new word to define" } }
 { $description "Defines a new generic word in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." } ;
 
 HELP: GENERIC#
-{ $syntax "GENERIC# word n" "GENERIC# word n ( stack -- effect )" }
+{ $syntax "GENERIC# word n ( stack -- effect )" }
 { $values { "word" "a new word to define" } { "n" "the stack position to dispatch on" } }
 { $description "Defines a new generic word which dispatches on the " { $snippet "n" } "th most element from the top of the stack in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." }
 { $notes
     "The following two definitions are equivalent:"
-    { $code "GENERIC: foo" }
-    { $code "GENERIC# foo 0" }
+    { $code "GENERIC: foo ( obj -- )" }
+    { $code "GENERIC# foo 0 ( obj -- )" }
 } ;
 
 HELP: MATH:
@@ -576,7 +578,7 @@ HELP: MATH:
 { $description "Defines a new generic word which uses the " { $link math-combination } " method combination." } ;
 
 HELP: HOOK:
-{ $syntax "HOOK: word variable" "HOOK: word variable ( stack -- effect ) " }
+{ $syntax "HOOK: word variable ( stack -- effect ) " }
 { $values { "word" "a new word to define" } { "variable" word } }
 { $description "Defines a new hook word in the current vocabulary. Hook words are generic words which dispatch on the value of a variable, so methods are defined with " { $link POSTPONE: M: } ". Hook words differ from other generic words in that the dispatch value is removed from the stack before the chosen method is called." }
 { $examples
@@ -762,7 +764,9 @@ HELP: >>
 { $description "Marks the end of a parse time code block." } ;
 
 HELP: call-next-method
+{ $syntax "call-next-method" }
 { $description "Calls the next applicable method. Only valid inside a method definition. The values at the top of the stack are passed on to the next method, and they must be compatible with that method's class specializer." }
+{ $notes "This word looks like an ordinary word but it is a parsing word. It cannot be factored out of a method definition, since the code expansion references the current method object directly." }
 { $errors
     "Throws a " { $link no-next-method } " error if this is the least specific method, and throws an " { $link inconsistent-next-method } " error if the values at the top of the stack are not compatible with the current method's specializer."
 } ;
@@ -770,3 +774,13 @@ HELP: call-next-method
 { POSTPONE: call-next-method (call-next-method) next-method } related-words
 
 { POSTPONE: << POSTPONE: >> } related-words
+
+HELP: call(
+{ $syntax "call( stack -- effect )" }
+{ $description "Calls the quotation on the top of the stack, asserting that it has the given stack effect. The quotation does not need to be known at compile time." } ;
+
+HELP: execute(
+{ $syntax "execute( stack -- effect )" }
+{ $description "Calls the word on the top of the stack, asserting that it has the given stack effect. The word does not need to be known at compile time." } ;
+
+{ POSTPONE: call( POSTPONE: execute( } related-words
\ No newline at end of file
index de3be98ceb28b201dd729e67daa1fc357561dcbc..2e072f72d823d867ef423adb92ea04b722f360b8 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien arrays byte-arrays definitions generic
 hashtables kernel math namespaces parser lexer sequences strings
@@ -22,217 +22,217 @@ IN: bootstrap.syntax
 : define-delimiter ( name -- )
     "syntax" lookup t "delimiter" set-word-prop ;
 
-: define-syntax ( name quot -- )
-    [ dup "syntax" lookup [ dup ] [ no-word-error ] ?if ] dip
-    define make-parsing ;
+: define-core-syntax ( name quot -- )
+    [ dup "syntax" lookup [ ] [ no-word-error ] ?if ] dip
+    define-syntax ;
 
 [
     { "]" "}" ";" ">>" } [ define-delimiter ] each
 
     "PRIMITIVE:" [
         "Primitive definition is not supported" throw
-    ] define-syntax
+    ] define-core-syntax
 
     "CS{" [
         "Call stack literals are not supported" throw
-    ] define-syntax
+    ] define-core-syntax
 
-    "!" [ lexer get next-line ] define-syntax
+    "!" [ lexer get next-line ] define-core-syntax
 
-    "#!" [ POSTPONE: ! ] define-syntax
+    "#!" [ POSTPONE: ! ] define-core-syntax
 
-    "IN:" [ scan set-in ] define-syntax
+    "IN:" [ scan set-in ] define-core-syntax
 
-    "PRIVATE>" [ in get ".private" ?tail drop set-in ] define-syntax
+    "PRIVATE>" [ in get ".private" ?tail drop set-in ] define-core-syntax
 
     "<PRIVATE" [
         POSTPONE: PRIVATE> in get ".private" append set-in
-    ] define-syntax
+    ] define-core-syntax
 
-    "USE:" [ scan use+ ] define-syntax
+    "USE:" [ scan use+ ] define-core-syntax
 
-    "USING:" [ ";" parse-tokens add-use ] define-syntax
+    "USING:" [ ";" parse-tokens add-use ] define-core-syntax
 
-    "QUALIFIED:" [ scan dup add-qualified ] define-syntax
+    "QUALIFIED:" [ scan dup add-qualified ] define-core-syntax
 
-    "QUALIFIED-WITH:" [ scan scan add-qualified ] define-syntax
+    "QUALIFIED-WITH:" [ scan scan add-qualified ] define-core-syntax
 
     "FROM:" [
         scan "=>" expect ";" parse-tokens swap add-words-from
-    ] define-syntax
+    ] define-core-syntax
 
     "EXCLUDE:" [
         scan "=>" expect ";" parse-tokens swap add-words-excluding
-    ] define-syntax
+    ] define-core-syntax
 
     "RENAME:" [
         scan scan "=>" expect scan add-renamed-word
-    ] define-syntax
+    ] define-core-syntax
 
-    "HEX:" [ 16 parse-base ] define-syntax
-    "OCT:" [ 8 parse-base ] define-syntax
-    "BIN:" [ 2 parse-base ] define-syntax
+    "HEX:" [ 16 parse-base ] define-core-syntax
+    "OCT:" [ 8 parse-base ] define-core-syntax
+    "BIN:" [ 2 parse-base ] define-core-syntax
 
-    "f" [ f parsed ] define-syntax
+    "f" [ f parsed ] define-core-syntax
     "t" "syntax" lookup define-singleton-class
 
     "CHAR:" [
         scan {
             { [ dup length 1 = ] [ first ] }
             { [ "\\" ?head ] [ next-escape >string "" assert= ] }
-            [ name>char-hook get call ]
+            [ name>char-hook get call( name -- char ) ]
         } cond parsed
-    ] define-syntax
+    ] define-core-syntax
 
-    "\"" [ parse-string parsed ] define-syntax
+    "\"" [ parse-string parsed ] define-core-syntax
 
     "SBUF\"" [
         lexer get skip-blank parse-string >sbuf parsed
-    ] define-syntax
+    ] define-core-syntax
 
     "P\"" [
         lexer get skip-blank parse-string <pathname> parsed
-    ] define-syntax
-
-    "[" [ parse-quotation parsed ] define-syntax
-    "{" [ \ } [ >array ] parse-literal ] define-syntax
-    "V{" [ \ } [ >vector ] parse-literal ] define-syntax
-    "B{" [ \ } [ >byte-array ] parse-literal ] define-syntax
-    "H{" [ \ } [ >hashtable ] parse-literal ] define-syntax
-    "T{" [ parse-tuple-literal parsed ] define-syntax
-    "W{" [ \ } [ first <wrapper> ] parse-literal ] define-syntax
-
-    "POSTPONE:" [ scan-word parsed ] define-syntax
-    "\\" [ scan-word <wrapper> parsed ] define-syntax
-    "inline" [ word make-inline ] define-syntax
-    "recursive" [ word make-recursive ] define-syntax
-    "foldable" [ word make-foldable ] define-syntax
-    "flushable" [ word make-flushable ] define-syntax
-    "delimiter" [ word t "delimiter" set-word-prop ] define-syntax
-    "parsing" [ word make-parsing ] define-syntax
+    ] define-core-syntax
+
+    "[" [ parse-quotation parsed ] define-core-syntax
+    "{" [ \ } [ >array ] parse-literal ] define-core-syntax
+    "V{" [ \ } [ >vector ] parse-literal ] define-core-syntax
+    "B{" [ \ } [ >byte-array ] parse-literal ] define-core-syntax
+    "H{" [ \ } [ >hashtable ] parse-literal ] define-core-syntax
+    "T{" [ parse-tuple-literal parsed ] define-core-syntax
+    "W{" [ \ } [ first <wrapper> ] parse-literal ] define-core-syntax
+
+    "POSTPONE:" [ scan-word parsed ] define-core-syntax
+    "\\" [ scan-word <wrapper> parsed ] define-core-syntax
+    "M\\" [ scan-word scan-word method <wrapper> parsed ] define-core-syntax
+    "inline" [ word make-inline ] define-core-syntax
+    "recursive" [ word make-recursive ] define-core-syntax
+    "foldable" [ word make-foldable ] define-core-syntax
+    "flushable" [ word make-flushable ] define-core-syntax
+    "delimiter" [ word t "delimiter" set-word-prop ] define-core-syntax
+
+    "SYNTAX:" [
+        CREATE-WORD parse-definition define-syntax
+    ] define-core-syntax
 
     "SYMBOL:" [
         CREATE-WORD define-symbol
-    ] define-syntax
+    ] define-core-syntax
 
     "SYMBOLS:" [
         ";" parse-tokens
         [ create-in dup reset-generic define-symbol ] each
-    ] define-syntax
+    ] define-core-syntax
 
     "SINGLETONS:" [
         ";" parse-tokens
         [ create-class-in define-singleton-class ] each
-    ] define-syntax
+    ] define-core-syntax
+
+    "DEFER:" [
+        scan current-vocab create
+        [ fake-definition ] [ set-word ] [ [ undefined ] define ] tri
+    ] define-core-syntax
     
     "ALIAS:" [
         CREATE-WORD scan-word define-alias
-    ] define-syntax
+    ] define-core-syntax
 
     "CONSTANT:" [
-        CREATE scan-object define-constant
-    ] define-syntax
-
-    "DEFER:" [
-        scan current-vocab create
-        [ fake-definition ] [ set-word ] [ [ undefined ] define ] tri
-    ] define-syntax
+        CREATE-WORD scan-object define-constant
+    ] define-core-syntax
 
     ":" [
-        (:) define
-    ] define-syntax
+        (:) define-declared
+    ] define-core-syntax
 
     "GENERIC:" [
-        CREATE-GENERIC define-simple-generic
-    ] define-syntax
+        [ simple-combination ] (GENERIC:)
+    ] define-core-syntax
 
     "GENERIC#" [
-        CREATE-GENERIC
-        scan-word <standard-combination> define-generic
-    ] define-syntax
+        [ scan-word <standard-combination> ] (GENERIC:)
+    ] define-core-syntax
 
     "MATH:" [
-        CREATE-GENERIC
-        T{ math-combination } define-generic
-    ] define-syntax
+        [ math-combination ] (GENERIC:)
+    ] define-core-syntax
 
     "HOOK:" [
-        CREATE-GENERIC scan-word
-        <hook-combination> define-generic
-    ] define-syntax
+        [ scan-word <hook-combination> ] (GENERIC:)
+    ] define-core-syntax
 
     "M:" [
         (M:) define
-    ] define-syntax
+    ] define-core-syntax
 
     "UNION:" [
         CREATE-CLASS parse-definition define-union-class
-    ] define-syntax
+    ] define-core-syntax
 
     "INTERSECTION:" [
         CREATE-CLASS parse-definition define-intersection-class
-    ] define-syntax
+    ] define-core-syntax
 
     "MIXIN:" [
         CREATE-CLASS define-mixin-class
-    ] define-syntax
+    ] define-core-syntax
 
     "INSTANCE:" [
         location [
             scan-word scan-word 2dup add-mixin-instance
             <mixin-instance>
         ] dip remember-definition
-    ] define-syntax
+    ] define-core-syntax
 
     "PREDICATE:" [
         CREATE-CLASS
         scan "<" assert=
         scan-word
         parse-definition define-predicate-class
-    ] define-syntax
+    ] define-core-syntax
 
     "SINGLETON:" [
         CREATE-CLASS define-singleton-class
-    ] define-syntax
+    ] define-core-syntax
 
     "TUPLE:" [
         parse-tuple-definition define-tuple-class
-    ] define-syntax
+    ] define-core-syntax
 
     "SLOT:" [
         scan define-protocol-slot
-    ] define-syntax
+    ] define-core-syntax
 
     "C:" [
         CREATE-WORD scan-word define-boa-word
-    ] define-syntax
+    ] define-core-syntax
 
     "ERROR:" [
         parse-tuple-definition
         pick save-location
         define-error-class
-    ] define-syntax
+    ] define-core-syntax
 
     "FORGET:" [
         scan-object forget
-    ] define-syntax
+    ] define-core-syntax
 
     "(" [
-        ")" parse-effect
-        word dup [ set-stack-effect ] [ 2drop ] if
-    ] define-syntax
+        ")" parse-effect drop
+    ] define-core-syntax
 
     "((" [
         "))" parse-effect parsed
-    ] define-syntax
+    ] define-core-syntax
 
-    "MAIN:" [ scan-word in get vocab (>>main) ] define-syntax
+    "MAIN:" [ scan-word in get vocab (>>main) ] define-core-syntax
 
     "<<" [
         [
             \ >> parse-until >quotation
-        ] with-nested-compilation-unit call
-    ] define-syntax
+        ] with-nested-compilation-unit call( -- )
+    ] define-core-syntax
 
     "call-next-method" [
         current-method get [
@@ -241,9 +241,13 @@ IN: bootstrap.syntax
         ] [
             not-in-a-method-error
         ] if*
-    ] define-syntax
+    ] define-core-syntax
     
     "initial:" "syntax" lookup define-symbol
     
     "read-only" "syntax" lookup define-symbol
+
+    "call(" [ \ call-effect parse-call( ] define-core-syntax
+
+    "execute(" [ \ execute-effect parse-call( ] define-core-syntax
 ] with-compilation-unit
index 527da053fbbaf0b91dab00f61afcd58e252d8ce9..e0d6fd44931ed4ca3c410aba0895b2f4c0c95298 100644 (file)
@@ -56,6 +56,7 @@ $nl
 "Application vocabularies can define a main entry point, giving the user a convenient way to run the application:"
 { $subsection POSTPONE: MAIN: }
 { $subsection run }
+{ $subsection runnable-vocab }
 { $see-also "vocabularies" "parser-files" "source-files" } ;
 
 ABOUT: "vocabs.loader"
index cb4a0b50aa9c78f176f162ce25705ced54d78911..87531caee4c5107c65e24e6020960e404127dd01 100644 (file)
@@ -27,20 +27,18 @@ combinators vocabs.parser grouping ;
 
 IN: vocabs.loader.test.2
 
-: hello 3 ;
+: hello ( -- ) ;
 
 MAIN: hello
 
 IN: vocabs.loader.tests
 
-[ { 3 3 3 } ] [
+[ ] [
     "vocabs.loader.test.2" run
     "vocabs.loader.test.2" vocab run
     "vocabs.loader.test.2" <vocab-link> run
-    3array
 ] unit-test
 
-
 [
     "resource:core/vocabs/loader/test/a/a.factor" forget-source
     "vocabs.loader.test.a" forget-vocab
@@ -134,7 +132,7 @@ IN: vocabs.loader.tests
     "vocabs.loader.test.d" vocab source-loaded?>>
 ] unit-test
 
-: forget-junk
+: forget-junk ( -- )
     [
         { "2" "a" "b" "d" "e" "f" }
         [
index 00c4df92a63ab88e07a07c9cc24a60920691cb89..4f9005e11061fed8915062e79b77c3d838be274f 100644 (file)
@@ -64,7 +64,7 @@ SYMBOL: load-help?
         +parsing+ >>source-loaded?
         dup vocab-source-path [ parse-file ] [ [ ] ] if*
         [ +parsing+ >>source-loaded? ] dip
-        [ % ] [ assert-depth ] if-bootstrapping
+        [ % ] [ call( -- ) ] if-bootstrapping
         +done+ >>source-loaded? drop
     ] [ ] [ f >>source-loaded? ] cleanup ;
 
@@ -90,7 +90,7 @@ PRIVATE>
 
 : run ( vocab -- )
     dup load-vocab vocab-main [
-        execute
+        execute( -- )
     ] [
         "The " write vocab-name write
         " vocabulary does not define an entry point." print
index e4f1c02a3a0ef767f3fad96e2d0ac49d7b2c82ab..a07695f1c3691009144180636a32203b35715181 100644 (file)
@@ -1,3 +1,3 @@
 IN: vocabs.loader.test.d
 
-: foo iterate-next ;
\ No newline at end of file
+: foo ( -- ) iterate-next ;
\ No newline at end of file
index 35feae34bbddfc73525836ac15bcf7a9c2c0d63f..e8783c0dbe1655fcadf5d7a141659fbd8ee0a87b 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2007, 2008 Daniel Ehrenberg, Bruno Deferrari,
+! Copyright (C) 2007, 2009 Daniel Ehrenberg, Bruno Deferrari,
 ! Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs hashtables kernel namespaces sequences
@@ -56,4 +56,4 @@ SYMBOL: in
     dup string? [ "Vocabulary name must be a string" throw ] unless ;
 
 : set-in ( name -- )
-    check-vocab-string dup in set create-vocab (use+) ;
+    check-vocab-string dup in set create-vocab (use+) ;
\ No newline at end of file
index 2929b5008180fd1d1f1386b7394eea41911566b9..2c87d9736a1533b393382828ed405f0c7dda3b42 100644 (file)
@@ -96,3 +96,6 @@ $nl
 HELP: >vocab-link
 { $values { "name" string } { "vocab" "a vocabulary specifier" } }
 { $description "If the vocabulary is loaded, outputs the corresponding " { $link vocab } " instance, otherwise creates a new " { $link vocab-link } "." } ;
+
+HELP: runnable-vocab
+{ $class-description "The class of vocabularies with a " { $slot "main" } " word." } ;
\ No newline at end of file
index 977eac2b35950846616337b3e498324813484a50..2b978e866625c101e51be13c2122119d6d1dd26f 100644 (file)
@@ -105,4 +105,9 @@ M: vocab-spec forget* forget-vocab ;
 
 SYMBOL: load-vocab-hook ! ( name -- vocab )
 
-: load-vocab ( name -- vocab ) load-vocab-hook get call ;
\ No newline at end of file
+: load-vocab ( name -- vocab ) load-vocab-hook get call( name -- vocab ) ;
+
+PREDICATE: runnable-vocab < vocab
+    vocab-main >boolean ;
+
+INSTANCE: vocab-spec definition
\ No newline at end of file
diff --git a/core/words/alias/alias-tests.factor b/core/words/alias/alias-tests.factor
new file mode 100644 (file)
index 0000000..0278a4d
--- /dev/null
@@ -0,0 +1,6 @@
+USING: math eval tools.test effects ;
+IN: words.alias.tests
+
+ALIAS: foo +
+[ ] [ "IN: words.alias.tests CONSTANT: foo 5" eval ] unit-test
+[ (( -- value )) ] [ \ foo stack-effect ] unit-test
\ No newline at end of file
index 0615e8333e570ec828f1cae969fe1c1864cc537a..73e270dffcf00484c60d5e1b36ff4e69c83a5073 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: quotations effects accessors sequences words kernel ;
+USING: quotations effects accessors sequences words kernel definitions ;
 IN: words.alias
 
 PREDICATE: alias < word "alias" word-prop ;
@@ -12,5 +12,6 @@ PREDICATE: alias < word "alias" word-prop ;
 M: alias reset-word
     [ call-next-method ] [ f "alias" set-word-prop ] bi ;
 
-M: alias stack-effect
-    def>> first stack-effect ;
+M: alias definer drop \ ALIAS: f ;
+
+M: alias definition def>> first 1quotation ;
\ No newline at end of file
diff --git a/core/words/constant/constant-tests.factor b/core/words/constant/constant-tests.factor
new file mode 100644 (file)
index 0000000..721846b
--- /dev/null
@@ -0,0 +1,20 @@
+IN: words.constant.tests
+USING: tools.test math words.constant ;
+
+CONSTANT: a +
+
+[ + ] [ a ] unit-test
+
+[ t ] [ \ a constant? ] unit-test
+
+CONSTANT: b \ +
+
+[ \ + ] [ b ] unit-test
+
+CONSTANT: c { 1 2 3 }
+
+[ { 1 2 3 } ] [ c ] unit-test
+
+SYMBOL: foo
+
+[ f ] [ \ foo constant? ] unit-test
\ No newline at end of file
index 43b7f37599c50d11f82ee891cf7e148cd35a591c..b518760bf980ded0d0fb3c6c8186c35f161a3c98 100644 (file)
@@ -1,10 +1,17 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel sequences words ;
+USING: accessors kernel sequences words definitions quotations ;
 IN: words.constant
 
-PREDICATE: constant < word ( obj -- ? )
-    def>> dup length 1 = [ first word? not ] [ drop f ] if ;
+PREDICATE: constant < word "constant" word-prop >boolean ;
 
 : define-constant ( word value -- )
-    [ ] curry (( -- value )) define-inline ;
+    [ "constant" set-word-prop ]
+    [ [ ] curry (( -- value )) define-inline ] 2bi ;
+
+M: constant reset-word
+    [ call-next-method ] [ f "constant" set-word-prop ] bi ;
+
+M: constant definer drop \ CONSTANT: f ;
+
+M: constant definition "constant" word-prop literalize 1quotation ;
\ No newline at end of file
index a107808eec35073761310c47a1e968cba061bf79..34ec6b9174f41f3d6e041024e9a1a9f18ed42721 100644 (file)
@@ -1,10 +1,9 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences accessors definitions
-words words.constant ;
+USING: kernel sequences accessors definitions words ;
 IN: words.symbol
 
-PREDICATE: symbol < constant ( obj -- ? )
+PREDICATE: symbol < word ( obj -- ? )
     [ def>> ] [ [ ] curry ] bi sequence= ;
 
 M: symbol definer drop \ SYMBOL: f ;
@@ -12,4 +11,4 @@ M: symbol definer drop \ SYMBOL: f ;
 M: symbol definition drop f ;
 
 : define-symbol ( word -- )
-    dup define-constant ;
+    dup [ ] curry (( -- value )) define-inline ;
index 9c32a8094e8340dddc53261e5cb46a5e81f0edf3..1ad6928acbab2e0c8319df57d765bd15328a0ee6 100644 (file)
@@ -57,16 +57,12 @@ $nl
 } ;
 
 ARTICLE: "declarations" "Declarations"
-"Declarations give special behavior to a word. Declarations are parsing words that set a word property in the most recently defined word."
-$nl
-"The first declaration specifies the time when a word runs. It affects both the non-optimizing and optimizing compilers:"
-{ $subsection POSTPONE: parsing }
-"The remaining declarations only affect definitions compiled with the optimizing compiler. They do not change evaluation semantics of a word, but instead declare that the word follows a certain contract, and thus may be compiled differently."
-{ $warning "If a generic word is declared " { $link POSTPONE: foldable } " or " { $link POSTPONE: flushable } ", all methods must satisfy the contract, otherwise unpredicable behavior will occur." }
+"Declarations are parsing words that set a word property in the most recently defined word. Declarations only affect definitions compiled with the optimizing compiler. They do not change evaluation semantics of a word, but instead declare that the word follows a certain contract, and thus may be compiled differently."
 { $subsection POSTPONE: inline }
 { $subsection POSTPONE: foldable }
 { $subsection POSTPONE: flushable }
 { $subsection POSTPONE: recursive }
+{ $warning "If a generic word is declared " { $link POSTPONE: foldable } " or " { $link POSTPONE: flushable } ", all methods must satisfy the contract, otherwise unpredicable behavior will occur." }
 "Stack effect declarations are documented in " { $link "effect-declaration" } "." ;
 
 ARTICLE: "word-definition" "Defining words"
@@ -169,7 +165,7 @@ HELP: execute ( word -- )
 { $values { "word" word } }
 { $description "Executes a word." }
 { $examples
-    { $example "USING: kernel io words ;" "IN: scratchpad" ": twice dup execute execute ;\n: hello \"Hello\" print ;\n\\ hello twice" "Hello\nHello" }
+    { $example "USING: kernel io words ;" "IN: scratchpad" ": twice ( word -- ) dup execute execute ;\n: hello ( -- ) \"Hello\" print ;\n\\ hello twice" "Hello\nHello" }
 } ;
 
 HELP: deferred
@@ -277,9 +273,9 @@ HELP: bootstrap-word
 { $values { "word" word } { "target" word } }
 { $description "Looks up a word with the same name and vocabulary as the given word, performing a transformation to handle parsing words in the target dictionary. Used during bootstrap to transfer host words to the target dictionary." } ;
 
-HELP: parsing-word? ( obj -- ? )
-{ $values { "obj" object } { "?" "a boolean" } }
-{ $description "Tests if an object is a parsing word declared by " { $link POSTPONE: parsing } "." }
+HELP: parsing-word?
+{ $values { "object" object } { "?" "a boolean" } }
+{ $description "Tests if an object is a parsing word declared by " { $link POSTPONE: SYNTAX: } "." }
 { $notes "Outputs " { $link f } " if the object is not a word." } ;
 
 HELP: define-declared
index a22b6a5b976d7328ab89de7d51f7edd83a3ba6dd..305541119b692d8e8845f14020b261ec69cd791d 100755 (executable)
@@ -50,23 +50,23 @@ SYMBOL: a-symbol
 
 ! See if redefining a generic as a colon def clears some
 ! word props.
-GENERIC: testing
-"IN: words.tests : testing ;" eval
+GENERIC: testing ( a -- b )
+"IN: words.tests : testing ( -- ) ;" eval
 
 [ f ] [ \ testing generic? ] unit-test
 
-: forgotten ;
-: another-forgotten ;
+: forgotten ( -- ) ;
+: another-forgotten ( -- ) ;
 
 FORGET: forgotten
 
 FORGET: another-forgotten
-: another-forgotten ;
+: another-forgotten ( -- ) ;
 
 ! I forgot remove-crossref calls!
-: fee ;
-: foe fee ;
-: fie foe ;
+: fee ( -- ) ;
+: foe ( -- ) fee ;
+: fie ( -- ) foe ;
 
 [ t ] [ \ fee usage [ word? ] filter empty? ] unit-test
 [ t ] [ \ foe usage empty? ] unit-test
@@ -97,7 +97,7 @@ DEFER: calls-a-gensym
 ! more xref buggery
 [ f ] [
     GENERIC: xyzzle ( x -- x )
-    : a ; \ a
+    : a ( -- ) ; \ a
     M: integer xyzzle a ;
     FORGET: a
     M: object xyzzle ;
@@ -106,7 +106,7 @@ DEFER: calls-a-gensym
 
 ! regression
 GENERIC: freakish ( x -- y )
-: bar freakish ;
+: bar ( x -- y ) freakish ;
 M: array freakish ;
 [ t ] [ \ bar \ freakish usage member? ] unit-test
 
@@ -116,7 +116,7 @@ DEFER: x
 [ ] [ "no-loc" "words.tests" create drop ] unit-test
 [ f ] [ "no-loc" "words.tests" lookup where ] unit-test
 
-[ ] [ "IN: words.tests : no-loc-2 ;" eval ] unit-test
+[ ] [ "IN: words.tests : no-loc-2 ( -- ) ;" eval ] unit-test
 [ f ] [ "no-loc-2" "words.tests" lookup where ] unit-test
 
 [ ] [ "IN: words.tests : test-last ( -- ) ;" eval ] unit-test
@@ -146,11 +146,11 @@ SYMBOL: quot-uses-b
     [ forget ] with-compilation-unit
 ] when*
 
-[ "IN: words.tests : undef-test ; << undef-test >>" eval ]
+[ "IN: words.tests : undef-test ( -- ) ; << undef-test >>" eval ]
 [ error>> undefined? ] must-fail-with
 
 [ ] [
-    "IN: words.tests GENERIC: symbol-generic" eval
+    "IN: words.tests GENERIC: symbol-generic ( -- )" eval
 ] unit-test
 
 [ ] [
@@ -161,7 +161,7 @@ SYMBOL: quot-uses-b
 [ f ] [ "symbol-generic" "words.tests" lookup generic? ] unit-test
 
 [ ] [
-    "IN: words.tests GENERIC: symbol-generic" <string-reader>
+    "IN: words.tests GENERIC: symbol-generic ( a -- b )" <string-reader>
     "symbol-generic-test" parse-stream drop
 ] unit-test
 
@@ -174,14 +174,14 @@ SYMBOL: quot-uses-b
 [ f ] [ "symbol-generic" "words.tests" lookup generic? ] unit-test
 
 ! Regressions
-[ ] [ "IN: words.tests : decl-forget-test ; foldable" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ; foldable" eval ] unit-test
 [ t ] [ "decl-forget-test" "words.tests" lookup "foldable" word-prop ] unit-test
-[ ] [ "IN: words.tests : decl-forget-test ;" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ;" eval ] unit-test
 [ f ] [ "decl-forget-test" "words.tests" lookup "foldable" word-prop ] unit-test
 
-[ ] [ "IN: words.tests : decl-forget-test ; flushable" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ; flushable" eval ] unit-test
 [ t ] [ "decl-forget-test" "words.tests" lookup "flushable" word-prop ] unit-test
-[ ] [ "IN: words.tests : decl-forget-test ;" eval ] unit-test
+[ ] [ "IN: words.tests : decl-forget-test ( -- ) ;" eval ] unit-test
 [ f ] [ "decl-forget-test" "words.tests" lookup "flushable" word-prop ] unit-test
 
 [ { } ]
index c27ea4fd8fbd02eedb92d6a6ce220b5f445831f3..5b230c1b0066c095ca20fce950ed3a029b46b158 100755 (executable)
@@ -1,4 +1,4 @@
-! Copyright (C) 2004, 2008 Slava Pestov.
+! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays definitions graphs assocs kernel
 kernel.private slots.private math namespaces sequences strings
@@ -10,10 +10,10 @@ IN: words
 
 : set-word ( word -- ) \ word set-global ;
 
-GENERIC: execute ( word -- )
-
 M: word execute (execute) ;
 
+M: word ?execute execute( -- value ) ;
+
 M: word <=>
     [ [ name>> ] [ vocabulary>> ] bi 2array ] compare ;
 
@@ -166,13 +166,14 @@ CONSTANT: reset-on-redefine { "inferred-effect" "cannot-infer" }
 : set-stack-effect ( effect word -- )
     2dup "declared-effect" word-prop = [ 2drop ] [
         swap
+        [ drop changed-effect ]
         [ "declared-effect" set-word-prop ]
-        [ drop dup primitive? [ dup redefined ] unless drop ] 2bi
+        [ drop dup primitive? [ drop ] [ redefined ] if ]
+        2tri
     ] if ;
 
 : define-declared ( word def effect -- )
-    pick swap "declared-effect" set-word-prop
-    define ;
+    [ nip swap set-stack-effect ] [ drop define ] 3bi ;
 
 : make-inline ( word -- )
     t "inline" set-word-prop ;
@@ -195,7 +196,7 @@ M: word reset-word
     {
         "unannotated-def" "parsing" "inline" "recursive"
         "foldable" "flushable" "reading" "writing" "reader"
-        "writer" "declared-effect" "delimiter"
+        "writer" "delimiter"
     } reset-props ;
 
 GENERIC: subwords ( word -- seq )
@@ -234,7 +235,10 @@ ERROR: bad-create name vocab ;
 
 PREDICATE: parsing-word < word "parsing" word-prop ;
 
-: make-parsing ( word -- ) t "parsing" set-word-prop ;
+M: parsing-word definer drop \ SYNTAX: \ ; ;
+
+: define-syntax ( word quot -- )
+    [ drop ] [ define ] 2bi t "parsing" set-word-prop ;
 
 : delimiter? ( obj -- ? )
     dup word? [ "delimiter" word-prop ] [ drop f ] if ;
@@ -248,7 +252,7 @@ M: word forget*
     dup "forgotten" word-prop [ drop ] [
         [ delete-xref ]
         [ [ name>> ] [ vocabulary>> vocab-words ] bi delete-at ]
-        [ [ reset-word ] [ t "forgotten" set-word-prop ] bi ]
+        [ t "forgotten" set-word-prop ]
         tri
     ] if ;
 
@@ -257,6 +261,6 @@ M: word hashcode*
 
 M: word literalize <wrapper> ;
 
-: ?word-name ( word -- name ) dup word? [ name>> ] when ;
-
 : xref-words ( -- ) all-words [ xref ] each ;
+
+INSTANCE: word definition
\ No newline at end of file
index f22ca001f47e91a10ef7c8007d1f6a498d776cc3..19928b2e0bf22d568d83eb951aa7b4f28d8d34d1 100644 (file)
@@ -57,7 +57,7 @@ DEFER: check-status
         [ dup quit? [ quit-game ] [ repeat ] if ]
     if ;
 : build-quad ( -- array ) 4 [ 10 random ] replicate >array ;
-: 24-able? ( vector -- t/f ) [ makes-24? ] with-datastack first ;
+: 24-able? ( quad -- t/f ) [ makes-24? ] with-datastack first ;
 : 24-able ( -- vector ) build-quad dup 24-able? [ drop build-quad ] unless ;
 : set-commands ( -- ) { + - * / rot swap q } commands set ;
 : play-game ( -- ) set-commands 24-able repeat ;
index 8ddbff96d9ed33a39f34f5b296132492b977ee1a..aae0b40d381b521ec920dd6df43dcf852a1dd145 100755 (executable)
@@ -17,7 +17,6 @@ colors
 colors.constants\r
 prettyprint\r
 vars\r
-call\r
 quotations\r
 io\r
 io.directories\r
@@ -37,6 +36,7 @@ ui.gadgets.panes
        ui.gadgets.buttons\r
        ui.gadgets.packs\r
        ui.gadgets.grids\r
+       ui.gadgets.corners\r
        ui.gestures\r
        ui.gadgets.scrollers\r
 splitting\r
@@ -172,7 +172,7 @@ VAR: present-space
         swap call space-ensure-solids \r
     >present-space \r
     update-model-projections \r
-    update-observer-projections ;\r
+    update-observer-projections ; inline\r
 \r
 : rotation-4D ( m -- ) \r
     '[ _ [ [ middle-of-space dup vneg ] keep \r
@@ -187,8 +187,6 @@ VAR: present-space
 ! menu\r
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r
 \r
-USE: ui.gadgets.labeled.private\r
-\r
 : menu-rotations-4D ( -- gadget )\r
     3 3 <frame>\r
         { 1 1 } >>filled-cell\r
index 1f36a4627581364a65a69bcd66d867ee85ec8cf4..0d46d73f55d2d2b4716fd2081cb17798728020e1 100755 (executable)
@@ -1,4 +1,4 @@
-USING: kernel namespaces math.vectors opengl 4DNav.turtle  ;
+USING: kernel namespaces math.vectors opengl opengl.glu 4DNav.turtle  ;
 
 IN: 4DNav.camera
 
index 5b5a452cdebd82888147f0a8708a2085f37b2258..2598a14429e70c51d1ce17888c670bdf5e4ac9bc 100755 (executable)
@@ -1 +1 @@
-4DNav : simmple tool to navigate thru a 4D space view as projections on 4 3D spaces.
\ No newline at end of file
+Simple tool to navigate through a 4D space with projections on 4 3D spaces
index ec77501b8ffb067dbdfac59d003fe4d654d996ed..4042528eba3b5f5201bebdb69cc6f7082ab0b9b1 100755 (executable)
@@ -60,7 +60,7 @@ t to: remove-hidden-solids?
 : dimension ( array -- x )      length 1- ; inline \r
 : last ( seq -- x )           [ dimension ] [ nth ] bi ; inline\r
 : change-last ( seq quot -- ) \r
-    [ [ dimension ] keep ] dip change-nth  ; \r
+    [ [ dimension ] keep ] dip change-nth  ; inline\r
 \r
 ! -------------------------------------------------------------\r
 ! light\r
@@ -445,7 +445,7 @@ TUPLE: space name dimension solids ambient-color lights ;
 \r
 : space-apply ( space m quot -- space ) \r
         curry [ map ] curry [ dup solids>> ] dip\r
-        [ call ] [ drop ] recover drop ;\r
+        [ call ] [ 2drop ] recover drop ; inline\r
 : space-transform ( space m -- space ) \r
     [ solid-transform ] space-apply ;\r
 : space-translate ( space v -- space ) \r
index be16150c2e003931ca520ce4d337264709188d10..a141489a0fd7b1d919d13dfadb709d4260260c5d 100644 (file)
@@ -7,7 +7,7 @@ IN: advice.tests
 [
     [ ad-do-it ] must-fail
     
-    : foo "foo" ; 
+    : foo ( -- str ) "foo" ; 
     \ foo make-advised
  
     { "bar" "foo" } [
index fbdfa9c66bb41397f312da904873c51c41efbf1b..9c0963469e42bbeabf6eb87a0102a0a50019542b 100644 (file)
@@ -49,15 +49,15 @@ PRIVATE>
     in-advice? get [ "ad-do-it should only be called inside 'around' advice" throw ] unless coyield ;
     
 : make-advised ( word -- )
-    [ dup [ over dup '[ _ call-before _ _ call-around _ call-after ] ] annotate ]
+    [ dup '[ [ _ ] dip over dup '[ _ call-before _ _ call-around _ call-after ] ] annotate ]
     [ { before after around } [ <linked-hash> swap set-word-prop ] with each ] 
     [ t advised set-word-prop ] tri ;
 
 : unadvise ( word --  )
     [ reset ] [ { before after around advised } [ f swap set-word-prop ] with each ] bi ;
 
-: ADVISE: ! word adname location => word adname quot loc
-    scan-word scan scan-word parse-definition swap [ spin ] dip advise ; parsing
+SYNTAX: ADVISE: ! word adname location => word adname quot loc
+    scan-word scan scan-word parse-definition swap [ spin ] dip advise ;
     
-: UNADVISE:    
-    scan-word parsed \ unadvise parsed ; parsing
\ No newline at end of file
+SYNTAX: UNADVISE:    
+    scan-word parsed \ unadvise parsed ;
\ No newline at end of file
index 000c0ce4cca8ca909357b8ba6331ba5f1f91287e..c875feab8348a71fcf210abfdbd00d681c0548db 100644 (file)
@@ -29,7 +29,7 @@ HELP: reset-progress ( -- )
     "a loop which makes use of " { $link progress } "."
 } ;
 
-HELP: progress ( -- time )
+HELP: progress
 { $values { "time" "an integer" } }
 { $description
     "Gives the time elapsed since the last time"
index 8ac4abe1fa0f2df62e695488947bb3aaf8f699eb..a5c7dbdde427ad043c0c2856cc70841fbbe4dd69 100644 (file)
@@ -9,7 +9,7 @@ SYMBOL: sleep-period
 
 : reset-progress ( -- ) millis last-loop set ;
 ! : my-progress ( -- progress ) millis 
-: progress ( -- progress ) millis last-loop get - reset-progress ;
+: progress ( -- time ) millis last-loop get - reset-progress ;
 : progress-peek ( -- progress ) millis last-loop get - ;
 : set-end ( duration -- end-time ) duration>milliseconds millis + ;
 : loop ( quot end -- ) dup millis > [ [ dup call ] dip loop ] [ 2drop ] if ; inline
index b3eccad6a32d4d33c65ddd4b0912318811224871..387c73abe4807e0f2eb4ede82d245b91f4bf4ecf 100644 (file)
@@ -24,7 +24,7 @@ NAMEs. DEFINES ${NAME}s.
 WHERE
 
 : (NAME) ( str -- ) drop ; inline
-: !NAME (parse-annotation) \ (NAME) parsed ; parsing
+SYNTAX: !NAME (parse-annotation) \ (NAME) parsed ;
 
 : NAMEs ( -- usages )
     \ (NAME) (non-annotation-usage) ;
diff --git a/extra/assoc-heaps/assoc-heaps-docs.factor b/extra/assoc-heaps/assoc-heaps-docs.factor
new file mode 100644 (file)
index 0000000..b148995
--- /dev/null
@@ -0,0 +1,32 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax io.streams.string assocs
+heaps.private ;
+IN: assoc-heaps
+
+HELP: <assoc-heap>
+{ $values { "assoc" assoc } { "heap" heap } { "assoc-heap" assoc-heap } }
+{ $description "Constructs a new " { $link assoc-heap } " from two existing data structures." } ;
+
+HELP: <unique-max-heap>
+{ $values { "unique-heap" assoc-heap } }
+{ $description "Creates a new " { $link assoc-heap } " where the assoc is a hashtable and the heap is a max-heap. Popping an element from the heap leaves this element in the hashtable to ensure that the element will not be processed again." } ;
+
+HELP: <unique-min-heap>
+{ $values { "unique-heap" assoc-heap } }
+{ $description "Creates a new " { $link assoc-heap } " where the assoc is a hashtable and the heap is a min-heap. Popping an element from the heap leaves this element in the hashtable to ensure that the element will not be processed again." } ;
+
+{ <unique-max-heap> <unique-min-heap> } related-words
+
+HELP: assoc-heap
+{ $description "A data structure containing an assoc and a heap to get certain properties with better time constraints at the expense of more space and complexity. For instance, a hashtable and a heap can be combined into one assoc-heap to get a sorted data structure with O(1) lookup. Operations on assoc-heap may update both the assoc and the heap or leave them out of sync if it's advantageous." } ;
+
+ARTICLE: "assoc-heaps" "Associative heaps"
+"The " { $vocab-link "assoc-heaps" } " vocabulary combines exists to synthesize data structures with better time properties than either of the two component data structures alone." $nl
+"Associative heap constructor:"
+{ $subsection <assoc-heap> }
+"Unique heaps:"
+{ $subsection <unique-min-heap> }
+{ $subsection <unique-max-heap> } ;
+
+ABOUT: "assoc-heaps"
diff --git a/extra/assoc-heaps/assoc-heaps-tests.factor b/extra/assoc-heaps/assoc-heaps-tests.factor
new file mode 100644 (file)
index 0000000..6ea3fe1
--- /dev/null
@@ -0,0 +1,4 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test assoc-heaps ;
+IN: assoc-heaps.tests
diff --git a/extra/assoc-heaps/assoc-heaps.factor b/extra/assoc-heaps/assoc-heaps.factor
new file mode 100644 (file)
index 0000000..a495aed
--- /dev/null
@@ -0,0 +1,30 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs hashtables heaps kernel ;
+IN: assoc-heaps
+
+TUPLE: assoc-heap assoc heap ;
+
+C: <assoc-heap> assoc-heap
+
+: <unique-min-heap> ( -- unique-heap )
+    H{ } clone <min-heap> <assoc-heap> ;
+
+: <unique-max-heap> ( -- unique-heap )
+    H{ } clone <max-heap> <assoc-heap> ;
+
+M: assoc-heap heap-push* ( value key assoc-heap -- entry )
+    pick over assoc>> key? [
+        3drop f
+    ] [
+        [ assoc>> swapd set-at ] [ heap>> heap-push* ] 3bi
+    ] if ;
+
+M: assoc-heap heap-pop ( assoc-heap -- value key )
+    heap>> heap-pop ;
+
+M: assoc-heap heap-peek ( assoc-heap -- value key )
+    heap>> heap-peek ;
+
+M: assoc-heap heap-empty? ( assoc-heap -- value key )
+    heap>> heap-empty? ;
diff --git a/extra/assoc-heaps/authors.txt b/extra/assoc-heaps/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/assoc-heaps/summary.txt b/extra/assoc-heaps/summary.txt
new file mode 100644 (file)
index 0000000..792be0a
--- /dev/null
@@ -0,0 +1 @@
+Priority queue with fast insertion, removal of first element, and lookup of arbitrary elements by key
index 0f8b5581dfe582ff2d413527f2bd29a0b407e89d..f06bc2fb81f4dc00f14668c83b47cec7dc0eeb44 100644 (file)
@@ -59,11 +59,11 @@ C: <transaction> transaction
         [ dup [ over [ swap call ] dip ] dip 1 days time+ ] dip each-day
     ] [
         3drop
-    ] if ;
+    ] if ; inline recursive
 
 : process-to-date ( account date -- account )
     over interest-last-paid>> 1 days time+
-    [ dupd process-day ] spin each-day ;
+    [ dupd process-day ] spin each-day ; inline
 
 : inserting-transactions ( account transactions -- account )
     [ [ date>> process-to-date ] keep >>transaction ] each ;
index 9afd2118766d9bebf382683e8797e4d07feb945a..489dc5e73faa5f475f87209f8ee445c57b7c75fb 100755 (executable)
@@ -24,10 +24,10 @@ IN: benchmark
         [
             [
                 [ [ 1array $vocab-link ] with-cell ]
-                [ [ 1000000 /f pprint-cell ] [ "failed" write ] if* ] bi*
+                [ [ 1000000 /f pprint-cell ] [ [ "failed" write ] with-cell ] if* ] bi*
             ] with-row
         ] assoc-each
-    ] tabular-output ;
+    ] tabular-output nl ;
 
 : benchmarks ( -- )
     run-benchmarks benchmarks. ;
diff --git a/extra/benchmark/fib6/deploy.factor b/extra/benchmark/fib6/deploy.factor
new file mode 100644 (file)
index 0000000..3a367dc
--- /dev/null
@@ -0,0 +1,15 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-name "benchmark.fib6" }
+    { deploy-threads? f }
+    { deploy-math? f }
+    { deploy-word-props? f }
+    { deploy-ui? f }
+    { deploy-io 1 }
+    { deploy-compiler? t }
+    { deploy-reflection 1 }
+    { "stop-after-last-window?" t }
+    { deploy-unicode? f }
+    { deploy-word-defs? f }
+    { deploy-c-types? f }
+}
diff --git a/extra/benchmark/regex-dna/deploy.factor b/extra/benchmark/regex-dna/deploy.factor
new file mode 100644 (file)
index 0000000..91edab4
--- /dev/null
@@ -0,0 +1,15 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-word-defs? f }
+    { deploy-word-props? f }
+    { deploy-math? f }
+    { deploy-compiler? t }
+    { deploy-ui? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-reflection 1 }
+    { deploy-name "benchmark.regex-dna" }
+    { deploy-io 2 }
+    { deploy-threads? f }
+    { deploy-unicode? f }
+}
index 5c11be357f790e8386b02cc50c9482a92ad9d2fa..24e77597831e5f180a64ef74eacaf5199d8156a3 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors prettyprint io io.encodings.ascii
-io.files kernel sequences assocs namespaces regexp ;
+USING: accessors io io.encodings.ascii io.files kernel sequences
+assocs math.parser namespaces regexp ;
 IN: benchmark.regex-dna
 
 ! Based on http://shootout.alioth.debian.org/gp4/benchmark.php?test=regexdna&lang=ruby&id=1
@@ -22,7 +22,7 @@ IN: benchmark.regex-dna
         R/ agggtaa[cgt]|[acg]ttaccct/i
     } [
         [ raw>> write bl ]
-        [ count-matches . ]
+        [ count-matches number>string print ]
         bi
     ] with each ;
 
@@ -50,9 +50,9 @@ SYMBOL: clen
     dup count-patterns
     do-replacements
     nl
-    ilen get .
-    clen get .
-    length . ;
+    ilen get number>string print
+    clen get number>string print
+    length number>string print ;
 
 : regex-dna-main ( -- )
     "resource:extra/benchmark/regex-dna/regex-dna-test-in.txt" regex-dna ;
index 64d2bdbb1f8fd9b897df4786cb57cb5515c050e3..b86e11e239d69757fca872e90c4579f89c431b6b 100644 (file)
@@ -48,6 +48,6 @@ IN: benchmark.spectral-norm
 HINTS: spectral-norm fixnum ;
 
 : spectral-norm-main ( -- )
-    5500 spectral-norm . ;
+    2000 spectral-norm . ;
 
 MAIN: spectral-norm-main
diff --git a/extra/c/preprocessor/authors.txt b/extra/c/preprocessor/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/c/preprocessor/preprocessor-tests.factor b/extra/c/preprocessor/preprocessor-tests.factor
new file mode 100644 (file)
index 0000000..ba0531d
--- /dev/null
@@ -0,0 +1,26 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.test c.preprocessor kernel accessors multiline ;
+IN: c.preprocessor.tests
+
+[ "vocab:c/tests/test1/test1.c" start-preprocess-file ]
+[ include-nested-too-deeply? ] must-fail-with
+
+[ "yo\n\n\n\nyo4\n" ]
+[ "vocab:c/tests/test2/test2.c" start-preprocess-file nip ] unit-test
+
+/*
+[ "vocab:c/tests/test3/test3.c" start-preprocess-file ]
+[ "\"BOO\"" = ] must-fail-with
+*/
+
+[ V{ "\"omg\"" "\"lol\"" } ]
+[ "vocab:c/tests/test4/test4.c" start-preprocess-file drop warnings>> ] unit-test
+
+
+/*
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); 
+f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); 
+int i[] = { 1, 23, 4, 5, }; 
+char c[2][6] = { "hello", "" }; 
+*/
diff --git a/extra/c/preprocessor/preprocessor.factor b/extra/c/preprocessor/preprocessor.factor
new file mode 100644 (file)
index 0000000..f787bef
--- /dev/null
@@ -0,0 +1,201 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: sequence-parser io io.encodings.utf8 io.files
+io.streams.string kernel combinators accessors io.pathnames
+fry sequences arrays locals namespaces io.directories
+assocs math splitting make unicode.categories
+combinators.short-circuit ;
+IN: c.preprocessor
+
+: initial-library-paths ( -- seq )
+    V{ "/usr/include" } clone ;
+
+: initial-symbol-table ( -- hashtable )
+    H{
+        { "__APPLE__" "" }
+        { "__amd64__" "" }
+        { "__x86_64__" "" }
+    } clone ;
+
+TUPLE: preprocessor-state library-paths symbol-table
+include-nesting include-nesting-max processing-disabled?
+ifdef-nesting warnings errors
+pragmas
+include-nexts
+ifs elifs elses ;
+
+: <preprocessor-state> ( -- preprocessor-state )
+    preprocessor-state new
+        initial-library-paths >>library-paths
+        initial-symbol-table >>symbol-table
+        0 >>include-nesting
+        200 >>include-nesting-max
+        0 >>ifdef-nesting
+        V{ } clone >>warnings
+        V{ } clone >>errors
+        V{ } clone >>pragmas
+        V{ } clone >>include-nexts
+        V{ } clone >>ifs
+        V{ } clone >>elifs
+        V{ } clone >>elses ;
+
+DEFER: preprocess-file
+
+ERROR: unknown-c-preprocessor sequence-parser name ;
+
+ERROR: bad-include-line line ;
+
+ERROR: header-file-missing path ;
+
+:: read-standard-include ( preprocessor-state path -- )
+    preprocessor-state dup library-paths>>
+    [ path append-path exists? ] find nip
+    [
+        dup [
+            path append-path
+            preprocess-file
+        ] with-directory
+    ] [
+        ! path header-file-missing
+        drop
+    ] if* ;
+
+:: read-local-include ( preprocessor-state path -- )
+    current-directory get path append-path dup :> full-path
+    dup exists? [
+        [ preprocessor-state ] dip preprocess-file
+    ] [
+        ! full-path header-file-missing
+        drop
+    ] if ;
+
+: skip-whitespace/comments ( sequence-parser -- sequence-parser )
+    skip-whitespace
+    {
+        { [ dup take-c-comment ] [ skip-whitespace/comments ] }
+        { [ dup take-c++-comment ] [ skip-whitespace/comments ] }
+        [ ]
+    } cond ;
+
+: handle-include ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments advance dup previous {
+        { CHAR: < [ CHAR: > take-until-object read-standard-include ] }
+        { CHAR: " [ CHAR: " take-until-object read-local-include ] }
+        [ bad-include-line ]
+    } case ;
+
+: (readlns) ( -- )
+    readln "\\" ?tail [ , ] dip [ (readlns) ] when ;
+
+: readlns ( -- string ) [ (readlns) ] { } make concat ;
+
+: take-define-identifier ( sequence-parser -- string )
+    skip-whitespace/comments
+    [ current { [ blank? ] [ CHAR: ( = ] } 1|| ] take-until ;
+
+: handle-define ( preprocessor-state sequence-parser -- )
+    [ take-define-identifier ]
+    [ skip-whitespace/comments take-rest ] bi 
+    "\\" ?tail [ readlns append ] when
+    spin symbol-table>> set-at ;
+
+: handle-undef ( preprocessor-state sequence-parser -- )
+    take-token swap symbol-table>> delete-at ;
+
+: handle-ifdef ( preprocessor-state sequence-parser -- )
+    [ [ 1 + ] change-ifdef-nesting ] dip
+    take-token over symbol-table>> key?
+    [ drop ] [ t >>processing-disabled? drop ] if ;
+
+: handle-ifndef ( preprocessor-state sequence-parser -- )
+    [ [ 1 + ] change-ifdef-nesting ] dip
+    take-token over symbol-table>> key?
+    [ t >>processing-disabled? drop ]
+    [ drop ] if ; 
+
+: handle-endif ( preprocessor-state sequence-parser -- )
+    drop [ 1 - ] change-ifdef-nesting drop ;
+
+: handle-if ( preprocessor-state sequence-parser -- )
+    [ [ 1 + ] change-ifdef-nesting ] dip
+    skip-whitespace/comments take-rest swap ifs>> push ;
+
+: handle-elif ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments take-rest swap elifs>> push ;
+
+: handle-else ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments take-rest swap elses>> push ;
+
+: handle-pragma ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments take-rest swap pragmas>> push ;
+
+: handle-include-next ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments take-rest swap include-nexts>> push ;
+
+: handle-error ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments take-rest swap errors>> push ;
+    ! nip take-rest throw ;
+
+: handle-warning ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments
+    take-rest swap warnings>> push ;
+
+: parse-directive ( preprocessor-state sequence-parser string -- )
+    {
+        { "warning" [ handle-warning ] }
+        { "error" [ handle-error ] }
+        { "include" [ handle-include ] }
+        { "define" [ handle-define ] }
+        { "undef" [ handle-undef ] }
+        { "ifdef" [ handle-ifdef ] }
+        { "ifndef" [ handle-ifndef ] }
+        { "endif" [ handle-endif ] }
+        { "if" [ handle-if ] }
+        { "elif" [ handle-elif ] }
+        { "else" [ handle-else ] }
+        { "pragma" [ handle-pragma ] }
+        { "include_next" [ handle-include-next ] }
+        [ unknown-c-preprocessor ]
+    } case ;
+
+: parse-directive-line ( preprocessor-state sequence-parser -- )
+    advance dup take-token
+    pick processing-disabled?>> [
+        "endif" = [
+            drop f >>processing-disabled?
+            [ 1 - ] change-ifdef-nesting
+            drop
+         ] [ 2drop ] if
+    ] [
+        parse-directive
+    ] if ;
+
+: preprocess-line ( preprocessor-state sequence-parser -- )
+    skip-whitespace/comments dup current CHAR: # =
+    [ parse-directive-line ]
+    [ swap processing-disabled?>> [ drop ] [ write-full nl ] if ] if ;
+
+: preprocess-lines ( preprocessor-state -- )
+    readln 
+    [ <sequence-parser> [ preprocess-line ] [ drop preprocess-lines ] 2bi ]
+    [ drop ] if* ;
+
+ERROR: include-nested-too-deeply ;
+
+: check-nesting ( preprocessor-state -- preprocessor-state )
+    [ 1 + ] change-include-nesting
+    dup [ include-nesting>> ] [ include-nesting-max>> ] bi > [
+        include-nested-too-deeply
+    ] when ;
+
+: preprocess-file ( preprocessor-state path -- )
+    [ check-nesting ] dip
+    [ utf8 [ preprocess-lines ] with-file-reader ]
+    [ drop [ 1 - ] change-include-nesting drop ] 2bi ;
+
+: start-preprocess-file ( path -- preprocessor-state string )
+    dup parent-directory [
+        [
+            [ <preprocessor-state> dup ] dip preprocess-file
+        ] with-string-writer
+    ] with-directory ;
diff --git a/extra/c/tests/test1/README b/extra/c/tests/test1/README
new file mode 100644 (file)
index 0000000..9987313
--- /dev/null
@@ -0,0 +1 @@
+Tests if the preprocessor bails on an infinite loop caused by mutually recursive #include lines.
diff --git a/extra/c/tests/test1/hi.h b/extra/c/tests/test1/hi.h
new file mode 100644 (file)
index 0000000..c9f337c
--- /dev/null
@@ -0,0 +1 @@
+#include "lo.h"
diff --git a/extra/c/tests/test1/lo.h b/extra/c/tests/test1/lo.h
new file mode 100644 (file)
index 0000000..d59fdd2
--- /dev/null
@@ -0,0 +1 @@
+#include "hi.h"
diff --git a/extra/c/tests/test1/test1.c b/extra/c/tests/test1/test1.c
new file mode 100644 (file)
index 0000000..d59fdd2
--- /dev/null
@@ -0,0 +1 @@
+#include "hi.h"
diff --git a/extra/c/tests/test10/test10.c b/extra/c/tests/test10/test10.c
new file mode 100644 (file)
index 0000000..7f38e70
--- /dev/null
@@ -0,0 +1,3 @@
+/*
+# lol
+*/
diff --git a/extra/c/tests/test11/foo.h b/extra/c/tests/test11/foo.h
new file mode 100644 (file)
index 0000000..381b753
--- /dev/null
@@ -0,0 +1 @@
+foo.h ftw
diff --git a/extra/c/tests/test11/test11.c b/extra/c/tests/test11/test11.c
new file mode 100644 (file)
index 0000000..1b05118
--- /dev/null
@@ -0,0 +1,2 @@
+#define FOO_H "foo.h"
+#include FOO_H
diff --git a/extra/c/tests/test12/test12.c b/extra/c/tests/test12/test12.c
new file mode 100644 (file)
index 0000000..2da127b
--- /dev/null
@@ -0,0 +1,3 @@
+#if 4 > (5 - 4++)
+#error "Umm"
+#endif
diff --git a/extra/c/tests/test13/test13.c b/extra/c/tests/test13/test13.c
new file mode 100644 (file)
index 0000000..13c48ff
--- /dev/null
@@ -0,0 +1,2 @@
+#if 10
+#error "Umm"
diff --git a/extra/c/tests/test14/test14.c b/extra/c/tests/test14/test14.c
new file mode 100644 (file)
index 0000000..1697ea1
--- /dev/null
@@ -0,0 +1,15 @@
+#if 4 > (1 + 2) 
+good
+#endif
+
+#if 4 > 1 + 2
+good
+#endif
+
+#if (4 > 1) - 1
+bad
+#endif
+
+#if (4 > 1) - 2
+good
+#endif
diff --git a/extra/c/tests/test2/README b/extra/c/tests/test2/README
new file mode 100644 (file)
index 0000000..4244828
--- /dev/null
@@ -0,0 +1 @@
+Tests whether #define and #ifdef/#endif work in the positive case.
diff --git a/extra/c/tests/test2/test2.c b/extra/c/tests/test2/test2.c
new file mode 100644 (file)
index 0000000..4cc4191
--- /dev/null
@@ -0,0 +1,17 @@
+#define YO
+#ifdef YO
+yo
+#endif
+
+#define YO2
+#ifndef YO2
+yo2
+#endif
+
+#ifdef YO3
+yo3
+#endif
+
+#ifndef YO4
+yo4
+#endif
diff --git a/extra/c/tests/test3/README b/extra/c/tests/test3/README
new file mode 100644 (file)
index 0000000..4244828
--- /dev/null
@@ -0,0 +1 @@
+Tests whether #define and #ifdef/#endif work in the positive case.
diff --git a/extra/c/tests/test3/test3.c b/extra/c/tests/test3/test3.c
new file mode 100644 (file)
index 0000000..8d08e83
--- /dev/null
@@ -0,0 +1 @@
+#error "BOO"
diff --git a/extra/c/tests/test4/test4.c b/extra/c/tests/test4/test4.c
new file mode 100644 (file)
index 0000000..5acd20d
--- /dev/null
@@ -0,0 +1,2 @@
+#warning "omg"
+#warning "lol"
diff --git a/extra/c/tests/test5/test5.c b/extra/c/tests/test5/test5.c
new file mode 100644 (file)
index 0000000..4c16964
--- /dev/null
@@ -0,0 +1,3 @@
+#define TABSIZE 100
+
+int table[TABSIZE];
diff --git a/extra/c/tests/test6/test6.c b/extra/c/tests/test6/test6.c
new file mode 100644 (file)
index 0000000..3b0353a
--- /dev/null
@@ -0,0 +1 @@
+#define max(a, b) ((a) > (b) ? (a) : (b))
diff --git a/extra/c/tests/test7/test7.c b/extra/c/tests/test7/test7.c
new file mode 100644 (file)
index 0000000..4d5e66b
--- /dev/null
@@ -0,0 +1,19 @@
+#define x 3 
+#define f(a) f(x * (a)) 
+#undef x 
+#define x 2 
+#define g f 
+#define z z[0] 
+#define h g(~ 
+#define m(a) a(w) 
+#define w 0,1 
+#define t(a) a 
+#define p() int 
+#define q(x) x 
+#define r(x,y) x ## y 
+#define str(x) # x 
+f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); 
+g(x+(3,4)-w) | h 5) & m 
+(f)^m(m); 
+p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; 
+char c[2][6] = { str(hello), str() }; 
diff --git a/extra/c/tests/test8/test8.c b/extra/c/tests/test8/test8.c
new file mode 100644 (file)
index 0000000..bc1e273
--- /dev/null
@@ -0,0 +1,15 @@
+#define str(s) #s 
+#define xstr(s) str(s) 
+#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ 
+x ## s, x ## t) 
+#define INCFILE(n) vers ## n 
+#define glue(a, b) a## b 
+#define xglue(a, b) glue(a, b) 
+#define HIGHLOW "hello" 
+#define LOW LOW ", world" 
+debug(1, 2); 
+fputs(str(strncmp("abc\0d", "abc", '\4') //this goes away 
+== 0) str(: @\n), s); 
+#include xstr(INCFILE(2).h) 
+glue(HIGH, LOW); 
+xglue(HIGH, LOW) 
diff --git a/extra/c/tests/test9/test9.c b/extra/c/tests/test9/test9.c
new file mode 100644 (file)
index 0000000..86940cf
--- /dev/null
@@ -0,0 +1,4 @@
+#define t(x,y,z) x ## y ## z 
+int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), 
+t(10,,), t(,11,), t(,,12), t(,,) }; 
+
index 64696759bb300b8a38ed14f067d27a5540701530..f43787673a4d35f4902c0fa578483265f2e49a3f 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008 Doug Coleman, Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays byte-arrays kernel math namespaces
-opengl.gl sequences math.vectors ui images images.viewer
-models ui.gadgets.worlds ui.gadgets fry alien.syntax ;
+opengl.gl sequences math.vectors ui images images.normalization
+images.viewer models ui.gadgets.worlds ui.gadgets fry alien.syntax ;
 IN: cap
 
 : screenshot-array ( world -- byte-array )
diff --git a/extra/chess960/chess960.factor b/extra/chess960/chess960.factor
new file mode 100644 (file)
index 0000000..6535cc1
--- /dev/null
@@ -0,0 +1,43 @@
+USING: math.ranges kernel random sequences arrays combinators ;
+IN: chess960
+
+SYMBOLS: pawn rook knight bishop queen king ;
+
+: all-positions ( -- range ) 0 8 [a,b) ;
+
+: black-bishop-positions ( -- range ) 0 6 2 <range> ;
+: white-bishop-positions ( -- range ) 1 7 2 <range> ;
+
+: frisk ( position positions -- position positions' )
+    [ drop ] [ remove ] 2bi ;
+
+: white-bishop ( positions -- position positions' )
+    [ white-bishop-positions random ] dip frisk ;
+: black-bishop ( positions -- position positions' )
+    [ black-bishop-positions random ] dip frisk ;
+
+: random-position ( positions -- position positions' )
+    [ random ] keep frisk ;
+
+: make-position ( white-bishop black-bishop knight knight queen {r,k,r} -- position )
+    first3
+    8 f <array> {
+        [ [ rook ] 2dip set-nth ]
+        [ [ king ] 2dip set-nth ]
+        [ [ rook ] 2dip set-nth ]
+        [ [ queen ] 2dip set-nth ]
+        [ [ knight ] 2dip set-nth ]
+        [ [ knight ] 2dip set-nth ]
+        [ [ bishop ] 2dip set-nth ]
+        [ [ bishop ] 2dip set-nth ]
+        [ ]
+    } cleave ;
+
+: chess960-position ( -- position )
+    all-positions
+    white-bishop
+    black-bishop
+    random-position
+    random-position
+    random-position
+    make-position ;
diff --git a/extra/chicago-talk/authors.txt b/extra/chicago-talk/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/chicago-talk/chicago-talk.factor b/extra/chicago-talk/chicago-talk.factor
new file mode 100644 (file)
index 0000000..9d42ff1
--- /dev/null
@@ -0,0 +1,65 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: slides help.markup ;
+IN: chicago-talk
+
+CONSTANT: chicago-slides
+{
+{ $slide "factor"
+
+{ $url "http://factorcode.org" }
+
+}
+{ $slide "goals"
+
+"high level language"
+"expressive and extensible"
+"reasonable performance"
+"interactive development with arbitrary redefinition"
+"standalone app deployment (strip out compiler and REPL)"
+
+}
+{ $slide "challenges"
+
+"higher-order functions"
+"dynamic typing"
+"memory allocation"
+"float boxing/unboxing"
+"integer overflow checks"
+"user-defined abstractions"
+
+}
+{ $slide "implementation"
+
+"VM: 12 kloc of C, library: >100 kloc of Factor"
+"generational copying garbage collection, card marking write barrier"
+"full continuations, tail calls"
+"simple non-optimizing “bootstrap” compiler"
+"optimizing compiler"
+
+}
+{ $slide "optimizing compiler"
+
+"about 12,000 lines of Factor code"
+"targets x86-32, x86-64, PowerPC"
+"factor code ⇒ high-level SSA ⇒ low-level SSA ⇒ machine code"
+
+}
+{ $slide "high-level optimizer"
+
+"macro expansion, defunctionalization"
+"type and interval inference, sparse conditional constant propagation, method inlining"
+"escape analysis and tuple unboxing"
+
+}
+{ $slide "low-level optimizer"
+
+"alias analysis, value numbering, write barrier elimination"
+"linear scan register allocation"
+
+}
+}
+
+: chicago-talk ( -- ) chicago-slides slides-window ;
+
+MAIN: chicago-talk
\ No newline at end of file
diff --git a/extra/chicago-talk/deploy.factor b/extra/chicago-talk/deploy.factor
new file mode 100755 (executable)
index 0000000..8f8adc1
--- /dev/null
@@ -0,0 +1,12 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 1 }
+    { deploy-reflection 1 }
+    { deploy-compiler? t }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "Chicago Talk" }
+}
diff --git a/extra/chicago-talk/summary.txt b/extra/chicago-talk/summary.txt
new file mode 100755 (executable)
index 0000000..229e1a3
--- /dev/null
@@ -0,0 +1 @@
+Slides for a talk at the Pycon VM Summit, Chicago, IL, March 2009
diff --git a/extra/chicago-talk/tags.txt b/extra/chicago-talk/tags.txt
new file mode 100644 (file)
index 0000000..cb5fc20
--- /dev/null
@@ -0,0 +1 @@
+demos
index fcb4dbd69d1654023e950a74506ee3168a215ee9..eeeb63dd7db86f61de4a72153f5b3d5f470a83d6 100755 (executable)
@@ -1,12 +1,15 @@
 USING: tools.deploy.config ;
-V{
-    { deploy-ui? t }
-    { deploy-io 1 }
-    { deploy-reflection 1 }
-    { deploy-compiler? t }
-    { deploy-math? t }
+H{
+    { deploy-name "Color Picker" }
     { deploy-word-props? f }
+    { deploy-ui? t }
+    { deploy-threads? t }
+    { deploy-unicode? f }
     { deploy-c-types? f }
+    { deploy-word-defs? f }
+    { deploy-compiler? t }
+    { deploy-io 2 }
+    { deploy-reflection 1 }
     { "stop-after-last-window?" t }
-    { deploy-name "Color Picker" }
+    { deploy-math? t }
 }
index 13a516eaf14621640d20174a63441770dfb493a3..0865dabcf7f17a69ae91fc6aa209102ef25e7654 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors combinators.smart sorting.human
-models colors.constants present
+models colors.constants present sorting.slots
 ui ui.gadgets.tables ui.gadgets.scrollers ;
 IN: color-table
 
@@ -29,7 +29,7 @@ M: color-renderer row-value
     drop named-color ;
 
 : <color-table> ( -- table )
-    named-colors human-sort <model>
+    named-colors { human<=> } sort-by <model>
     color-renderer
     <table>
         5 >>gap
@@ -40,4 +40,4 @@ M: color-renderer row-value
 : color-table-demo ( -- )
     [ <color-table> <scroller> "Colors" open-window ] with-ui ;
 
-MAIN: color-table-demo
\ No newline at end of file
+MAIN: color-table-demo
index b984cdce543bfc84c82e138d0ce33bb1085a69ef..0377808dca795a26551c20d88746446b2a85e952 100644 (file)
@@ -36,7 +36,7 @@ HELP: ctags-write ( seq path -- )
 { $notes
   { $snippet "tags" } " file will contain a single line: if\\t/path/to/factor/extra/unix/unix.factor\\t91" } ;
 
-HELP: ctag-strings ( alist -- seq )
+HELP: ctag-strings
 { $values { "alist" "an association list" }
           { "seq" sequence } }
 { $description "Converts an " { $snippet "alist" } " with ctag format (a word as key and a sequence whose first element is a resource name and a second element is a line number as value) in a " { $snippet "seq" } " of ctag strings." }
index 38160de0e9cf7780711dcf145c645ba7cf34d48b..e351fbf7937457b1003ce677caccddd819a54553 100644 (file)
@@ -6,7 +6,7 @@
 
 USING: arrays kernel sequences io io.files io.backend
 io.encodings.ascii math.parser vocabs definitions
-namespaces make words sorting ;
+namespaces make words sorting present ;
 IN: ctags
 
 : ctag-word ( ctag -- word )
@@ -20,14 +20,14 @@ IN: ctags
 
 : ctag ( seq -- str )
   [
-    dup ctag-word ?word-name %
+    dup ctag-word present %
     "\t" %
     dup ctag-path normalize-path %
     "\t" %
     ctag-lineno number>string %
   ] "" make ;
 
-: ctag-strings ( seq1 -- seq2 )
+: ctag-strings ( alist -- seq )
   [ ctag ] map ;
 
 : ctags-write ( seq path -- )
index 9fe63e914e6bf65f6c4a013b63f02a34c746eab1..40c0b791cfd43ca4a72b200e2bac21c530b46115 100644 (file)
@@ -5,7 +5,7 @@
 ! Alfredo Beaumont <alfredo.beaumont@gmail.com>
 USING: kernel sequences sorting assocs words prettyprint ctags
 io.encodings.ascii io.files math math.parser namespaces make
-strings shuffle io.backend arrays ;
+strings shuffle io.backend arrays present ;
 IN: ctags.etags
 
 : etag-at ( key hash -- vector )
@@ -36,7 +36,7 @@ IN: ctags.etags
 
 : etag ( lines seq -- str )
   [
-    dup first ?word-name %
+    dup first present %
     1 HEX: 7f <string> %
     second dup number>string %
     1 CHAR: , <string> %
index b1c481a5769c5333b3ce462ae47c3994f162a250..3ff9404bff39955c3017619380e7cc565f531b66 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien alien.syntax combinators kernel system ;
+USING: accessors alien alien.syntax combinators kernel system
+alien.libraries ;
 IN: curses.ffi
 
 << "curses" {
index fd7aafb60120e40423c91fe1a2985dfd235a2a52..dfd73f1236d84f758dd6589c03c75c1b95d1fe1e 100644 (file)
@@ -1,22 +1,16 @@
-
-USING: kernel fry sequences
-       vocabs.loader tools.vocabs.browser
-       ui ui.gadgets ui.gadgets.buttons ui.gadgets.packs ui.gadgets.scrollers
-       ui.tools.listener
-       accessors ;
-
+USING: kernel fry sequences vocabs.loader help.vocabs ui
+ui.gadgets ui.gadgets.buttons ui.gadgets.packs ui.gadgets.borders
+ui.gadgets.scrollers ui.tools.listener accessors ;
 IN: demos
 
 : demo-vocabs ( -- seq ) "demos" tagged [ second ] map concat [ name>> ] map ;
 
 : <run-vocab-button> ( vocab-name -- button )
-  dup '[ drop [ _ run ] call-listener ] <border-button> ;
+    dup '[ drop [ _ run ] \ run call-listener ] <border-button> ;
 
 : <demo-runner> ( -- gadget )
-  <pile> 1 >>fill demo-vocabs [ <run-vocab-button> add-gadget ] each ;
-
-: demos ( -- ) [ <demo-runner> <scroller> "Demos" open-window ] with-ui ;
+    <pile> 1 >>fill { 2 2 } >>gap demo-vocabs [ <run-vocab-button> add-gadget ] each ;
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+: demos ( -- ) [ <demo-runner> { 2 2 } <border> <scroller> "Demos" open-window ] with-ui ;
 
 MAIN: demos
\ No newline at end of file
index dc02f8bd9d04e4eddb1838f6d12c46f67fc2f7fc..6ced201c13a51918c324ed54dd53ce94f8d3c82d 100755 (executable)
@@ -1,20 +1,28 @@
-USING: help.syntax help.markup ;\r
+USING: help.syntax help.markup words ;\r
 IN: descriptive\r
 \r
 HELP: DESCRIPTIVE:\r
 { $syntax "DESCRIPTIVE: word ( inputs -- outputs ) definition ;" }\r
-{ $description "Defines a word such that, if an error is thrown from within it, that error is wrapped in a descriptive tag including the arguments to that word." } ;\r
+{ $description "Defines a word such that, if an error is thrown from within it, that error is wrapped in a " { $link descriptive-error } " with the arguments to that word." } ;\r
 \r
 HELP: DESCRIPTIVE::\r
 { $syntax "DESCRIPTIVE:: word ( inputs -- outputs ) definition ;" }\r
-{ $description "Defines a word which uses locals such that, if an error is thrown from within it, that error is wrapped in a descriptive tag including the arguments to that word." } ;\r
+{ $description "Defines a word which uses locals such that, if an error is thrown from within it, that error is wrapped in a " { $link descriptive-error } " with the arguments to that word." } ;\r
 \r
-HELP: descriptive\r
-{ $class-description "The class of errors wrapping another error (in the underlying slot) which were thrown in a word (in the word slot) with a given set of arguments (in the args slot)." } ;\r
+HELP: descriptive-error\r
+{ $error-description "The class of errors wrapping another error (in the underlying slot) which were thrown in a word (in the word slot) with a given set of arguments (in the args slot)." } ;\r
+\r
+HELP: make-descriptive\r
+{ $values { "word" word } }\r
+{ $description "Makes the word wrap errors in " { $link descriptive-error } " instances." } ;\r
 \r
 ARTICLE: "descriptive" "Descriptive errors"\r
-"This vocabulary defines automatic descriptive errors. Using it, you can define a word which acts as normal, except when it throws an error, the error is wrapped in a special descriptor declaring that an error was thrown from inside that word, and including the arguments given to that word. The error is of the following class:"\r
-{ $subsection descriptive }\r
+"This vocabulary defines automatic descriptive errors. Using it, you can define a word which acts as normal, except when it throws an error, the error is wrapped in an instance of a class:"\r
+{ $subsection descriptive-error }\r
+"The wrapper contains the word itself, the input parameters, as well as the original error."\r
+$nl\r
+"To annotate an existing word with descriptive error checking:"\r
+{ $subsection make-descriptive }\r
 "To define words which throw descriptive errors, use the following words:"\r
 { $subsection POSTPONE: DESCRIPTIVE: }\r
 { $subsection POSTPONE: DESCRIPTIVE:: } ;\r
index dd0042455cc3d66e6ce6fefc0a94ca7a2afc574e..9af94aa4ed47fa6b181f96a36ca81af2abc762f7 100755 (executable)
@@ -1,45 +1,55 @@
-USING: words kernel sequences locals locals.parser\r
-locals.definitions accessors parser namespaces continuations\r
-summary definitions generalizations arrays ;\r
-IN: descriptive\r
-\r
-ERROR: descriptive-error args underlying word ;\r
-\r
-M: descriptive-error summary\r
-    word>> "The " swap name>> " word encountered an error."\r
-    3append ;\r
-\r
-<PRIVATE\r
-: rethrower ( word inputs -- quot )\r
-    [ length ] keep [ [ narray ] dip swap 2array flip ] 2curry\r
-    [ 2 ndip descriptive-error ] 2curry ;\r
-\r
-: [descriptive] ( word def -- newdef )\r
-    swap dup "declared-effect" word-prop in>> rethrower\r
-    [ recover ] 2curry ;\r
-PRIVATE>\r
-\r
-: define-descriptive ( word def -- )\r
-    [ "descriptive-definition" set-word-prop ]\r
-    [ dupd [descriptive] define ] 2bi ;\r
-\r
-: DESCRIPTIVE:\r
-    (:) define-descriptive ; parsing\r
-\r
-PREDICATE: descriptive < word\r
-    "descriptive-definition" word-prop ;\r
-\r
-M: descriptive definer drop \ DESCRIPTIVE: \ ; ;\r
-\r
-M: descriptive definition\r
-    "descriptive-definition" word-prop ;\r
-\r
-: DESCRIPTIVE::\r
-    (::) define-descriptive ; parsing\r
-\r
-INTERSECTION: descriptive-lambda descriptive lambda-word ;\r
-\r
-M: descriptive-lambda definer drop \ DESCRIPTIVE:: \ ; ;\r
-\r
-M: descriptive-lambda definition\r
-    "lambda" word-prop body>> ;\r
+! Copyright (c) 2008 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: words kernel sequences locals locals.parser fry
+locals.definitions accessors parser namespaces continuations
+summary definitions generalizations arrays prettyprint debugger io
+effects tools.annotations ;
+IN: descriptive
+
+ERROR: descriptive-error args underlying word ;
+
+M: descriptive-error error.
+    "The word " write dup word>> pprint " encountered an error." print
+    "Arguments:" print
+    dup args>> stack.
+    "Error:" print
+    underlying>> error. ;
+
+<PRIVATE
+
+: rethrower ( word inputs -- quot )
+    [ length ] keep [ [ narray ] dip swap 2array flip ] 2curry
+    [ 2 ndip descriptive-error ] 2curry ;
+
+: [descriptive] ( word def effect -- newdef )
+    swapd in>> rethrower [ recover ] 2curry ;
+
+PRIVATE>
+
+: make-descriptive ( word -- )
+    dup [ ] [ def>> ] [ stack-effect ] tri [descriptive]
+    '[ drop _ ] annotate-methods ;
+
+: define-descriptive ( word def effect -- )
+    [ drop "descriptive-definition" set-word-prop ]
+    [ [ [ dup ] 2dip [descriptive] ] keep define-declared ]
+    3bi ;
+
+SYNTAX: DESCRIPTIVE: (:) define-descriptive ;
+
+PREDICATE: descriptive < word
+    "descriptive-definition" word-prop ;
+
+M: descriptive definer drop \ DESCRIPTIVE: \ ; ;
+
+M: descriptive definition
+    "descriptive-definition" word-prop ;
+
+SYNTAX: DESCRIPTIVE:: (::) define-descriptive ;
+
+INTERSECTION: descriptive-lambda descriptive lambda-word ;
+
+M: descriptive-lambda definer drop \ DESCRIPTIVE:: \ ; ;
+
+M: descriptive-lambda definition
+    "lambda" word-prop body>> ;
diff --git a/extra/descriptive/tags.txt b/extra/descriptive/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/extra/drills/drills.factor b/extra/drills/drills.factor
new file mode 100644 (file)
index 0000000..98da129
--- /dev/null
@@ -0,0 +1,42 @@
+USING: accessors arrays cocoa.dialogs combinators continuations
+fry grouping io.encodings.utf8 io.files io.styles kernel math
+math.parser models models.arrow models.history namespaces random
+sequences splitting ui ui.gadgets.alerts ui.gadgets.book-extras
+ui.gadgets.books ui.gadgets.buttons ui.gadgets.frames
+ui.gadgets.grids ui.gadgets.labels ui.gadgets.tracks ui.gestures
+ui.gadgets.corners ;
+
+IN: drills
+SYMBOLS: it startLength ;
+: big ( gadget -- gadget ) { "sans-serif" plain 30 } >>font ;
+: card ( model quot -- button ) <arrow> <label-control> big [ next ] <book-btn> ;
+: op ( quot str -- gadget ) <label> big swap <book-bevel-btn> ;
+
+: show ( model -- gadget ) dup it set-global [ random ] <arrow>
+   { [ [ first ] card ]
+   [ [ [ second ] [ drop [ "malformed input" throw ] "Malformed Input" alert ] recover ] card ]
+   [ '[ |<< [ it get [
+      _ value>> swap remove
+      [ [ it get go-back ] "Drill Complete" alert return ] when-empty
+   ] change-model ] with-return ] "Yes" op ]
+   [ '[ |<< it get _ model-changed ] "No" op ] } cleave
+2array { 1 0 } <track> swap [ 0.5 track-add ] each
+3array <book*> 3 3 <frame> { 450 175 } >>pref-dim swap @center grid-add
+it get [ length startLength get swap - number>string "/" startLength get number>string 3append ] <arrow> <label-control> @bottom grid-add ;
+
+: drill ( -- ) [ 
+   open-panel [
+      [ utf8 file-lines [ "\t" split
+         [ " " split 4 group [ " " join ] map ] map ] map ] map concat dup [ [ first ] [ second ] bi swap 2array ] map append
+         [ length startLength set-global ] keep <history> [ add-history ] [ show ] bi
+      "Got it?" open-window
+   ] when*
+] with-ui ;
+
+
+MAIN: drill
+
+    
+! FIXME: command-line opening
+! TODO: Menu bar
+! TODO: Pious hot-buttons
\ No newline at end of file
diff --git a/extra/drills/tags.txt b/extra/drills/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/extra/ecdsa/authors.txt b/extra/ecdsa/authors.txt
new file mode 100644 (file)
index 0000000..f97e1bf
--- /dev/null
@@ -0,0 +1 @@
+Maxim Savchenko
diff --git a/extra/ecdsa/ecdsa-tests.factor b/extra/ecdsa/ecdsa-tests.factor
new file mode 100644 (file)
index 0000000..b319fa2
--- /dev/null
@@ -0,0 +1,30 @@
+! Copyright (C) 2009 Maxim Savchenko
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: namespaces ecdsa tools.test checksums checksums.sha2 ;
+IN: ecdsa.tests
+
+SYMBOLS: priv-key pub-key signature ;
+
+: message ( -- msg ) "Hello world!" ;
+
+[ ] ! Generating keys
+[
+    "prime256v1" [ generate-key get-private-key get-public-key ] with-ec
+    pub-key set priv-key set
+] unit-test
+
+[ ] ! Signing message
+[
+    message sha-256 checksum-bytes
+    priv-key get
+    "prime256v1" [ set-private-key ecdsa-sign ] with-ec
+    signature set
+] unit-test
+
+[ t ] ! Verifying signature
+[
+    message sha-256 checksum-bytes
+    signature get pub-key get
+    "prime256v1" [ set-public-key ecdsa-verify ] with-ec
+] unit-test
\ No newline at end of file
diff --git a/extra/ecdsa/ecdsa.factor b/extra/ecdsa/ecdsa.factor
new file mode 100644 (file)
index 0000000..d76b93a
--- /dev/null
@@ -0,0 +1,75 @@
+! Copyright (C) 2009 Maxim Savchenko
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: kernel accessors sequences sequences.private destructors math namespaces
+       locals openssl openssl.libcrypto byte-arrays bit-arrays.private
+       alien.c-types alien.destructors ;
+
+IN: ecdsa
+
+<PRIVATE
+
+TUPLE: ec-key handle ;
+
+M: ec-key dispose
+    [ EC_KEY_free f ] change-handle drop ;
+
+: <ec-key> ( curve -- key )
+    OBJ_sn2nid dup zero? [ "Unknown curve name" throw ] when
+    EC_KEY_new_by_curve_name dup ssl-error ec-key boa ;
+
+: ec-key-handle ( -- handle )
+    ec-key get dup handle>> [ nip ] [ already-disposed ] if* ;
+
+DESTRUCTOR: BN_clear_free
+
+DESTRUCTOR: EC_POINT_clear_free
+
+PRIVATE>
+
+: with-ec ( curve quot -- )
+    swap <ec-key> [ ec-key rot with-variable ] with-disposal ; inline
+
+: generate-key ( -- )
+    ec-key get handle>> EC_KEY_generate_key ssl-error ;
+
+: set-private-key ( bin -- )
+    ec-key-handle swap
+    dup length f BN_bin2bn dup ssl-error
+    [ &BN_clear_free EC_KEY_set_private_key ssl-error ] with-destructors ;
+
+:: set-public-key ( BIN -- )
+    ec-key-handle :> KEY
+    KEY EC_KEY_get0_group :> GROUP
+    GROUP EC_POINT_new dup ssl-error
+    [
+        &EC_POINT_clear_free :> POINT
+        GROUP POINT BIN dup length f EC_POINT_oct2point ssl-error
+        KEY POINT EC_KEY_set_public_key ssl-error
+    ] with-destructors ;
+
+: get-private-key ( -- bin/f )
+    ec-key-handle EC_KEY_get0_private_key
+    dup [ dup BN_num_bits bits>bytes <byte-array> tuck BN_bn2bin drop ] when ;
+
+:: get-public-key ( -- bin/f )
+    ec-key-handle :> KEY
+    KEY EC_KEY_get0_public_key dup 
+    [| PUB |
+        KEY EC_KEY_get0_group :> GROUP
+        GROUP EC_GROUP_get_degree bits>bytes 1+ :> LEN
+        LEN <byte-array> :> BIN
+        GROUP PUB POINT_CONVERSION_COMPRESSED BIN LEN f
+        EC_POINT_point2oct ssl-error
+        BIN
+    ] when ;
+
+:: ecdsa-sign ( DGST -- sig )
+    ec-key-handle :> KEY
+    KEY ECDSA_size dup ssl-error <byte-array> :> SIG
+    "uint" <c-object> :> LEN
+    0 DGST dup length SIG LEN KEY ECDSA_sign ssl-error
+    LEN *uint SIG resize ;
+
+: ecdsa-verify ( dgst sig -- ? )
+    ec-key-handle [ 0 -rot [ dup length ] bi@ ] dip ECDSA_verify 0 > ;
\ No newline at end of file
diff --git a/extra/ecdsa/summary.txt b/extra/ecdsa/summary.txt
new file mode 100644 (file)
index 0000000..8f952c3
--- /dev/null
@@ -0,0 +1 @@
+Elliptic Curve Digital Signature Algorithm (OpenSSL realisation)
diff --git a/extra/ecdsa/tags.txt b/extra/ecdsa/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
index cf733dbbfd8aa3a3f1a497c71fe25ba93b052e88..bc6b8a092fa84092d7434163b6069946e4e60469 100755 (executable)
@@ -356,9 +356,9 @@ M: quotation fjsc-parse ( object -- ast )
 : fjsc-compile* ( string -- string )
   'statement' parse ast>> fjsc-compile ;
 
-: fc* ( string -- string )
+: fc* ( string -- )
   [
-  'statement' parse ast>> values>> do-expressions
+    'statement' parse ast>> values>> do-expressions
   ] { } make [ write ] each ;
 
 
index 06c875b2fadb7839a167a83d2d35a8d98a9674bb..c45475cefa30a9b81567e7232959c84e3f9e4f0b 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2005, 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.syntax kernel system combinators ;
+USING: alien alien.syntax kernel system combinators
+alien.libraries ;
 IN: freetype
 
 << "freetype" {
index 6368e542a78c19319bb8c2c2354fde3bcd64e991..30d6845a9b3413afcc4fb0732a4c94c22bbc5080 100644 (file)
@@ -3,7 +3,7 @@
 
 USING: accessors arrays assocs combinators help help.crossref
 help.markup help.topics io io.streams.string kernel make namespaces
-parser prettyprint sequences summary tools.vocabs tools.vocabs.browser
+parser prettyprint sequences summary tools.vocabs help.vocabs
 vocabs vocabs.loader words see ;
 
 IN: fuel.help
index ccba90fb6f603bcc6b27467c37d308287292d3a2..be713542eddaa7b8d7dfb4975a61331afe8cdad4 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: slides help.markup math arrays hashtables namespaces
 sequences kernel sequences parser memoize io.encodings.binary
-locals kernel.private tools.vocabs.browser assocs quotations
+locals kernel.private help.vocabs assocs quotations
 urls peg.ebnf tools.vocabs tools.annotations tools.crossref
 help.topics math.functions compiler.tree.optimizer
 compiler.cfg.optimizer fry ;
index c6004a82214493de0283ff7969f42ef84e5852a7..a2beaf6d9bb6682ce285ddf2184cff412fec9088 100755 (executable)
@@ -2,10 +2,10 @@ USING: windows.dinput windows.dinput.constants parser
 alien.c-types windows.ole32 namespaces assocs kernel arrays
 vectors windows.kernel32 windows.com windows.dinput shuffle
 windows.user32 windows.messages sequences combinators locals
-math.rectangles ui.windows accessors math windows alien
+math.rectangles accessors math windows alien
 alien.strings io.encodings.utf16 io.encodings.utf16n
 continuations byte-arrays game-input.dinput.keys-array
-game-input ;
+game-input ui.backend.windows ;
 IN: game-input.dinput
 
 SINGLETON: dinput-game-input-backend
index a5c79e02683f978c9e37385cb7e949d354196f21..2bf923c12bd8c8b60d5992ea57e86ce563199656 100644 (file)
@@ -1,7 +1,12 @@
 IN: game-input.tests
-USING: game-input tools.test kernel system ;
+USING: ui game-input tools.test kernel system threads
+combinators.short-circuit calendar ;
 
-os windows? os macosx? or [
+{
+    [ os windows? ui-running? and ]
+    [ os macosx? ]
+} 0|| [
     [ ] [ open-game-input ] unit-test
+    [ ] [ 1 seconds sleep ] unit-test
     [ ] [ close-game-input ] unit-test
 ] when
\ No newline at end of file
index 46e3ba9e8dafc0522a33b528cc4bea5db32e7f64..6efe31861a69863490d75b03b1042a5e5086e954 100755 (executable)
@@ -35,7 +35,7 @@ PRIVATE>
     ] when ;
 
 : with-game-input ( quot -- )
-    open-game-input [ close-game-input ] [ ] cleanup ;
+    open-game-input [ close-game-input ] [ ] cleanup ; inline
 
 TUPLE: controller handle ;
 TUPLE: controller-state x y z rx ry rz slider pov buttons ;
index ad6302ca55b4e7e71a814c4b4153e7031e76b078..d07ed4b69c703feabc7c0d8e6c30edbe785c8e1c 100644 (file)
@@ -9,7 +9,7 @@ IN: geo-ip
 
 : db-path ( -- path ) "IpToCountry.csv" temp-file ;
 
-: db-url ( -- url ) "http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download" ;
+CONSTANT: db-url "http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download"
 
 : download-db ( -- path )
     db-path dup exists? [
diff --git a/extra/geobytes/authors.txt b/extra/geobytes/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/geobytes/geobytes.factor b/extra/geobytes/geobytes.factor
new file mode 100644 (file)
index 0000000..bbd16b7
--- /dev/null
@@ -0,0 +1,90 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators combinators.smart csv io.encodings.8-bit
+math.parser memoize sequences kernel unicode.categories money ;
+IN: geobytes
+
+! GeoBytes is not free software.
+! Please read their license should you choose to use it.
+! This is just a binding to the GeoBytes CSV files.
+! Download and install GeoBytes yourself should you wish to use it.
+! http://www.geobytes.com/GeoWorldMap.zip
+
+CONSTANT: geobytes-cities-path "resource:GeoWorldMap/Cities.txt"
+CONSTANT: geobytes-countries-path "resource:GeoWorldMap/Countries.txt"
+CONSTANT: geobytes-regions-path "resource:GeoWorldMap/Regions.txt"
+CONSTANT: geobytes-version-path "resource:GeoWorldMap/version.txt"
+
+TUPLE: country country-id country fips104 iso2 iso3 ison internet capital map-reference
+nationality-singular nationality-plural currency currency-code population title
+comment ;
+
+TUPLE: region region-id country-id region code adm1-code ;
+
+TUPLE: city city-id country-id region-id city longitude latitude timezone code ;
+
+TUPLE: version component version rows ;
+
+MEMO: load-countries ( -- seq )
+    geobytes-countries-path latin1 file>csv rest-slice [
+        [
+            {
+                [ string>number ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ ]
+                [ string>number ]
+                [ ]
+                [ ]
+            } spread country boa
+        ] input<sequence 
+    ] map ;
+
+MEMO: load-regions ( -- seq )
+    geobytes-regions-path latin1 file>csv rest-slice [
+        [
+            {
+                [ string>number ]
+                [ string>number ]
+                [ ]
+                [ ]
+                [ [ blank? ] trim ]
+            } spread region boa
+        ] input<sequence 
+    ] map ;
+
+MEMO: load-cities ( -- seq )
+    geobytes-cities-path latin1 file>csv rest-slice [
+        [
+            {
+                [ string>number ]
+                [ string>number ]
+                [ string>number ]
+                [ ]
+                [ parse-decimal ]
+                [ parse-decimal ]
+                [ ]
+                [ string>number ]
+            } spread city boa
+        ] input<sequence 
+    ] map ;
+
+MEMO: load-version ( -- seq )
+    geobytes-version-path latin1 file>csv rest-slice [
+        [
+            {
+                [ ]
+                [ ]
+                [ string>number ]
+            } spread version boa
+        ] input<sequence 
+    ] map ;
diff --git a/extra/geobytes/summary.txt b/extra/geobytes/summary.txt
new file mode 100644 (file)
index 0000000..50fd51f
--- /dev/null
@@ -0,0 +1 @@
+City, country, region database using database from http://www.geobytes.com/GeoWorldMap.zip
diff --git a/extra/geobytes/tags.txt b/extra/geobytes/tags.txt
new file mode 100644 (file)
index 0000000..0aef4fe
--- /dev/null
@@ -0,0 +1 @@
+enterprise
index 4d4e3b0507d51cec4f55073fedab901488c83da1..ab8e72fc76bb58cdf1712dc121381caaee0a38ea 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: slides help.markup math arrays hashtables namespaces
 sequences kernel sequences parser memoize io.encodings.binary
-locals kernel.private tools.vocabs.browser assocs quotations
+locals kernel.private help.vocabs assocs quotations
 urls peg.ebnf tools.vocabs tools.annotations tools.crossref
 help.topics math.functions compiler.tree.optimizer
 compiler.cfg.optimizer fry ;
diff --git a/extra/hello-unicode/deploy.factor b/extra/hello-unicode/deploy.factor
new file mode 100644 (file)
index 0000000..f2f1c9f
--- /dev/null
@@ -0,0 +1,15 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-word-defs? f }
+    { deploy-reflection 1 }
+    { deploy-word-props? f }
+    { deploy-compiler? t }
+    { deploy-threads? t }
+    { deploy-unicode? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "hello-unicode" }
+    { deploy-math? t }
+    { deploy-ui? t }
+    { deploy-io 2 }
+    { deploy-c-types? f }
+}
index ef492958e7071f5de32558b08cb811945eabdfa4..4374db20031d427d2e216163d155b1ab74d3bf5c 100644 (file)
@@ -15,6 +15,6 @@ IN: hello-unicode
         ] with-style
     ] make-pane { 10 10 } <border> ;
 
-: hello-unicode ( -- ) <hello-gadget> "გამარჯობა" open-window ;
+: hello-unicode ( -- ) [ <hello-gadget> "გამარჯობა" open-window ] with-ui ;
 
 MAIN: hello-unicode
\ No newline at end of file
index abe830c3faa20d4b643076b6c9bfad3e9e4617fd..2196f1baaa1493ab4ce485548e9b0c0dac3439b6 100755 (executable)
@@ -3,7 +3,7 @@
 USING: assocs html.parser kernel math sequences strings ascii
 arrays generalizations shuffle unicode.case namespaces make
 splitting http accessors io combinators http.client urls
-urls.encoding fry prettyprint ;
+urls.encoding fry prettyprint sets ;
 IN: html.parser.analyzer
 
 TUPLE: link attributes clickable ;
@@ -46,7 +46,7 @@ TUPLE: link attributes clickable ;
 : find-between-all ( vector quot -- seq )
     dupd
     '[ _ [ closing?>> not ] bi and ] find-all
-    [ first2 find-between* ] with map ;
+    [ first2 find-between* ] with map ; inline
 
 : remove-blank-text ( vector -- vector' )
     [
@@ -113,7 +113,7 @@ TUPLE: link attributes clickable ;
     [ clickable>> [ bl bl text>> print ] each nl ] bi ;
 
 : find-by-text ( seq quot -- tag )
-    [ dup name>> text = ] prepose find drop ;
+    [ dup name>> text = ] prepose find drop ; inline
 
 : find-opening-tags-by-name ( name seq -- seq )
     [ [ name>> = ] [ closing?>> not ] bi and ] with find-all ;
@@ -126,7 +126,17 @@ TUPLE: link attributes clickable ;
     [ [
         [ name>> "a" = ]
         [ attributes>> "href" swap key? ] bi and ] filter
-    ] map sift [ [ attributes>> "href" swap at ] map ] map concat ;
+    ] map sift
+    [ [ attributes>> "href" swap at ] map ] map concat
+    [ >url ] map ;
+
+: find-frame-links ( vector -- vector' )
+    [ name>> "frame" = ] find-between-all
+    [ [ attributes>> "src" swap at ] map sift ] map concat sift
+    [ >url ] map ;
+
+: find-all-links ( vector -- vector' )
+    [ find-hrefs ] [ find-frame-links ] bi append prune ;
 
 : find-forms ( vector -- vector' )
     "form" over find-opening-tags-by-name
index 9757f70a67d8bb4392e1aa72617aa5ee523835f5..ca276fc54e069fd645570062add13e24c0a79ea7 100644 (file)
@@ -42,6 +42,19 @@ V{
 }
 ] [ "<a   href  =    \"http://factorcode.org/\"    foo   =  bar baz='quux'a=pirsqd  >" parse-html ] unit-test
 
+[
+V{
+    T{ tag f "a"
+        H{
+            { "a" "pirsqd" }
+            { "foo" "bar" }
+            { "href" "http://factorcode.org/" }
+            { "baz" "quux" }
+            { "nofollow" "nofollow" }
+        } f f }
+}
+] [ "<a   href  =    \"http://factorcode.org/\"    nofollow  foo   =  bar baz='quux'a=pirsqd  >" parse-html ] unit-test
+
 [
 V{
     T{ tag f "html" H{ } f f }
index c445b708c5859bf73e2ad6bf6f317f7f2ca3608f..d95c79dd887b053d129fe51630d2cc4857c2e032 100644 (file)
@@ -1,8 +1,9 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays html.parser.utils hashtables io kernel
-namespaces make prettyprint quotations sequences splitting
-html.parser.state strings unicode.categories unicode.case ;
+USING: accessors arrays hashtables sequence-parser
+html.parser.utils kernel namespaces sequences
+unicode.case unicode.categories combinators.short-circuit
+quoting fry ;
 IN: html.parser
 
 TUPLE: tag name attributes text closing? ;
@@ -10,6 +11,9 @@ TUPLE: tag name attributes text closing? ;
 SINGLETON: text
 SINGLETON: dtd
 SINGLETON: comment
+
+<PRIVATE
+
 SYMBOL: tagstack
 
 : push-tag ( tag -- )
@@ -17,7 +21,7 @@ SYMBOL: tagstack
 
 : closing-tag? ( string -- ? )
     [ f ]
-    [ [ first ] [ peek ] bi [ CHAR: / = ] bi@ or ] if-empty ;
+    [ { [ first CHAR: / = ] [ peek CHAR: / = ] } 1|| ] if-empty ;
 
 : <tag> ( name attributes closing? -- tag )
     tag new
@@ -28,116 +32,96 @@ SYMBOL: tagstack
 : make-tag ( string attribs -- tag )
     [ [ closing-tag? ] keep "/" trim1 ] dip rot <tag> ;
 
-: make-text-tag ( string -- tag )
+: new-tag ( text name -- tag )
     tag new
-        text >>name
-        swap >>text ;
+        swap >>name
+        swap >>text ; inline
 
-: make-comment-tag ( string -- tag )
-    tag new
-        comment >>name
-        swap >>text ;
+: (read-quote) ( sequence-parser ch -- string )
+    '[ [ current _ = ] take-until ] [ advance drop ] bi ;
 
-: make-dtd-tag ( string -- tag )
-    tag new
-        dtd >>name
-        swap >>text ;
+: read-single-quote ( sequence-parser -- string )
+    CHAR: ' (read-quote) ;
 
-: read-whitespace ( -- string )
-    [ get-char blank? not ] take-until ;
+: read-double-quote ( sequence-parser -- string )
+    CHAR: " (read-quote) ;
 
-: read-whitespace* ( -- ) read-whitespace drop ;
+: read-quote ( sequence-parser -- string )
+    dup get+increment CHAR: ' =
+    [ read-single-quote ] [ read-double-quote ] if ;
 
-: read-token ( -- string )
-    read-whitespace*
-    [ get-char blank? ] take-until ;
+: read-key ( sequence-parser -- string )
+    skip-whitespace
+    [ current { [ CHAR: = = ] [ blank? ] } 1|| ] take-until ;
 
-: read-single-quote ( -- string )
-    [ get-char CHAR: ' = ] take-until ;
+: read-token ( sequence-parser -- string )
+    [ current blank? ] take-until ;
 
-: read-double-quote ( -- string )
-    [ get-char CHAR: " = ] take-until ;
+: read-value ( sequence-parser -- string )
+    skip-whitespace
+    dup current quote? [ read-quote ] [ read-token ] if
+    [ blank? ] trim ;
 
-: read-quote ( -- string )
-    get-char next CHAR: ' =
-    [ read-single-quote ] [ read-double-quote ] if next ;
+: read-comment ( sequence-parser -- )
+    "-->" take-until-sequence comment new-tag push-tag ;
 
-: read-key ( -- string )
-    read-whitespace*
-    [ get-char [ CHAR: = = ] [ blank? ] bi or ] take-until ;
+: read-dtd ( sequence-parser -- )
+    ">" take-until-sequence dtd new-tag push-tag ;
 
-: read-= ( -- )
-    read-whitespace*
-    [ get-char CHAR: = = ] take-until drop next ;
+: read-bang ( sequence-parser -- )
+    advance dup { [ current CHAR: - = ] [ peek-next CHAR: - = ] } 1&&
+    [ advance advance read-comment ] [ read-dtd ] if ;
 
-: read-value ( -- string )
-    read-whitespace*
-    get-char quote? [ read-quote ] [ read-token ] if
-    [ blank? ] trim ;
+: read-tag ( sequence-parser -- string )
+    [ [ current "><" member? ] take-until ]
+    [ dup current CHAR: < = [ advance ] unless drop ] bi ;
 
-: read-comment ( -- )
-    "-->" take-string make-comment-tag push-tag ;
+: read-until-< ( sequence-parser -- string )
+    [ current CHAR: < = ] take-until ;
 
-: read-dtd ( -- )
-    ">" take-string make-dtd-tag push-tag ;
+: parse-text ( sequence-parser -- )
+    read-until-< [ text new-tag push-tag ] unless-empty ;
 
-: read-bang ( -- )
-    next get-char CHAR: - = get-next CHAR: - = and [
-        next next
-        read-comment
-    ] [
-        read-dtd
-    ] if ;
+: parse-key/value ( sequence-parser -- key value )
+    [ read-key >lower ]
+    [ skip-whitespace "=" take-sequence ]
+    [ swap [ read-value ] [ drop dup ] if ] tri ;
 
-: read-tag ( -- string )
-    [ get-char CHAR: > = get-char CHAR: < = or ] take-until
-    get-char CHAR: < = [ next ] unless ;
-
-: read-< ( -- string )
-    next get-char CHAR: ! = [
-        read-bang f
+: (parse-attributes) ( sequence-parser -- )
+    skip-whitespace
+    dup sequence-parse-end? [
+        drop
     ] [
-        read-tag
+        [ parse-key/value swap set ] [ (parse-attributes) ] bi
     ] if ;
 
-: read-until-< ( -- string )
-    [ get-char CHAR: < = ] take-until ;
+: parse-attributes ( sequence-parser -- hashtable )
+    [ (parse-attributes) ] H{ } make-assoc ;
 
-: parse-text ( -- )
-    read-until-< [
-        make-text-tag push-tag
-    ] unless-empty ;
+: (parse-tag) ( string -- string' hashtable )
+    [
+        [ read-token >lower ] [ parse-attributes ] bi
+    ] parse-sequence ;
 
-: (parse-attributes) ( -- )
-    read-whitespace*
-    string-parse-end? [
-        read-key >lower read-= read-value
-        2array , (parse-attributes)
-    ] unless ;
+: read-< ( sequence-parser -- string/f )
+    advance dup current [
+        CHAR: ! = [ read-bang f ] [ read-tag ] if
+    ] [
+        drop f
+    ] if* ;
 
-: parse-attributes ( -- hashtable )
-    [ (parse-attributes) ] { } make >hashtable ;
+: parse-tag ( sequence-parser -- )
+    read-< [ (parse-tag) make-tag push-tag ] unless-empty ;
 
-: (parse-tag) ( string -- string' hashtable )
-    [
-        read-token >lower
-        parse-attributes
-    ] string-parse ;
-
-: parse-tag ( -- )
-    read-< [
-        (parse-tag) make-tag push-tag
-    ] unless-empty ;
-
-: (parse-html) ( -- )
-    get-next [
-        parse-text
-        parse-tag
-        (parse-html)
-    ] when ;
+: (parse-html) ( sequence-parser -- )
+    dup peek-next [
+        [ parse-text ] [ parse-tag ] [ (parse-html) ] tri
+    ] [ drop ] if ;
 
 : tag-parse ( quot -- vector )
-    V{ } clone tagstack [ string-parse ] with-variable ;
+    V{ } clone tagstack [ parse-sequence ] with-variable ; inline
+
+PRIVATE>
 
 : parse-html ( string -- vector )
     [ (parse-html) tagstack get ] tag-parse ;
diff --git a/extra/html/parser/state/state-tests.factor b/extra/html/parser/state/state-tests.factor
deleted file mode 100644 (file)
index a9be38c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-USING: tools.test html.parser.state ascii kernel ;
-IN: html.parser.state.tests
-
-: take-rest ( -- string )
-    [ f ] take-until ;
-
-: take-char ( -- string )
-    [ get-char = ] curry take-until ;
-
-[ "hello" ] [ "hello" [ take-rest ] string-parse ] unit-test
-[ "hi" " how are you?" ] [ "hi how are you?" [ [ get-char blank? ] take-until take-rest ] string-parse ] unit-test
-[ "foo" ";bar" ] [ "foo;bar" [ CHAR: ; take-char take-rest ] string-parse ] unit-test
-! [ "foo " " bar" ] [ "foo and bar" [ "and" take-string take-rest ] string-parse ] unit-test
diff --git a/extra/html/parser/state/state.factor b/extra/html/parser/state/state.factor
deleted file mode 100644 (file)
index 4b1027d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-! Copyright (C) 2005, 2009 Daniel Ehrenberg
-! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces math kernel sequences accessors fry circular ;
-IN: html.parser.state
-
-TUPLE: state string i ;
-
-: get-i ( -- i ) state get i>> ;
-
-: get-char ( -- char )
-    state get [ i>> ] [ string>> ] bi ?nth ;
-
-: get-next ( -- char )
-    state get [ i>> 1+ ] [ string>> ] bi ?nth ;
-
-: next ( -- )
-    state get [ 1+ ] change-i drop ;
-
-: string-parse ( string quot -- )
-    [ 0 state boa state ] dip with-variable ;
-
-: short* ( n seq -- n' seq )
-    over [ nip dup length swap ] unless ;
-
-: skip-until ( quot: ( -- ? ) -- )
-    get-char [
-        [ call ] keep swap
-        [ drop ] [ next skip-until ] if
-    ] [ drop ] if ; inline recursive
-
-: take-until ( quot: ( -- ? ) -- )
-    [ get-i ] dip skip-until get-i
-    state get string>> subseq ;
-
-: string-matches? ( string circular -- ? )
-    get-char over push-circular sequence= ;
-
-: take-string ( match -- string )
-    dup length <circular-string>
-    [ 2dup string-matches? ] take-until nip
-    dup length rot length 1- - head next ;
index 6d8e3bc05f07128f9c288fd3247ecd74ef30d905..ec6780687d7e434bf0c11b1a71aff9a6d78f96e1 100644 (file)
@@ -1,20 +1,13 @@
 USING: assocs combinators continuations hashtables
 hashtables.private io kernel math
 namespaces prettyprint quotations sequences splitting
-strings tools.test ;
-USING: html.parser.utils ;
+strings tools.test html.parser.utils quoting ;
 IN: html.parser.utils.tests
 
 [ "'Rome'" ] [ "Rome" single-quote ] unit-test
 [ "\"Roma\"" ] [ "Roma" double-quote ] unit-test
 [ "'Firenze'" ] [ "Firenze" quote ] unit-test
 [ "\"Caesar's\"" ] [ "Caesar's" quote ] unit-test
-[ f ] [ "" quoted? ] unit-test
-[ t ] [ "''" quoted? ] unit-test
-[ t ] [ "\"\"" quoted? ] unit-test
-[ t ] [ "\"Circus Maximus\"" quoted? ] unit-test
-[ t ] [ "'Circus Maximus'" quoted? ] unit-test
-[ f ] [ "Circus Maximus" quoted? ] unit-test
 [ "'Italy'" ] [ "Italy" ?quote ] unit-test
 [ "'Italy'" ] [ "'Italy'" ?quote ] unit-test
 [ "\"Italy\"" ] [ "\"Italy\"" ?quote ] unit-test
index c913b9d306cebd77db6e8785706300fb7063b73e..afd63daf6bf241bca2c96f4f117501ca8fb42855 100644 (file)
@@ -2,17 +2,13 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs circular combinators continuations hashtables
 hashtables.private io kernel math namespaces prettyprint
-quotations sequences splitting html.parser.state strings
+quotations sequences splitting strings quoting
 combinators.short-circuit ;
 IN: html.parser.utils
 
-: string-parse-end? ( -- ? ) get-next not ;
-
 : trim1 ( seq ch -- newseq )
     [ [ ?head-slice drop ] [ ?tail-slice drop ] bi ] 2keep drop like ;
 
-: quote? ( ch -- ? ) "'\"" member? ;
-
 : single-quote ( str -- newstr ) "'" dup surround ;
 
 : double-quote ( str -- newstr ) "\"" dup surround ;
@@ -21,14 +17,4 @@ IN: html.parser.utils
     CHAR: ' over member?
     [ double-quote ] [ single-quote ] if ;
 
-: quoted? ( str -- ? )
-    {
-        [ length 1 > ]
-        [ first quote? ]
-        [ [ first ] [ peek ] bi = ]
-    } 1&& ;
-
 : ?quote ( str -- newstr ) dup quoted? [ quote ] unless ;
-
-: unquote ( str -- newstr )
-    dup quoted? [ but-last-slice rest-slice >string ] when ;
index d171d037984b08f74d49947d6d38252a9238239e..c43559a630f91f26e2161ee0dd4d4c8d92d486d0 100644 (file)
 ! Copyright (C) 2008 Tim Wawrzynczak
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax sequences kernel accessors ;
+USING: help.markup help.syntax sequences kernel accessors
+id3.private strings ;
 IN: id3
 
-HELP: file-id3-tags
+HELP: mp3>id3
 { $values 
     { "path" "a path string" } 
-    { "id3v2-info/f" "a tuple storing ID3v2 metadata or f" } }
-    { $description "Return a tuple containing the ID3 information parsed out of the MP3 file, or " { $link f } " if no metadata is present.  Currently, the parser supports the following tags: "
-      $nl { $link title>> }
-      $nl { $link artist>> }
-      $nl { $link album>> }
-      $nl { $link year>> }
-      $nl { $link genre>> }
-      $nl { $link comment>> } } ;
+    { "id3/f" "a tuple storing ID3v2 metadata or f" } }
+    { $description "Return a tuple containing the ID3 information parsed out of the MP3 file, or " { $link f } " if no metadata is present. Words to access the ID3v1 information are here:"
+        { $list
+          { $link title }
+          { $link artist }
+          { $link album }
+          { $link year }
+          { $link genre }
+          { $link comment }
+        }
+        "For other fields, use the " { $link find-id3-frame } " word."
+    } ;
+
+HELP: album
+{ $values
+    { "id3" id3 }
+    { "string/f" "string or f" }
+}
+{ $description "Returns the album, or " { $link f } " if this field is missing, from a parsed id3 tag." } ;
+
+HELP: artist
+{ $values
+    { "id3" id3 }
+    { "string/f" "string or f" }
+}
+{ $description "Returns the artist, or " { $link f } " if this field is missing, from a parsed id3 tag." } ;
+
+HELP: comment
+{ $values
+    { "id3" id3 }
+    { "string/f" "string or f" }
+}
+{ $description "Returns the comment, or " { $link f } " if this field is missing, from a parsed id3 tag." } ;
+
+HELP: genre
+{ $values
+    { "id3" id3 }
+    { "string/f" "string or f" }
+}
+{ $description "Returns the genre, or " { $link f } " if this field is missing, from a parsed id3 tag." } ;
+
+HELP: title
+{ $values
+    { "id3" id3 }
+    { "string/f" "string or f" }
+}
+{ $description "Returns the title, or " { $link f } " if this field is missing, from a parsed id3 tag." } ;
+
+HELP: year
+{ $values
+    { "id3" id3 }
+    { "string/f" "string or f" }
+}
+{ $description "Returns the year, or " { $link f } " if this field is missing, from a parsed id3 tag." } ;
+
+HELP: find-id3-frame
+{ $values
+    { "id3" id3 } { "name" string }
+    { "obj/f" "object or f" }
+}
+{ $description "Returns the " { $slot "data" } " slot of the ID3 frame with the given name, or " { $link f } "." } ;
+
+HELP: mp3-paths>id3s
+{ $values
+    { "seq" sequence }
+    { "seq'" sequence }
+}
+{ $description "From a sequence of pathnames, parses each ID3 header and returns a sequence of key/value pairs of pathnames and ID3 objects." } ;
+
+HELP: find-mp3s
+{ $values
+    { "path" "a pathname string" }
+    { "seq" sequence }
+}
+{ $description "Returns a sequence of MP3 pathnames from a directory and all of its subdirectories." } ;
+
+HELP: parse-mp3-directory
+{ $values
+    { "path" "a pathname string" }
+    { "seq" sequence }
+}
+{ $description "Returns a sequence of key/value pairs where the key is the path of an MP3 and the value is the parsed ID3 header or " { $link f } " recursively for each MP3 file in the directory and all subdirectories." } ;
 
 ARTICLE: "id3" "ID3 tags"
 "The " { $vocab-link "id3" } " vocabulary contains words for parsing " { $emphasis "ID3" } " tags, which are textual fields storing an MP3's title, artist, and other metadata." $nl
-"Parsing ID3 tags from an MP3 file:"
-{ $subsection file-id3-tags } ;
+"Parsing ID3 tags for a directory of MP3s, recursively:"
+{ $subsection parse-mp3-directory }
+"Finding MP3 files recursively:"
+{ $subsection find-mp3s }
+"Parsing a sequence of MP3 pathnames:"
+{ $subsection mp3-paths>id3s }
+"Parsing an MP3 file's ID3 tags:"
+{ $subsection mp3>id3 }
+"ID3v1 frame tag accessors:"
+{ $subsection album }
+{ $subsection artist }
+{ $subsection comment }
+{ $subsection genre }
+{ $subsection title }
+{ $subsection year }
+"Access any frame tag:"
+{ $subsection find-id3-frame } ;
 
 ABOUT: "id3"
index aefbec8550b6c37eb46570e26bd2ab8254c5f6c4..9bb755807771054a1aaf8cda2a74ec6abd8f058d 100644 (file)
@@ -1,16 +1,17 @@
 ! Copyright (C) 2009 Tim Wawrzynczak
 ! See http://factorcode.org/license.txt for BSD license.
-USING: tools.test id3 combinators ;
+USING: tools.test id3 combinators grouping id3.private
+sequences math ;
 IN: id3.tests
 
 : id3-params ( id3 -- title artist album year comment genre )
     {
-        [ id3-title ]
-        [ id3-artist ]
-        [ id3-album ]
-        [ id3-year ]
-        [ id3-comment ]
-        [ id3-genre ]
+        [ title ]
+        [ artist ]
+        [ album ]
+        [ year ]
+        [ comment ]
+        [ genre ]
     } cleave ;
 
 [
@@ -20,7 +21,7 @@ IN: id3.tests
    "2009"
    "COMMENT"
    "Bluegrass"
-] [ "vocab:id3/tests/blah.mp3" file-id3-tags id3-params ] unit-test
+] [ "vocab:id3/tests/blah.mp3" mp3>id3 id3-params ] unit-test
 
 [
     "Anthem of the Trinity"
@@ -29,7 +30,7 @@ IN: id3.tests
     f
     f
     "Classical"
-] [ "vocab:id3/tests/blah2.mp3" file-id3-tags id3-params ] unit-test
+] [ "vocab:id3/tests/blah2.mp3" mp3>id3 id3-params ] unit-test
 
 [    
    "Stormy Weather"
@@ -38,5 +39,8 @@ IN: id3.tests
     f
    "eng, AG# 08E1C12E"
    "Big Band"
-] [ "vocab:id3/tests/blah3.mp3" file-id3-tags id3-params ] unit-test
+] [ "vocab:id3/tests/blah3.mp3" mp3>id3 id3-params ] unit-test
 
+
+[ t ]
+[ 10000 [ synchsafe>seq seq>synchsafe ] map [ < ] monotonic? ] unit-test
index 3def293771e77a738604e205f88dab6573253302..a5671a5822811364fc8906e5e67f46ed9bc0a416 100644 (file)
@@ -6,7 +6,7 @@ combinators math.ranges unicode.categories byte-arrays
 io.encodings.string io.encodings.utf16 assocs math.parser
 combinators.short-circuit fry namespaces combinators.smart
 splitting io.encodings.ascii arrays io.files.info unicode.case
-io.directories.search ;
+io.directories.search literals math.functions ;
 IN: id3
 
 <PRIVATE
@@ -37,108 +37,132 @@ CONSTANT: genres
         "Primus" "Porn Groove" "Satire" "Slow Jam" "Club" "Tango" 
         "Samba" "Folklore" "Ballad" "Power Ballad" "Rhythmic Soul" 
         "Freestyle" "Duet" "Punk Rock" "Drum Solo" "A capella" 
-        "Euro-House" "Dance Hall"
+        "Euro-House" "Dance Hall" "Goa" "Drum & Bass" "Club-House"
+        "Hardcore" "Terror" "Indie" "BritPop" "Negerpunk"
+        "Polsk Punk" "Beat" "Christian Gangsta Rap" "Heavy Metal"
+        "Black Metal" "Crossover" "Contemporary Christian"
+        "Christian Rock"
     }
 
 TUPLE: header version flags size ;
 
-TUPLE: frame frame-id flags size data ;
+TUPLE: frame tag flags size data ;
 
-TUPLE: id3v2-info header frames ;
+TUPLE: id3 header frames
+title artist album year comment genre
+speed genre-name start-time end-time ;
 
-TUPLE: id3v1-info title artist album year comment genre ;
+: <id3> ( -- id3 )
+    id3 new
+    H{ } clone >>frames ; inline
 
-: <id3v1-info> ( -- object ) id3v1-info new ;
+: <header> ( -- object ) header new ; inline
 
-: <id3v2-info> ( header frames -- object )
-    [ [ frame-id>> ] keep ] H{ } map>assoc
-    id3v2-info boa ;
+: <frame> ( -- object ) frame new ; inline
 
-: <header> ( -- object ) header new ;
+: id3v2? ( seq -- ? ) "ID3" head? ; inline
 
-: <frame> ( -- object ) frame new ;
+CONSTANT: id3v1-length 128
+CONSTANT: id3v1-offset 128
+CONSTANT: id3v1+-length 227
+CONSTANT: id3v1+-offset $[ 128 227 + ]
 
-: id3v2? ( mmap -- ? ) "ID3" head? ; inline
-
-: id3v1? ( mmap -- ? )
-    { [ length 128 >= ] [ 128 tail-slice* "TAG" head? ] } 1&& ; inline
+: id3v1? ( seq -- ? )
+    {
+        [ length id3v1-offset >= ]
+        [ id3v1-length tail-slice* "TAG" head? ]
+    } 1&& ;
 
-: id3v1-frame ( string key -- frame )
-    <frame>
-        swap >>frame-id
-        swap >>data ;
+: id3v1+? ( seq -- ? )
+    {
+        [ length id3v1+-offset >= ]
+        [ id3v1+-length tail-slice* "TAG+" head? ]
+    } 1&& ;
+
+: pair>frame ( string key -- frame/f )
+    over [
+        <frame>
+            swap >>tag
+            swap >>data
+    ] [
+        2drop f
+    ] if ;
 
-: id3v1>id3v2 ( id3v1 -- id3v2 )
+: id3v1>frames ( id3v1 -- seq )
     [
         {
-            [ title>> "TIT2" id3v1-frame ]
-            [ artist>> "TPE1" id3v1-frame ]
-            [ album>> "TALB" id3v1-frame ]
-            [ year>> "TYER" id3v1-frame ]
-            [ comment>> "COMM" id3v1-frame ]
-            [ genre>> "TCON" id3v1-frame ]
+            [ title>> "TIT2" pair>frame ]
+            [ artist>> "TPE1" pair>frame ]
+            [ album>> "TALB" pair>frame ]
+            [ year>> "TYER" pair>frame ]
+            [ comment>> "COMM" pair>frame ]
+            [ genre>> "TCON" pair>frame ]
         } cleave
-    ] output>array f swap <id3v2-info> ;
+    ] output>array sift ;
 
-: >28bitword ( seq -- int )
-    0 [ [ 7 shift ] dip bitor ] reduce ; inline
+: seq>synchsafe ( seq -- n )
+    0 [ [ 7 shift ] dip bitor ] reduce ;
+
+: synchsafe>seq ( n -- seq )
+    dup 1+ log2 1+ 7 / ceiling
+    [ [ -7 shift ] keep HEX: 7f bitand  ] replicate nip reverse ;
 
 : filter-text-data ( data -- filtered )
-    [ printable? ] filter ; inline
+    [ printable? ] filter ;
 
-: valid-frame-id? ( id -- ? )
-    [ { [ digit? ] [ LETTER? ] } 1|| ] all? ; inline
+: valid-tag? ( id -- ? )
+    [ { [ digit? ] [ LETTER? ] } 1|| ] all? ;
 
-: read-frame-data ( frame mmap -- frame data )
-    [ 10 over size>> 10 + ] dip <slice> filter-text-data ; inline
+: read-frame-data ( frame seq -- frame data )
+    [ 10 over size>> 10 + ] dip <slice> filter-text-data ;
 
 : decode-text ( string -- string' )
     dup 2 short head
     { { HEX: ff HEX: fe } { HEX: fe HEX: ff } } member?
-    utf16 ascii ? decode ; inline
+    utf16 ascii ? decode ;
 
-: (read-frame) ( mmap -- frame )
+: (read-frame) ( seq -- frame )
     [ <frame> ] dip
     {
-        [ 4 head-slice decode-text >>frame-id ]
-        [ [ 4 8 ] dip subseq >28bitword >>size ]
+        [ 4 head-slice decode-text >>tag ]
+        [ [ 4 8 ] dip subseq seq>synchsafe >>size ]
         [ [ 8 10 ] dip subseq >byte-array >>flags ]
         [ read-frame-data decode-text >>data ]
     } cleave ;
 
-: read-frame ( mmap -- frame/f )
-    dup 4 head-slice valid-frame-id?
+: read-frame ( seq -- frame/f )
+    dup 4 head-slice valid-tag?
     [ (read-frame) ] [ drop f ] if ;
 
-: remove-frame ( mmap frame -- mmap )
-    size>> 10 + tail-slice ; inline
+: remove-frame ( seq frame -- seq )
+    size>> 10 + tail-slice ;
 
-: read-frames ( mmap -- frames )
-    [ dup read-frame dup ]
-    [ [ remove-frame ] keep ]
-    produce 2nip ;
-    
-! header stuff
+: frames>assoc ( seq -- assoc )
+    [ [ tag>> ] keep ] H{ } map>assoc ;
 
-: read-v2-header ( seq -- id3header )
+: read-frames ( seq -- assoc )
+    [ dup read-frame dup ] [ [ remove-frame ] keep ] produce 2nip ;
+    
+: read-v2-header ( seq -- header )
     [ <header> ] dip
     {
         [ [ 3 5 ] dip <slice> >array >>version ]
         [ [ 5 ] dip nth >>flags ]
-        [ [ 6 10 ] dip <slice> >28bitword >>size ]
-    } cleave ; inline
+        [ [ 6 10 ] dip <slice> seq>synchsafe >>size ]
+    } cleave ;
 
-: read-v2-tag-data ( seq -- id3v2-info )
-    10 cut-slice
-    [ read-v2-header ]
-    [ read-frames ] bi* <id3v2-info> ; inline
-    
-! v1 information
+: merge-frames ( id3 assoc -- id3 )
+    [ dup frames>> ] dip update ;
 
-: skip-to-v1-data ( seq -- seq ) 125 tail-slice* ; inline
+: merge-id3v1 ( id3 -- id3 )
+    dup id3v1>frames frames>assoc merge-frames ;
 
-: (read-v1-tag-data) ( seq -- mp3-file )
-    [ <id3v1-info> ] dip
+: read-v2-tags ( id3 seq -- id3 )
+    10 cut-slice
+    [ read-v2-header >>header ]
+    [ read-frames frames>assoc merge-frames ] bi* ;
+    
+: extract-v1-tags ( id3 seq -- id3 )
     {
         [ 30 head-slice decode-text filter-text-data >>title ]
         [ [ 30 60 ] dip subseq decode-text filter-text-data >>artist ]
@@ -146,10 +170,32 @@ TUPLE: id3v1-info title artist album year comment genre ;
         [ [ 90 94 ] dip subseq decode-text filter-text-data >>year ]
         [ [ 94 124 ] dip subseq decode-text filter-text-data >>comment ]
         [ [ 124 ] dip nth number>string >>genre ]
-    } cleave ; inline
+    } cleave ;
 
-: read-v1-tag-data ( seq -- mp3-file )
-    skip-to-v1-data (read-v1-tag-data) ; inline
+: read-v1-tags ( id3 seq -- id3 )
+    id3v1-offset tail-slice* 3 tail-slice
+    extract-v1-tags ;
+
+: extract-v1+-tags ( id3 seq -- id3 )
+    {
+        [ 60 head-slice decode-text filter-text-data [ append ] change-title ]
+        [
+            [ 60 120 ] dip subseq decode-text filter-text-data
+            [ append ] change-artist
+        ]
+        [
+            [ 120 180 ] dip subseq decode-text filter-text-data
+            [ append ] change-album
+        ]
+        [ [ 180 ] dip nth >>speed ]
+        [ [ 181 211 ] dip subseq decode-text >>genre-name ]
+        [ [ 211 217 ] dip subseq decode-text >>start-time ]
+        [ [ 217 223 ] dip subseq decode-text >>end-time ]
+    } cleave ;
+
+: read-v1+-tags ( id3 seq -- id3 )
+    id3v1+-offset tail-slice* 4 tail-slice
+    extract-v1+-tags ;
 
 : parse-genre ( string -- n/f )
     dup "(" ?head-slice drop ")" ?tail-slice drop
@@ -157,41 +203,44 @@ TUPLE: id3v1-info title artist album year comment genre ;
         genres ?nth swap or
     ] [
         drop
-    ] if ; inline
+    ] if ;
+
+: (mp3>id3) ( path -- id3v2/f )
+    [
+        [ <id3> ] dip
+        {
+            [ dup id3v1? [ read-v1-tags merge-id3v1 ] [ drop ] if ]
+            [ dup id3v1+? [ read-v1+-tags merge-id3v1 ] [ drop ] if ]
+            [ dup id3v2? [ read-v2-tags ] [ drop ] if ]
+        } cleave
+    ] with-mapped-uchar-file ;
 
 PRIVATE>
 
-: frame-named ( id3 name quot -- obj )
-    [ swap frames>> at* ] dip
-    [ data>> ] prepose [ drop f ] if ; inline
+: mp3>id3 ( path -- id3/f )
+    dup file-info size>> 0 <= [ drop f ] [ (mp3>id3) ] if ;
 
-: id3-title ( id3 -- title/f ) "TIT2" [ ] frame-named ; inline
+: find-id3-frame ( id3 name -- obj/f )
+    swap frames>> at* [ data>> ] when ;
 
-: id3-artist ( id3 -- artist/f ) "TPE1" [ ] frame-named ; inline
+: title ( id3 -- string/f ) "TIT2" find-id3-frame ;
 
-: id3-album ( id3 -- album/f ) "TALB" [ ] frame-named ; inline
+: artist ( id3 -- string/f ) "TPE1" find-id3-frame ;
 
-: id3-year ( id3 -- year/f ) "TYER" [ ] frame-named ; inline
+: album ( id3 -- string/f ) "TALB" find-id3-frame ;
 
-: id3-comment ( id3 -- comment/f ) "COMM" [ ] frame-named ; inline
+: year ( id3 -- string/f ) "TYER" find-id3-frame ;
 
-: id3-genre ( id3 -- genre/f )
-    "TCON" [ parse-genre ] frame-named ; inline
+: comment ( id3 -- string/f ) "COMM" find-id3-frame ;
 
-: id3-frame ( id3 key -- value/f ) [ ] frame-named ; inline
+: genre ( id3 -- string/f )
+    "TCON" find-id3-frame parse-genre ;
 
-: (file-id3-tags) ( path -- id3v2-info/f )
-    [
-        {
-            { [ dup id3v2? ] [ read-v2-tag-data ] }
-            { [ dup id3v1? ] [ read-v1-tag-data id3v1>id3v2 ] }
-            [ drop f ]
-        } cond
-    ] with-mapped-uchar-file ;
+: find-mp3s ( path -- seq )
+    [ >lower ".mp3" tail? ] find-all-files ;
 
-: file-id3-tags ( path -- id3v2-info/f )
-    dup file-info size>> 0 <= [ drop f ] [ (file-id3-tags) ] if ;
+: mp3-paths>id3s ( seq -- seq' )
+    [ dup mp3>id3 ] { } map>assoc ;
 
-: parse-id3s ( path -- seq )
-    [ >lower ".mp3" tail? ] find-all-files
-    [ dup file-id3-tags ] { } map>assoc ;
+: parse-mp3-directory ( path -- seq )
+    find-mp3s mp3-paths>id3s ;
diff --git a/extra/images/normalization/authors.txt b/extra/images/normalization/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/extra/images/normalization/normalization.factor b/extra/images/normalization/normalization.factor
new file mode 100755 (executable)
index 0000000..dcdf39a
--- /dev/null
@@ -0,0 +1,90 @@
+! Copyright (C) 2009 Doug Coleman
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors grouping sequences combinators
+math specialized-arrays.direct.uint byte-arrays fry
+specialized-arrays.direct.ushort specialized-arrays.uint
+specialized-arrays.ushort specialized-arrays.float images ;
+IN: images.normalization
+
+<PRIVATE
+
+: add-dummy-alpha ( seq -- seq' )
+    3 <groups> [ 255 suffix ] map concat ;
+
+: normalize-floats ( byte-array -- byte-array )
+    byte-array>float-array [ 255.0 * >integer ] B{ } map-as ;
+
+GENERIC: normalize-component-order* ( image component-order -- image )
+
+: normalize-component-order ( image -- image )
+    dup component-order>> '[ _ normalize-component-order* ] change-bitmap ;
+
+M: RGBA normalize-component-order* drop ;
+
+M: R32G32B32A32 normalize-component-order*
+    drop normalize-floats ;
+
+M: R32G32B32 normalize-component-order*
+    drop normalize-floats add-dummy-alpha ;
+
+: RGB16>8 ( bitmap -- bitmap' )
+    byte-array>ushort-array [ -8 shift ] B{ } map-as ; inline
+
+M: R16G16B16A16 normalize-component-order*
+    drop RGB16>8 ;
+
+M: R16G16B16 normalize-component-order*
+    drop RGB16>8 add-dummy-alpha ;
+
+: BGR>RGB ( bitmap -- pixels )
+    3 <sliced-groups> [ <reversed> ] map B{ } join ; inline
+
+: BGRA>RGBA ( bitmap -- pixels )
+    4 <sliced-groups>
+    [ unclip-last-slice [ <reversed> ] dip suffix ] map concat ; inline
+
+M: BGRA normalize-component-order*
+    drop BGRA>RGBA ;
+
+M: RGB normalize-component-order*
+    drop add-dummy-alpha ;
+
+M: BGR normalize-component-order*
+    drop BGR>RGB add-dummy-alpha ;
+
+: ARGB>RGBA ( bitmap -- bitmap' )
+    4 <groups> [ unclip suffix ] map B{ } join ; inline
+
+M: ARGB normalize-component-order*
+    drop ARGB>RGBA ;
+
+M: ABGR normalize-component-order*
+    drop ARGB>RGBA BGRA>RGBA ;
+
+: fix-XBGR ( bitmap -- bitmap' )
+    dup 4 <sliced-groups> [ [ 255 0 ] dip set-nth ] each ;
+
+M: XBGR normalize-component-order*
+    drop fix-XBGR ABGR normalize-component-order* ;
+
+: fix-BGRX ( bitmap -- bitmap' )
+    dup 4 <sliced-groups> [ [ 255 3 ] dip set-nth ] each ;
+
+M: BGRX normalize-component-order*
+    drop fix-BGRX BGRA normalize-component-order* ;
+
+: normalize-scan-line-order ( image -- image )
+    dup upside-down?>> [
+        dup dim>> first 4 * '[
+            _ <groups> reverse concat
+        ] change-bitmap
+        f >>upside-down?
+    ] when ;
+
+PRIVATE>
+
+: normalize-image ( image -- image )
+    [ >byte-array ] change-bitmap
+    normalize-component-order
+    normalize-scan-line-order
+    RGBA >>component-order ;
index 7e8e2dfcc97c2ecfa4342a3b0142cdea5c4cb87f..5e3d5d67cb6eb913c7469f60106154690258e84c 100644 (file)
@@ -31,8 +31,6 @@ IN: infix.tests
 [ f ] [ 2 \ gcd check-word ] unit-test ! multiple return values
 [ f ] [ 1 \ drop check-word ] unit-test ! no return value
 [ f ] [ 1 \ lcm check-word ] unit-test ! takes 2 args
-: no-stack-effect-declared + ;
-[ 0 \ no-stack-effect-declared check-word ] must-fail
 
 : qux ( -- x ) 2 ;
 [ t ] [ 0 \ qux check-word ] unit-test
index 87080683b2c4e773ca27b2dff05531f88656a7d6..ed268e558daaee26b47325b1ef03b13c6672861b 100644 (file)
@@ -81,8 +81,8 @@ M: ast-function infix-codegen
     infix-codegen prepare-operand ;
 PRIVATE>
 
-: [infix
-    "infix]" [infix-parse parsed \ call parsed ; parsing
+SYNTAX: [infix
+    "infix]" [infix-parse parsed \ call parsed ;
 
 <PRIVATE
 : parse-infix-locals ( assoc end -- quot )
@@ -93,6 +93,6 @@ PRIVATE>
     ] with-scope ;
 PRIVATE>
 
-: [infix|
+SYNTAX: [infix|
     "|" parse-bindings "infix]" parse-infix-locals <let>
-    ?rewrite-closures over push-all ; parsing
+    ?rewrite-closures over push-all ;
index e9b8d78e4b7fd9ffd5540026bd5b13bf94cb4590..f4c0c6b45a4cbc91ce9862867c11dc20291c4b2b 100644 (file)
@@ -5,7 +5,10 @@ IN: io.serial.unix
 
 : serial-obj ( -- obj )
     serial new
-    "/dev/ttyS0" >>path
+    "/dev/ttyS0" >>path ! linux
+    ! "/dev/dty00" >>path ! netbsd
+    ! "/dev/ttyd0" >>path ! freebsd
+    ! "/dev/ttyU0" >>path ! openbsd
     19200 >>baud
     { IGNPAR ICRNL } flags >>iflag
     { } flags >>oflag
index c82f2e292c3e21f694b168770aae1759ecdc8ff6..97fa65920908c5494a119c35f4cc6edfd22d194b 100755 (executable)
@@ -165,7 +165,7 @@ M: irc-chat to-chat in-messages>> mailbox-put ;
     " hostname servername :irc.factor" irc-print ;
 
 : /CONNECT ( server port -- stream )
-    irc> connect>> call drop ;
+    irc> connect>> call drop ; inline
 
 : /JOIN ( channel password -- )
     "JOIN " irc-write
index e2ca8816d9822a3ccb094aa50386cffecc721d18..70035f18546769168ee95181ffa24f5c9775ac44 100644 (file)
@@ -9,6 +9,6 @@ IN: lint.tests
 : lint2 ( n -- n' ) 1 + ; ! 1+
 [ { [ 1 + ] } ] [ \ lint2 lint ] unit-test
 
-: lint3 dup -rot ; ! tuck
+: lint3 ( a b -- b a b ) dup -rot ; ! tuck
 
 [ { { lint3 { [ dup -rot ] } } } ] [ \ lint3 lint-word ] unit-test
index 6525264f6a59815975a432734e8ef468a9fa6535..0d61dcb467534b754c888e9131ed131fe90bba00 100644 (file)
@@ -21,7 +21,7 @@ CONSTANT: five 5
 USING: kernel literals prettyprint ;
 IN: scratchpad
 
-<< : seven-eleven 7 11 ; >>
+<< : seven-eleven ( -- a b ) 7 11 ; >>
 { $ seven-eleven } .
     "> "{ 7 11 }" }
 
@@ -37,7 +37,7 @@ HELP: $[
 USING: kernel literals math prettyprint ;
 IN: scratchpad
 
-<< : five 5 ; >>
+<< CONSTANT: five 5 >>
 { $[ five dup 1+ dup 2 + ] } .
     "> "{ 5 6 8 }" }
 
@@ -51,7 +51,7 @@ ARTICLE: "literals" "Interpolating code results into literal values"
 USING: kernel literals math prettyprint ;
 IN: scratchpad
 
-<< : five 5 ; >>
+<< CONSTANT: five 5 >>
 { $ five $[ five dup 1+ dup 2 + ] } .
     "> "{ 5 5 6 8 }" }
 { $subsection POSTPONE: $ }
index 6bff666f072c0672a19e6810ca644adc4e288989..e55d78ab6ef183781192d04f69da15f90b4ded77 100644 (file)
@@ -2,5 +2,5 @@
 USING: accessors continuations kernel parser words quotations vectors ;
 IN: literals
 
-: $ scan-word [ def>> call ] curry with-datastack >vector ; parsing
-: $[ parse-quotation with-datastack >vector ; parsing
+SYNTAX: $ scan-word [ def>> call ] curry with-datastack >vector ;
+SYNTAX: $[ parse-quotation with-datastack >vector ;
index 706dc126161d276dfff17a488a025319e2cad0e5..90ca1d31ff3938c4b23526b8351b1d68d9f8ec8f 100644 (file)
@@ -5,6 +5,8 @@ io.files io.launcher mason.child mason.cleanup mason.common
 mason.help mason.release mason.report namespaces prettyprint ;
 IN: mason.build
 
+QUALIFIED: continuations
+
 : create-build-dir ( -- )
     now datestamp stamp set
     build-dir make-directory ;
@@ -21,10 +23,11 @@ IN: mason.build
     create-build-dir
     enter-build-dir
     clone-builds-factor
-    record-id
-    build-child
-    upload-help
-    release
-    cleanup ;
+    [
+        record-id
+        build-child
+        upload-help
+        release
+    ] [ cleanup ] [ ] continuations:cleanup ;
 
-MAIN: build
\ No newline at end of file
+MAIN: build
index 104360e1fa9aa01527d0152331066e9fcf486633..27bb42ed074ad465cda3cc4fefb2868ad39e8b4f 100644 (file)
@@ -32,3 +32,11 @@ USING: mason.child mason.config tools.test namespaces ;
         boot-cmd
     ] with-scope
 ] unit-test
+
+[ { "./factor.com" "-i=boot.x86.32.image" "-no-user-init" } ] [
+    [
+        "winnt" target-os set
+        "x86.32" target-cpu set
+        boot-cmd
+    ] with-scope
+] unit-test
old mode 100644 (file)
new mode 100755 (executable)
index 1999c76..feb1193
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008, 2009 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays calendar combinators.short-circuit
-continuations debugger http.client io.directories io.files io.launcher
+continuations debugger io.directories io.files io.launcher
 io.pathnames io.encodings.ascii kernel make mason.common mason.config
 mason.platform mason.report mason.email namespaces sequences ;
 IN: mason.child
@@ -9,20 +9,8 @@ IN: mason.child
 : make-cmd ( -- args )
     gnu-make platform 2array ;
 
-: dll-url ( -- url )
-    "http://factorcode.org/dlls/"
-    target-cpu get "x86.64" = [ "64/" append ] when ;
-
-: download-dlls ( -- )
-    target-os get "winnt" = [
-        dll-url "build-support/dlls.txt" ascii file-lines
-        [ append download ] with each
-    ] when ;
-
 : make-vm ( -- )
     "factor" [
-        download-dlls
-
         <process>
             make-cmd >>command
             "../compile-log" >>stdout
@@ -37,8 +25,11 @@ IN: mason.child
     builds-factor-image "." copy-file-into
     builds-factor-image "factor" copy-file-into ;
 
+: factor-vm ( -- string )
+    target-os get "winnt" = "./factor.com" "./factor" ? ;
+
 : boot-cmd ( -- cmd )
-    "./factor"
+    factor-vm
     "-i=" boot-image-name append
     "-no-user-init"
     3array ;
@@ -54,7 +45,7 @@ IN: mason.child
         try-process
     ] with-directory ;
 
-: test-cmd ( -- cmd ) { "./factor" "-run=mason.test" } ;
+: test-cmd ( -- cmd ) factor-vm "-run=mason.test" 2array ;
 
 : test ( -- )
     "factor" [
@@ -67,7 +58,7 @@ IN: mason.child
         try-process
     ] with-directory ;
 
-: return-with ( obj -- ) return-continuation get continue-with ;
+: return-with ( obj -- ) return-continuation get continue-with ;
 
 : build-clean? ( -- ? )
     {
index 1b2697a5d1cba3ade471428c3318b4f24058e877..52e1608885f6e3901de4250523d8fbc2aa4ecddc 100644 (file)
@@ -16,7 +16,7 @@ IN: mason.report
     "git id: " write "git-id" eval-file print nl ;
 
 : with-report ( quot -- )
-    [ "report" utf8 ] dip '[ common-report @ ] with-file-writer ;
+    [ "report" utf8 ] dip '[ common-report @ ] with-file-writer ; inline
 
 : compile-failed-report ( error -- )
     [
index a15a96c63eaea977e65ee81fcc682affe86641b5..bc00f659fa5ae87625628c001a4e1726ec56635c 100644 (file)
@@ -4,7 +4,7 @@ USING: accessors assocs benchmark bootstrap.stage2
 compiler.errors generic help.html help.lint io.directories
 io.encodings.utf8 io.files kernel mason.common math namespaces
 prettyprint sequences sets sorting tools.test tools.time
-tools.vocabs words ;
+tools.vocabs words system io ;
 IN: mason.test
 
 : do-load ( -- )
@@ -44,9 +44,19 @@ M: method-body word-vocabulary "method-generic" word-prop word-vocabulary ;
 : benchmark-ms ( quot -- ms )
     benchmark 1000 /i ; inline
 
+: check-boot-image ( -- )
+    "" to-refresh drop 2dup [ empty? not ] either?
+    [
+        "Boot image is out of date. Changed vocabs:" print
+        append prune [ print ] each
+        flush
+        1 exit
+    ] [ 2drop ] if ;
+
 : do-all ( -- )
     ".." [
         bootstrap-time get boot-time-file to-file
+        check-boot-image
         [ do-load do-compile-errors ] benchmark-ms load-time-file to-file
         [ generate-help ] benchmark-ms html-help-time-file to-file
         [ do-tests ] benchmark-ms test-time-file to-file
index 1d10e07ceaaf9be7fdac9c3a332c522e563ed19e..cdbd5eef39c283385a769c1c4b46fd851f5f605c 100644 (file)
@@ -33,6 +33,12 @@ IN: math.affine-transforms.tests
     dup inverse-transform a.
 ] unit-test
 
+{ 2.0 -1.0 } { -1.0 -2.0 } { 5.0 -6.0 } <affine-transform> 1array [
+    { 1.0 0.0 } { 0.0 -1.0 } { 0.0 0.0 } <affine-transform>
+    { 2.0 1.0 } { -1.0 2.0 } { 5.0 6.0 } <affine-transform>
+    a.
+] unit-test
+
 [ t ] [
     { 0.01  0.02  } { 0.03  0.04  } { 0.05  0.06  } <affine-transform>
     { 0.011 0.021 } { 0.031 0.041 } { 0.051 0.061 } <affine-transform> 0.01 a~
index 822af51614eb7f1d61c49882864a2697f122a215..20b73ba67884c2bdddb34e9399f4a6d4f0844151 100644 (file)
@@ -3,11 +3,14 @@ USING: accessors arrays combinators combinators.short-circuit kernel math math.v
 math.functions sequences ;
 IN: math.affine-transforms
 
-TUPLE: affine-transform x y origin ;
+TUPLE: affine-transform { x read-only } { y read-only } { origin read-only } ;
 C: <affine-transform> affine-transform
 
 CONSTANT: identity-transform T{ affine-transform f { 1.0 0.0 } { 0.0 1.0 } { 0.0 0.0 } }
 
+: axes ( a -- a' )
+     [ x>> ] [ y>> ] bi { 0.0 0.0 } <affine-transform> ;
+
 : a.v ( a v -- v )
     [ [ x>> ] [ first  ] bi* v*n ]
     [ [ y>> ] [ second ] bi* v*n ]
@@ -23,7 +26,7 @@ CONSTANT: identity-transform T{ affine-transform f { 1.0 0.0 } { 0.0 1.0 } { 0.0
     [ 0.0 2array ] [ 0.0 swap 2array ] bi* { 0.0 0.0 } <affine-transform> ;
 
 : center-rotation ( transform center -- transform )
-    [ clone dup ] dip [ vneg a.v ] [ v+ ] bi >>origin ;
+    [ [ x>> ] [ y>> ] [ ] tri ] dip [ vneg a.v ] [ v+ ] bi <affine-transform> ;
     
 : flatten-transform ( transform -- array )
     [ x>> ] [ y>> ] [ origin>> ] tri 3append ;
@@ -42,8 +45,8 @@ CONSTANT: identity-transform T{ affine-transform f { 1.0 0.0 } { 0.0 1.0 } { 0.0
     (inverted-axes) { 0.0 0.0 } <affine-transform> ;
 
 : inverse-transform ( a -- a^-1 )
-    [ inverse-axes dup ] [ origin>> ] bi
-    a.v vneg >>origin ;
+    [ inverse-axes [ x>> ] [ y>> ] [ ] tri ] [ origin>> ] bi
+    a.v vneg <affine-transform> ;
 
 : transpose-axes ( a -- a^T )
     [ [ x>> first  ] [ y>> first  ] bi 2array ]
@@ -51,11 +54,11 @@ CONSTANT: identity-transform T{ affine-transform f { 1.0 0.0 } { 0.0 1.0 } { 0.0
     [ origin>> ] tri <affine-transform> ;
 
 : a. ( a a -- a )
-    transpose-axes {
-        [ [ x>> ] [ x>> ] bi* v. ]
-        [ [ x>> ] [ y>> ] bi* v. ]
-        [ [ y>> ] [ x>> ] bi* v. ]
-        [ [ y>> ] [ y>> ] bi* v. ]
+    {
+        [ [ transpose-axes x>> ] [ x>> ] bi* v. ]
+        [ [ transpose-axes y>> ] [ x>> ] bi* v. ]
+        [ [ transpose-axes x>> ] [ y>> ] bi* v. ]
+        [ [ transpose-axes y>> ] [ y>> ] bi* v. ]
         [ origin>> a.v ]
     } 2cleave
     [ [ 2array ] 2bi@ ] dip <affine-transform> ;
index 5b537c2621ba5777998440f42d7b7814cfc15609..1c11162a68370c0f7b0f28e4e4cfcf60f845bcce 100644 (file)
@@ -2,8 +2,7 @@ USING: kernel math math.functions tools.test math.analysis
 math.constants ;
 IN: math.analysis.tests
 
-: eps
-    .00000001 ;
+CONSTANT: eps .00000001
 
 [ t ] [ -9000000000000000000000000000000000000000000 gamma 1/0. = ] unit-test
 [ t ] [ -1.5 gamma 2.363271801207344 eps ~ ] unit-test
index 02b0608ed817251e1632abbd93cb8fdd26b4056a..1dadfd18c83c65182a8a7ce9c1b100a4732b3ce1 100644 (file)
@@ -5,6 +5,6 @@ USING: kernel parser words effects accessors sequences
     
 IN: math.derivatives.syntax
 
-: DERIVATIVE: scan-object dup stack-effect in>> length [1,b] 
+SYNTAX: DERIVATIVE: scan-object dup stack-effect in>> length [1,b] 
     [ drop scan-object ] map 
-    "derivative" set-word-prop ; parsing
\ No newline at end of file
+    "derivative" set-word-prop ;
\ No newline at end of file
index 6f87109ba08a55c96ccb800e18fe915362f8c539..20942356dedf16467e5feb3924ccb6d862510e88 100644 (file)
@@ -104,3 +104,6 @@ USING: math.matrices math.vectors tools.test math ;
 [ { 0 1 0 } ] [ { 0 0 1 } { 1 0 0 } cross ] unit-test
 
 [ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
+
+[ { { { 1 "a" } { 1 "b" } } { { 2 "a" } { 2 "b" } } } ]
+[ { 1 2 } { "a" "b" } cross-zip ] unit-test
\ No newline at end of file
index 0088b17372253b890fba644cce111efc7e148108..7c687d753d37e74d30ce6996ec8ce56e73b75ef5 100755 (executable)
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel math math.order math.vectors sequences ;
 IN: math.matrices
@@ -57,3 +57,6 @@ PRIVATE>
 
 : norm-gram-schmidt ( seq -- orthonormal )
     gram-schmidt [ normalize ] map ;
+
+: cross-zip ( seq1 seq2 -- seq1xseq2 )
+    [ [ 2array ] with map ] curry map ;
\ No newline at end of file
diff --git a/extra/method-chains/authors.txt b/extra/method-chains/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/method-chains/method-chains-tests.factor b/extra/method-chains/method-chains-tests.factor
new file mode 100644 (file)
index 0000000..e1a18fa
--- /dev/null
@@ -0,0 +1,13 @@
+IN: method-chains.tests
+USING: method-chains tools.test arrays strings sequences kernel namespaces ;
+
+GENERIC: testing ( a b -- c )
+
+M: sequence testing nip reverse ;
+AFTER: string testing append ;
+BEFORE: array testing over prefix "a" set ;
+
+[ V{ 3 2 1 } ] [ 3 V{ 1 2 3 } testing ] unit-test
+[ "heyyeh" ] [ 4 "yeh" testing ] unit-test
+[ { 4 2 0 } ] [ 5 { 0 2 4 } testing ] unit-test
+[ { 5 0 2 4 } ] [ "a" get ] unit-test
\ No newline at end of file
diff --git a/extra/method-chains/method-chains.factor b/extra/method-chains/method-chains.factor
new file mode 100644 (file)
index 0000000..5d24311
--- /dev/null
@@ -0,0 +1,7 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel generic generic.parser words fry ;
+IN: method-chains
+
+SYNTAX: AFTER: (M:) dupd '[ [ _ (call-next-method) ] _ bi ] define ;
+SYNTAX: BEFORE: (M:) over '[ _ [ _ (call-next-method) ] bi ] define ;
index 2f7f79da9d46cbeda587c8284938b11fe0b930fb..32b78a2c137af31b0547281c96ccb4449af7a898 100755 (executable)
@@ -8,5 +8,5 @@ V{
     { deploy-word-props? f }
     { deploy-c-types? f }
     { "stop-after-last-window?" t }
-    { deploy-name "Catalyst Talk" }
+    { deploy-name "Minnesota Talk" }
 }
index 7fcc7abc882ad69d0acf8aefd0dc6d49619279fd..ef8d1bd5e3a68cd309f1c4f99837048420b76e69 100755 (executable)
@@ -1 +1 @@
-Slides for a talk at Ruby.mn, Minneapolis MN, January 2008
+Slides for a talk at Ruby.mn, Minneapolis, MN, January 2008
diff --git a/extra/models/history/history-docs.factor b/extra/models/history/history-docs.factor
new file mode 100644 (file)
index 0000000..d157729
--- /dev/null
@@ -0,0 +1,36 @@
+USING: help.syntax help.markup kernel math classes classes.tuple\r
+calendar models ;\r
+IN: models.history\r
+\r
+HELP: history\r
+{ $class-description "History models record a timeline of previous values on calls to " { $link add-history } ", and can travel back and forth on the timeline with " { $link go-back } " and " { $link go-forward } ". History models are constructed by " { $link <history> } "." } ;\r
+\r
+HELP: <history>\r
+{ $values { "value" object } { "history" "a new " { $link history } } }\r
+{ $description "Creates a new history model with an initial value." } ;\r
+\r
+{ <history> add-history go-back go-forward } related-words\r
+\r
+HELP: go-back\r
+{ $values { "history" history } }\r
+{ $description "Restores the previous value and calls " { $link model-changed } " on all observers registered with " { $link add-connection } "." } ;\r
+\r
+HELP: go-forward\r
+{ $values { "history" history } }\r
+{ $description "Restores the value set prior to the last call to " { $link go-back } " and calls " { $link model-changed } " on all observers registered with " { $link add-connection } "." } ;\r
+\r
+HELP: add-history\r
+{ $values { "history" history } }\r
+{ $description "Adds the current value to the history." } ;\r
+\r
+ARTICLE: "models-history" "History models"\r
+"History models record previous values."\r
+{ $subsection history }\r
+{ $subsection <history> }\r
+"Recording history:"\r
+{ $subsection add-history }\r
+"Navigating the history:"\r
+{ $subsection go-back }\r
+{ $subsection go-forward } ;\r
+\r
+ABOUT: "models-history"\r
diff --git a/extra/models/history/history-tests.factor b/extra/models/history/history-tests.factor
new file mode 100644 (file)
index 0000000..c89dd5c
--- /dev/null
@@ -0,0 +1,37 @@
+USING: arrays generic kernel math models namespaces sequences assocs\r
+tools.test models.history accessors ;\r
+IN: models.history.tests\r
+\r
+f <history> "history" set\r
+\r
+"history" get add-history\r
+\r
+[ t ] [ "history" get back>> empty? ] unit-test\r
+[ t ] [ "history" get forward>> empty? ] unit-test\r
+\r
+"history" get add-history\r
+3 "history" get set-model\r
+\r
+[ t ] [ "history" get back>> empty? ] unit-test\r
+[ t ] [ "history" get forward>> empty? ] unit-test\r
+\r
+"history" get add-history\r
+4 "history" get set-model\r
+\r
+[ f ] [ "history" get back>> empty? ] unit-test\r
+[ t ] [ "history" get forward>> empty? ] unit-test\r
+\r
+"history" get go-back\r
+\r
+[ 3 ] [ "history" get value>> ] unit-test\r
+\r
+[ t ] [ "history" get back>> empty? ] unit-test\r
+[ f ] [ "history" get forward>> empty? ] unit-test\r
+\r
+"history" get go-forward\r
+\r
+[ 4 ] [ "history" get value>> ] unit-test\r
+\r
+[ f ] [ "history" get back>> empty? ] unit-test\r
+[ t ] [ "history" get forward>> empty? ] unit-test\r
+\r
diff --git a/extra/models/history/history.factor b/extra/models/history/history.factor
new file mode 100644 (file)
index 0000000..90d6b59
--- /dev/null
@@ -0,0 +1,31 @@
+! Copyright (C) 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: accessors kernel models sequences ;\r
+IN: models.history\r
+\r
+TUPLE: history < model back forward ;\r
+\r
+: reset-history ( history -- history )\r
+    V{ } clone >>back\r
+    V{ } clone >>forward ; inline\r
+\r
+: <history> ( value -- history )\r
+    history new-model\r
+        reset-history ;\r
+\r
+: (add-history) ( history to -- )\r
+    swap value>> dup [ swap push ] [ 2drop ] if ;\r
+\r
+: go-back/forward ( history to from -- )\r
+    [ 2drop ]\r
+    [ [ dupd (add-history) ] dip pop swap set-model ] if-empty ;\r
+\r
+: go-back ( history -- )\r
+    dup [ forward>> ] [ back>> ] bi go-back/forward ;\r
+\r
+: go-forward ( history -- )\r
+    dup [ back>> ] [ forward>> ] bi go-back/forward ;\r
+\r
+: add-history ( history -- )\r
+    dup forward>> delete-all\r
+    dup back>> (add-history) ;\r
diff --git a/extra/models/history/summary.txt b/extra/models/history/summary.txt
new file mode 100644 (file)
index 0000000..76f7b88
--- /dev/null
@@ -0,0 +1 @@
+History models remember prior values
index 44234bc4bc538242503e11d55e3664c9439630d2..ee63b14f3c27d999d6556881af3522ab5291957c 100644 (file)
@@ -79,7 +79,7 @@ IN: monads.tests
 LAZY: nats-from ( n -- list )
     dup 1+ nats-from cons ;
 
-: nats 0 nats-from ;
+: nats ( -- list ) 0 nats-from ;
 
 [ 3 ] [
     {
index e9ae1675323d53170bb47ccdd76739088b60c76e..6b35772596f92e59e06c18b8ff6055e19ab6720d 100644 (file)
@@ -6,7 +6,7 @@ shuffle ;
 IN: monads
 
 ! Functors
-GENERIC# fmap 1 ( functor quot -- functor' ) inline
+GENERIC# fmap 1 ( functor quot -- functor' )
 
 ! Monads
 
@@ -21,7 +21,7 @@ GENERIC: >>= ( mvalue -- quot )
 M: monad return monad-of return ;
 M: monad fail   monad-of fail   ;
 
-: bind ( mvalue quot -- mvalue' ) swap >>= call ;
+: bind ( mvalue quot -- mvalue' ) swap >>= call( quot -- mvalue ) ;
 : >>   ( mvalue k -- mvalue' ) '[ drop _ ] bind ;
 
 :: lift-m2 ( m1 m2 f monad -- m3 )
@@ -30,14 +30,14 @@ M: monad fail   monad-of fail   ;
 :: apply ( mvalue mquot monad -- result )
     mvalue [| value |
         mquot [| quot |
-            value quot call monad return
+            value quot call( value -- mvalue ) monad return
         ] bind
     ] bind ;
 
 M: monad fmap over '[ @ _ return ] bind ;
 
 ! 'do' notation
-: do ( quots -- result ) unclip dip [ bind ] each ;
+: do ( quots -- result ) unclip [ call( -- mvalue ) ] curry dip [ bind ] each ;
 
 ! Identity
 SINGLETON: identity-monad
@@ -51,7 +51,7 @@ M: identity monad-of drop identity-monad ;
 M: identity-monad return drop identity boa ;
 M: identity-monad fail   "Fail" throw ;
 
-M: identity >>= value>> '[ _ swap call ] ;
+M: identity >>= value>> '[ _ swap call( x -- y ) ] ;
 
 : run-identity ( identity -- value ) value>> ;
 
@@ -73,7 +73,7 @@ M: maybe-monad return drop just ;
 M: maybe-monad fail   2drop nothing ;
 
 M: nothing >>= '[ drop _ ] ;
-M: just    >>= value>> '[ _ swap call ] ;
+M: just    >>= value>> '[ _ swap call( x -- y ) ] ;
 
 : if-maybe ( maybe just-quot nothing-quot -- )
     pick nothing? [ 2nip call ] [ drop [ value>> ] dip call ] if ; inline
@@ -97,7 +97,7 @@ M: either-monad return  drop right ;
 M: either-monad fail    drop left ;
 
 M: left  >>= '[ drop _ ] ;
-M: right >>= value>> '[ _ swap call ] ;
+M: right >>= value>> '[ _ swap call( x -- y ) ] ;
 
 : if-either ( value left-quot right-quot -- )
     [ [ value>> ] [ left? ] bi ] 2dip if ; inline
@@ -140,14 +140,14 @@ M: state monad-of drop state-monad ;
 M: state-monad return drop '[ _ 2array ] state ;
 M: state-monad fail   "Fail" throw ;
 
-: mcall ( state -- ) quot>> call ;
+: mcall ( x state -- y ) quot>> call( x -- y ) ;
 
 M: state >>= '[ _ swap '[ _ mcall first2 @ mcall ] state ] ;
 
 : get-st ( -- state ) [ dup 2array ] state ;
 : put-st ( value -- state ) '[ drop _ f 2array ] state ;
 
-: run-st ( state initial -- ) swap mcall second ;
+: run-st ( state initial -- value ) swap mcall second ;
 
 : return-st ( value -- mvalue ) state-monad return ;
 
@@ -166,7 +166,7 @@ M: reader-monad fail   "Fail" throw ;
 
 M: reader >>= '[ _ swap '[ dup _ mcall @ mcall ] reader ] ;
 
-: run-reader ( reader env -- ) swap mcall ;
+: run-reader ( reader env -- value ) swap quot>> call( env -- value ) ;
 
 : ask ( -- reader ) [ ] reader ;
 : local ( reader quot -- reader' ) swap '[ @ _ mcall ] reader ;
@@ -187,6 +187,6 @@ M: writer-monad fail   "Fail" throw ;
 
 M: writer >>= '[ [ _ run-writer ] dip '[ @ run-writer ] dip append writer ] ;
 
-: pass ( writer -- writer' ) run-writer [ first2 ] dip swap call writer ;
+: pass ( writer -- writer' ) run-writer [ first2 ] dip swap call( x -- y ) writer ;
 : listen ( writer -- writer' ) run-writer [ 2array ] keep writer ;
 : tell ( seq -- writer ) f swap writer ;
index 1b9dee74b7ec6e9d7d6c513e02888bbaaf29304d..994d2143355c5925e2c583b855625ac325215d14 100644 (file)
@@ -30,5 +30,4 @@ ERROR: not-an-integer x ;
     ] keep length
     10 swap ^ / + swap [ neg ] when ;
 
-: DECIMAL:
-    scan parse-decimal parsed ; parsing
+SYNTAX: DECIMAL: scan parse-decimal parsed ;
index 7c5d5fb431c1d01414efeb024af994ca401e9f63..17f0de120e0db7c88f73d8a43aa4479e080f7030 100755 (executable)
@@ -1,11 +1,11 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math sequences vectors classes classes.algebra
 combinators arrays words assocs parser namespaces make
 definitions prettyprint prettyprint.backend prettyprint.custom
 quotations generalizations debugger io compiler.units
 kernel.private effects accessors hashtables sorting shuffle
-math.order sets see ;
+math.order sets see effects.parser ;
 IN: multi-methods
 
 ! PART I: Converting hook specializers
@@ -214,18 +214,16 @@ M: no-method error.
     [ "multi-method-specializer" word-prop ]
     [ "multi-method-generic" word-prop ] bi prefix ;
 
-: define-generic ( word -- )
-    dup "multi-methods" word-prop [
-        drop
-    ] [
+: define-generic ( word effect -- )
+    over set-stack-effect
+    dup "multi-methods" word-prop [ drop ] [
         [ H{ } clone "multi-methods" set-word-prop ]
         [ update-generic ]
         bi
     ] if ;
 
 ! Syntax
-: GENERIC:
-    CREATE define-generic ; parsing
+SYNTAX: GENERIC: CREATE-WORD complete-effect define-generic ;
 
 : parse-method ( -- quot classes generic )
     parse-definition [ 2 tail ] [ second ] [ first ] tri ;
@@ -238,13 +236,13 @@ M: no-method error.
 
 : (METHOD:) ( -- method def ) CREATE-METHOD parse-definition ;
 
-: METHOD: (METHOD:) define ; parsing
+SYNTAX: METHOD: (METHOD:) define ;
 
 ! For compatibility
-: M:
+SYNTAX: M:
     scan-word 1array scan-word create-method-in
     parse-definition
-    define ; parsing
+    define ;
 
 ! Definition protocol. We qualify core generics here
 QUALIFIED: syntax
diff --git a/extra/multi-methods/tags.txt b/extra/multi-methods/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 991551c00959915cd37bd6c7dcda4167d7231e94..91982de95cc33e5eb2da99079171e09dd7b4a9fa 100644 (file)
@@ -4,11 +4,11 @@ kernel strings ;
 
 [ { POSTPONE: f integer } ] [ { f integer } canonicalize-specializer-0 ] unit-test
 
-: setup-canon-test
+: setup-canon-test ( -- )
     0 args set
     V{ } clone hooks set ;
 
-: canon-test-1
+: canon-test-1 ( -- seq )
     { integer { cpu x86 } sequence } canonicalize-specializer-1 ;
 
 [ { { -2 integer } { -1 sequence } { cpu x86 } } ] [
@@ -36,12 +36,12 @@ kernel strings ;
     ] with-scope
 ] unit-test
 
-: example-1
+CONSTANT: example-1
     {
         { { { cpu x86 } { os linux } } "a" }
         { { { cpu ppc } } "b" }
         { { string { os windows } } "c" }
-    } ;
+    }
 
 [
     {
index 64363af428ae724959cc627be064c722bf2c12c0..240c9f86d7f328de2a43018a9e38842bebee47b9 100644 (file)
@@ -26,7 +26,7 @@ DEFER: fake
 
     DEFER: testing
 
-    [ ] [ \ testing define-generic ] unit-test
+    [ ] [ \ testing (( -- )) define-generic ] unit-test
 
     [ t ] [ \ testing generic? ] unit-test
 ] with-compilation-unit
index f4bd0a00b224bcb973b949e23b0c2e9c0caedb1e..b6d732643fb8a5d2a587d8476e20633a8248bf9d 100644 (file)
@@ -1,7 +1,7 @@
 IN: multi-methods.tests
 USING: math strings sequences tools.test ;
 
-GENERIC: legacy-test
+GENERIC: legacy-test ( a -- b )
 
 M: integer legacy-test sq ;
 M: string legacy-test " hey" append ;
index 9d9c80b21416ea976e98e0e6bda5da0c39c4c7b1..cc073099d8f2226102d45409354e682e4e13d6f9 100644 (file)
@@ -3,7 +3,7 @@ USING: multi-methods tools.test math sequences namespaces system
 kernel strings definitions prettyprint debugger arrays
 hashtables continuations classes assocs accessors see ;
 
-GENERIC: first-test
+GENERIC: first-test ( -- )
 
 [ t ] [ \ first-test generic? ] unit-test
 
@@ -13,7 +13,7 @@ SINGLETON: paper    INSTANCE: paper thing
 SINGLETON: scissors INSTANCE: scissors thing
 SINGLETON: rock     INSTANCE: rock thing
 
-GENERIC: beats?
+GENERIC: beats? ( obj1 obj2 -- ? )
 
 METHOD: beats? { paper scissors } t ;
 METHOD: beats? { scissors rock } t ;
@@ -34,7 +34,7 @@ METHOD: beats? { thing thing } f ;
 
 SYMBOL: some-var
 
-GENERIC: hook-test
+GENERIC: hook-test ( -- obj )
 
 METHOD: hook-test { array { some-var array } } reverse ;
 METHOD: hook-test { { some-var array } } class ;
@@ -57,7 +57,7 @@ TUPLE: busted-1 ;
 TUPLE: busted-2 ; INSTANCE: busted-2 busted
 TUPLE: busted-3 ;
 
-GENERIC: busted-sort
+GENERIC: busted-sort ( obj1 obj2 -- obj1 obj2 )
 
 METHOD: busted-sort { busted-1 busted-2 } ;
 METHOD: busted-sort { busted-2 busted-3 } ;
index 4169050e6fc171006c7e49b65023ec9a36515a5e..bf7955fa8456b59bbdeac7b866a37d591b999232 100644 (file)
@@ -140,11 +140,11 @@ METHOD: as-mutate { object object assoc }       set-at ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: filter-of ( quot seq -- seq ) swap filter ;
+: filter-of ( quot seq -- seq ) swap filter ; inline
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: map-over ( quot seq -- seq ) swap map ;
+: map-over ( quot seq -- seq ) swap map ; inline
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -242,7 +242,7 @@ METHOD: as-mutate { object object assoc }       set-at ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: purge ( seq quot -- seq ) [ not ] compose filter ;
+: purge ( seq quot -- seq ) [ not ] compose filter ; inline
 
 : purge! ( seq quot -- seq )
-  dupd '[ swap @ [ pluck! ] [ drop ] if ] each-index ;
+  dupd '[ swap @ [ pluck! ] [ drop ] if ] each-index ; inline
diff --git a/extra/opengl/glu/authors.txt b/extra/opengl/glu/authors.txt
new file mode 100644 (file)
index 0000000..e9c193b
--- /dev/null
@@ -0,0 +1 @@
+Alex Chapman
diff --git a/extra/opengl/glu/glu.factor b/extra/opengl/glu/glu.factor
new file mode 100644 (file)
index 0000000..fe060e3
--- /dev/null
@@ -0,0 +1,267 @@
+! Copyright (C) 2005 Alex Chapman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien alien.libraries alien.syntax kernel sequences words system
+combinators ;
+IN: opengl.glu
+
+os {
+    { [ dup macosx? ] [ drop ] }
+    { [ dup windows? ] [ drop ] }
+    { [ dup unix? ] [ drop "glu" "libGLU.so.1" "cdecl" add-library ] }
+} cond
+
+LIBRARY: glu
+! These are defined as structs in glu.h, but we only ever use pointers to them
+TYPEDEF: void* GLUnurbs*
+TYPEDEF: void* GLUquadric*
+TYPEDEF: void* GLUtesselator*
+TYPEDEF: void* GLubyte*
+TYPEDEF: void* GLUfuncptr
+
+! StringName
+CONSTANT: GLU_VERSION                        100800
+CONSTANT: GLU_EXTENSIONS                     100801
+
+! ErrorCode
+CONSTANT: GLU_INVALID_ENUM                   100900
+CONSTANT: GLU_INVALID_VALUE                  100901
+CONSTANT: GLU_OUT_OF_MEMORY                  100902
+CONSTANT: GLU_INCOMPATIBLE_GL_VERSION        100903
+CONSTANT: GLU_INVALID_OPERATION              100904
+
+! NurbsDisplay
+CONSTANT: GLU_OUTLINE_POLYGON                100240
+CONSTANT: GLU_OUTLINE_PATCH                  100241
+
+! NurbsCallback
+CONSTANT: GLU_NURBS_ERROR                    100103
+CONSTANT: GLU_ERROR                          100103
+CONSTANT: GLU_NURBS_BEGIN                    100164
+CONSTANT: GLU_NURBS_BEGIN_EXT                100164
+CONSTANT: GLU_NURBS_VERTEX                   100165
+CONSTANT: GLU_NURBS_VERTEX_EXT               100165
+CONSTANT: GLU_NURBS_NORMAL                   100166
+CONSTANT: GLU_NURBS_NORMAL_EXT               100166
+CONSTANT: GLU_NURBS_COLOR                    100167
+CONSTANT: GLU_NURBS_COLOR_EXT                100167
+CONSTANT: GLU_NURBS_TEXTURE_COORD            100168
+CONSTANT: GLU_NURBS_TEX_COORD_EXT            100168
+CONSTANT: GLU_NURBS_END                      100169
+CONSTANT: GLU_NURBS_END_EXT                  100169
+CONSTANT: GLU_NURBS_BEGIN_DATA               100170
+CONSTANT: GLU_NURBS_BEGIN_DATA_EXT           100170
+CONSTANT: GLU_NURBS_VERTEX_DATA              100171
+CONSTANT: GLU_NURBS_VERTEX_DATA_EXT          100171
+CONSTANT: GLU_NURBS_NORMAL_DATA              100172
+CONSTANT: GLU_NURBS_NORMAL_DATA_EXT          100172
+CONSTANT: GLU_NURBS_COLOR_DATA               100173
+CONSTANT: GLU_NURBS_COLOR_DATA_EXT           100173
+CONSTANT: GLU_NURBS_TEXTURE_COORD_DATA       100174
+CONSTANT: GLU_NURBS_TEX_COORD_DATA_EXT       100174
+CONSTANT: GLU_NURBS_END_DATA                 100175
+CONSTANT: GLU_NURBS_END_DATA_EXT             100175
+
+! NurbsError
+CONSTANT: GLU_NURBS_ERROR1                   100251
+CONSTANT: GLU_NURBS_ERROR2                   100252
+CONSTANT: GLU_NURBS_ERROR3                   100253
+CONSTANT: GLU_NURBS_ERROR4                   100254
+CONSTANT: GLU_NURBS_ERROR5                   100255
+CONSTANT: GLU_NURBS_ERROR6                   100256
+CONSTANT: GLU_NURBS_ERROR7                   100257
+CONSTANT: GLU_NURBS_ERROR8                   100258
+CONSTANT: GLU_NURBS_ERROR9                   100259
+CONSTANT: GLU_NURBS_ERROR10                  100260
+CONSTANT: GLU_NURBS_ERROR11                  100261
+CONSTANT: GLU_NURBS_ERROR12                  100262
+CONSTANT: GLU_NURBS_ERROR13                  100263
+CONSTANT: GLU_NURBS_ERROR14                  100264
+CONSTANT: GLU_NURBS_ERROR15                  100265
+CONSTANT: GLU_NURBS_ERROR16                  100266
+CONSTANT: GLU_NURBS_ERROR17                  100267
+CONSTANT: GLU_NURBS_ERROR18                  100268
+CONSTANT: GLU_NURBS_ERROR19                  100269
+CONSTANT: GLU_NURBS_ERROR20                  100270
+CONSTANT: GLU_NURBS_ERROR21                  100271
+CONSTANT: GLU_NURBS_ERROR22                  100272
+CONSTANT: GLU_NURBS_ERROR23                  100273
+CONSTANT: GLU_NURBS_ERROR24                  100274
+CONSTANT: GLU_NURBS_ERROR25                  100275
+CONSTANT: GLU_NURBS_ERROR26                  100276
+CONSTANT: GLU_NURBS_ERROR27                  100277
+CONSTANT: GLU_NURBS_ERROR28                  100278
+CONSTANT: GLU_NURBS_ERROR29                  100279
+CONSTANT: GLU_NURBS_ERROR30                  100280
+CONSTANT: GLU_NURBS_ERROR31                  100281
+CONSTANT: GLU_NURBS_ERROR32                  100282
+CONSTANT: GLU_NURBS_ERROR33                  100283
+CONSTANT: GLU_NURBS_ERROR34                  100284
+CONSTANT: GLU_NURBS_ERROR35                  100285
+CONSTANT: GLU_NURBS_ERROR36                  100286
+CONSTANT: GLU_NURBS_ERROR37                  100287
+
+! NurbsProperty
+CONSTANT: GLU_AUTO_LOAD_MATRIX               100200
+CONSTANT: GLU_CULLING                        100201
+CONSTANT: GLU_SAMPLING_TOLERANCE             100203
+CONSTANT: GLU_DISPLAY_MODE                   100204
+CONSTANT: GLU_PARAMETRIC_TOLERANCE           100202
+CONSTANT: GLU_SAMPLING_METHOD                100205
+CONSTANT: GLU_U_STEP                         100206
+CONSTANT: GLU_V_STEP                         100207
+CONSTANT: GLU_NURBS_MODE                     100160
+CONSTANT: GLU_NURBS_MODE_EXT                 100160
+CONSTANT: GLU_NURBS_TESSELLATOR              100161
+CONSTANT: GLU_NURBS_TESSELLATOR_EXT          100161
+CONSTANT: GLU_NURBS_RENDERER                 100162
+CONSTANT: GLU_NURBS_RENDERER_EXT             100162
+
+! NurbsSampling
+CONSTANT: GLU_OBJECT_PARAMETRIC_ERROR        100208
+CONSTANT: GLU_OBJECT_PARAMETRIC_ERROR_EXT    100208
+CONSTANT: GLU_OBJECT_PATH_LENGTH             100209
+CONSTANT: GLU_OBJECT_PATH_LENGTH_EXT         100209
+CONSTANT: GLU_PATH_LENGTH                    100215
+CONSTANT: GLU_PARAMETRIC_ERROR               100216
+CONSTANT: GLU_DOMAIN_DISTANCE                100217
+
+! NurbsTrim
+CONSTANT: GLU_MAP1_TRIM_2                    100210
+CONSTANT: GLU_MAP1_TRIM_3                    100211
+
+! QuadricDrawStyle
+CONSTANT: GLU_POINT                          100010
+CONSTANT: GLU_LINE                           100011
+CONSTANT: GLU_FILL                           100012
+CONSTANT: GLU_SILHOUETTE                     100013
+
+! QuadricNormal
+CONSTANT: GLU_SMOOTH                         100000
+CONSTANT: GLU_FLAT                           100001
+CONSTANT: GLU_NONE                           100002
+
+! QuadricOrientation
+CONSTANT: GLU_OUTSIDE                        100020
+CONSTANT: GLU_INSIDE                         100021
+
+! TessCallback
+CONSTANT: GLU_TESS_BEGIN                     100100
+CONSTANT: GLU_BEGIN                          100100
+CONSTANT: GLU_TESS_VERTEX                    100101
+CONSTANT: GLU_VERTEX                         100101
+CONSTANT: GLU_TESS_END                       100102
+CONSTANT: GLU_END                            100102
+CONSTANT: GLU_TESS_ERROR                     100103
+CONSTANT: GLU_TESS_EDGE_FLAG                 100104
+CONSTANT: GLU_EDGE_FLAG                      100104
+CONSTANT: GLU_TESS_COMBINE                   100105
+CONSTANT: GLU_TESS_BEGIN_DATA                100106
+CONSTANT: GLU_TESS_VERTEX_DATA               100107
+CONSTANT: GLU_TESS_END_DATA                  100108
+CONSTANT: GLU_TESS_ERROR_DATA                100109
+CONSTANT: GLU_TESS_EDGE_FLAG_DATA            100110
+CONSTANT: GLU_TESS_COMBINE_DATA              100111
+
+! TessContour
+CONSTANT: GLU_CW                             100120
+CONSTANT: GLU_CCW                            100121
+CONSTANT: GLU_INTERIOR                       100122
+CONSTANT: GLU_EXTERIOR                       100123
+CONSTANT: GLU_UNKNOWN                        100124
+
+! TessProperty
+CONSTANT: GLU_TESS_WINDING_RULE              100140
+CONSTANT: GLU_TESS_BOUNDARY_ONLY             100141
+CONSTANT: GLU_TESS_TOLERANCE                 100142
+
+! TessError
+CONSTANT: GLU_TESS_ERROR1                    100151
+CONSTANT: GLU_TESS_ERROR2                    100152
+CONSTANT: GLU_TESS_ERROR3                    100153
+CONSTANT: GLU_TESS_ERROR4                    100154
+CONSTANT: GLU_TESS_ERROR5                    100155
+CONSTANT: GLU_TESS_ERROR6                    100156
+CONSTANT: GLU_TESS_ERROR7                    100157
+CONSTANT: GLU_TESS_ERROR8                    100158
+CONSTANT: GLU_TESS_MISSING_BEGIN_POLYGON     100151
+CONSTANT: GLU_TESS_MISSING_BEGIN_CONTOUR     100152
+CONSTANT: GLU_TESS_MISSING_END_POLYGON       100153
+CONSTANT: GLU_TESS_MISSING_END_CONTOUR       100154
+CONSTANT: GLU_TESS_COORD_TOO_LARGE           100155
+CONSTANT: GLU_TESS_NEED_COMBINE_CALLBACK     100156
+
+! TessWinding
+CONSTANT: GLU_TESS_WINDING_ODD               100130
+CONSTANT: GLU_TESS_WINDING_NONZERO           100131
+CONSTANT: GLU_TESS_WINDING_POSITIVE          100132
+CONSTANT: GLU_TESS_WINDING_NEGATIVE          100133
+CONSTANT: GLU_TESS_WINDING_ABS_GEQ_TWO       100134
+
+LIBRARY: glu
+
+FUNCTION: void gluBeginCurve ( GLUnurbs* nurb ) ;
+FUNCTION: void gluBeginPolygon ( GLUtesselator* tess ) ;
+FUNCTION: void gluBeginSurface ( GLUnurbs* nurb ) ;
+FUNCTION: void gluBeginTrim ( GLUnurbs* nurb ) ;
+
+FUNCTION: void gluCylinder ( GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks ) ;
+FUNCTION: void gluDeleteNurbsRenderer ( GLUnurbs* nurb ) ;
+FUNCTION: void gluDeleteQuadric ( GLUquadric* quad ) ;
+FUNCTION: void gluDeleteTess ( GLUtesselator* tess ) ;
+FUNCTION: void gluDisk ( GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops ) ;
+FUNCTION: void gluEndCurve ( GLUnurbs* nurb ) ;
+FUNCTION: void gluEndPolygon ( GLUtesselator* tess ) ;
+FUNCTION: void gluEndSurface ( GLUnurbs* nurb ) ;
+FUNCTION: void gluEndTrim ( GLUnurbs* nurb ) ;
+FUNCTION: char* gluErrorString ( GLenum error ) ;
+FUNCTION: void gluGetNurbsProperty ( GLUnurbs* nurb, GLenum property, GLfloat* data ) ;
+FUNCTION: char* gluGetString ( GLenum name ) ;
+FUNCTION: void gluGetTessProperty ( GLUtesselator* tess, GLenum which, GLdouble* data ) ;
+FUNCTION: void gluLoadSamplingMatrices ( GLUnurbs* nurb, GLfloat* model, GLfloat* perspective, GLint* view ) ;
+FUNCTION: void gluLookAt ( GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ ) ;
+FUNCTION: GLUnurbs* gluNewNurbsRenderer ( ) ;
+FUNCTION: GLUquadric* gluNewQuadric ( ) ;
+FUNCTION: GLUtesselator* gluNewTess ( ) ;
+FUNCTION: void gluNextContour ( GLUtesselator* tess, GLenum type ) ;
+FUNCTION: void gluNurbsCallback ( GLUnurbs* nurb, GLenum which, GLUfuncptr CallBackFunc ) ;
+! FUNCTION: void gluNurbsCallbackData ( GLUnurbs* nurb, GLvoid* userData ) ;
+! FUNCTION: void gluNurbsCallbackDataEXT ( GLUnurbs* nurb, GLvoid* userData ) ;
+FUNCTION: void gluNurbsCurve ( GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type ) ;
+FUNCTION: void gluNurbsProperty ( GLUnurbs* nurb, GLenum property, GLfloat value ) ;
+FUNCTION: void gluNurbsSurface ( GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type ) ;
+FUNCTION: void gluOrtho2D ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top ) ;
+FUNCTION: void gluPartialDisk ( GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep ) ;
+FUNCTION: void gluPerspective ( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) ;
+FUNCTION: void gluPickMatrix ( GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint* viewport ) ;
+FUNCTION: GLint gluProject ( GLdouble objX, GLdouble objY, GLdouble objZ, GLdouble* model, GLdouble* proj, GLint* view, GLdouble* winX, GLdouble* winY, GLdouble* winZ ) ;
+FUNCTION: void gluPwlCurve ( GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type ) ;
+FUNCTION: void gluQuadricCallback ( GLUquadric* quad, GLenum which, GLUfuncptr CallBackFunc ) ;
+FUNCTION: void gluQuadricDrawStyle ( GLUquadric* quad, GLenum draw ) ;
+FUNCTION: void gluQuadricNormals ( GLUquadric* quad, GLenum normal ) ;
+FUNCTION: void gluQuadricOrientation ( GLUquadric* quad, GLenum orientation ) ;
+FUNCTION: void gluQuadricTexture ( GLUquadric* quad, GLboolean texture ) ;
+FUNCTION: GLint gluScaleImage ( GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, void* dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut ) ;
+FUNCTION: void gluSphere ( GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks ) ;
+FUNCTION: void gluTessBeginContour ( GLUtesselator* tess ) ;
+FUNCTION: void gluTessBeginPolygon ( GLUtesselator* tess, GLvoid* data ) ;
+FUNCTION: void gluTessCallback ( GLUtesselator* tess, GLenum which, GLUfuncptr CallBackFunc ) ;
+FUNCTION: void gluTessEndContour ( GLUtesselator* tess ) ;
+FUNCTION: void gluTessEndPolygon ( GLUtesselator* tess ) ;
+FUNCTION: void gluTessNormal ( GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ ) ;
+FUNCTION: void gluTessProperty ( GLUtesselator* tess, GLenum which, GLdouble data ) ;
+FUNCTION: void gluTessVertex ( GLUtesselator* tess, GLdouble* location, GLvoid* data ) ;
+FUNCTION: GLint gluUnProject ( GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble* model, GLdouble* proj, GLint* view, GLdouble* objX, GLdouble* objY, GLdouble* objZ ) ;
+
+! Not present on Windows
+! FUNCTION: GLint gluBuild1DMipmapLevels ( GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data ) ;
+! FUNCTION: GLint gluBuild1DMipmaps ( GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, void* data ) ;
+! FUNCTION: GLint gluBuild2DMipmapLevels ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data ) ;
+! FUNCTION: GLint gluBuild2DMipmaps ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, void* data ) ;
+! FUNCTION: GLint gluBuild3DMipmapLevels ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, void* data ) ;
+! FUNCTION: GLint gluBuild3DMipmaps ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* data ) ;
+! FUNCTION: GLboolean gluCheckExtension ( GLubyte* extName, GLubyte* extString ) ;
+! FUNCTION: GLint gluUnProject4 ( GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, GLdouble* model, GLdouble* proj, GLint* view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW ) ;
+
+: gl-look-at ( eye focus up -- )
+    [ first3 ] tri@ gluLookAt ;
\ No newline at end of file
diff --git a/extra/opengl/glu/summary.txt b/extra/opengl/glu/summary.txt
new file mode 100644 (file)
index 0000000..a90f4a3
--- /dev/null
@@ -0,0 +1 @@
+OpenGL binding - libGLU
diff --git a/extra/opengl/glu/tags.txt b/extra/opengl/glu/tags.txt
new file mode 100644 (file)
index 0000000..bb863cf
--- /dev/null
@@ -0,0 +1 @@
+bindings
index 2ce307ce207b45fdea574d5aa87ae36b6ae1e39f..b7256246fe378b66ea428d5f7808f6130e985956 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: slides help.markup math arrays hashtables namespaces sequences
 kernel sequences parser memoize io.encodings.binary locals
-kernel.private tools.vocabs.browser assocs quotations tools.vocabs
+kernel.private help.vocabs assocs quotations tools.vocabs
 tools.annotations tools.crossref help.topics math.functions
 compiler.tree.optimizer compiler.cfg.optimizer fry ui.gadgets.panes
 tetris tetris.game combinators generalizations multiline
diff --git a/extra/parser-combinators/regexp/authors.txt b/extra/parser-combinators/regexp/authors.txt
deleted file mode 100755 (executable)
index 5674120..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Doug Coleman
-Slava Pestov
diff --git a/extra/parser-combinators/regexp/regexp-tests.factor b/extra/parser-combinators/regexp/regexp-tests.factor
deleted file mode 100755 (executable)
index 78abd8b..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-USING: parser-combinators.regexp tools.test kernel ;
-IN: parser-combinators.regexp.tests
-
-[ f ] [ "b" "a*" f <regexp> matches? ] unit-test
-[ t ] [ "" "a*" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a*" f <regexp> matches? ] unit-test
-[ t ] [ "aaaaaaa" "a*" f <regexp> matches? ] unit-test
-[ f ] [ "ab" "a*" f <regexp> matches? ] unit-test
-
-[ t ] [ "abc" "abc" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a|b|c" f <regexp> matches? ] unit-test
-[ t ] [ "b" "a|b|c" f <regexp> matches? ] unit-test
-[ t ] [ "c" "a|b|c" f <regexp> matches? ] unit-test
-[ f ] [ "c" "d|e|f" f <regexp> matches? ] unit-test
-
-[ f ] [ "aa" "a|b|c" f <regexp> matches? ] unit-test
-[ f ] [ "bb" "a|b|c" f <regexp> matches? ] unit-test
-[ f ] [ "cc" "a|b|c" f <regexp> matches? ] unit-test
-[ f ] [ "cc" "d|e|f" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "a+" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a+" f <regexp> matches? ] unit-test
-[ t ] [ "aa" "a+" f <regexp> matches? ] unit-test
-
-[ t ] [ "" "a?" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a?" f <regexp> matches? ] unit-test
-[ f ] [ "aa" "a?" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "." f <regexp> matches? ] unit-test
-[ t ] [ "a" "." f <regexp> matches? ] unit-test
-[ t ] [ "." "." f <regexp> matches? ] unit-test
-! [ f ] [ "\n" "." f <regexp> matches? ] unit-test
-
-[ f ] [ "" ".+" f <regexp> matches? ] unit-test
-[ t ] [ "a" ".+" f <regexp> matches? ] unit-test
-[ t ] [ "ab" ".+" f <regexp> matches? ] unit-test
-
-[ t ] [ "" "a|b*|c+|d?" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a|b*|c+|d?" f <regexp> matches? ] unit-test
-[ t ] [ "c" "a|b*|c+|d?" f <regexp> matches? ] unit-test
-[ t ] [ "cc" "a|b*|c+|d?" f <regexp> matches? ] unit-test
-[ f ] [ "ccd" "a|b*|c+|d?" f <regexp> matches? ] unit-test
-[ t ] [ "d" "a|b*|c+|d?" f <regexp> matches? ] unit-test
-
-[ t ] [ "foo" "foo|bar" f <regexp> matches? ] unit-test
-[ t ] [ "bar" "foo|bar" f <regexp> matches? ] unit-test
-[ f ] [ "foobar" "foo|bar" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "(a)" f <regexp> matches? ] unit-test
-[ t ] [ "a" "(a)" f <regexp> matches? ] unit-test
-[ f ] [ "aa" "(a)" f <regexp> matches? ] unit-test
-[ t ] [ "aa" "(a*)" f <regexp> matches? ] unit-test
-
-[ f ] [ "aababaaabbac" "(a|b)+" f <regexp> matches? ] unit-test
-[ t ] [ "ababaaabba" "(a|b)+" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "a{1}" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a{1}" f <regexp> matches? ] unit-test
-[ f ] [ "aa" "a{1}" f <regexp> matches? ] unit-test
-
-[ f ] [ "a" "a{2,}" f <regexp> matches? ] unit-test
-[ t ] [ "aaa" "a{2,}" f <regexp> matches? ] unit-test
-[ t ] [ "aaaa" "a{2,}" f <regexp> matches? ] unit-test
-[ t ] [ "aaaaa" "a{2,}" f <regexp> matches? ] unit-test
-
-[ t ] [ "" "a{,2}" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a{,2}" f <regexp> matches? ] unit-test
-[ t ] [ "aa" "a{,2}" f <regexp> matches? ] unit-test
-[ f ] [ "aaa" "a{,2}" f <regexp> matches? ] unit-test
-[ f ] [ "aaaa" "a{,2}" f <regexp> matches? ] unit-test
-[ f ] [ "aaaaa" "a{,2}" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "a{1,3}" f <regexp> matches? ] unit-test
-[ t ] [ "a" "a{1,3}" f <regexp> matches? ] unit-test
-[ t ] [ "aa" "a{1,3}" f <regexp> matches? ] unit-test
-[ t ] [ "aaa" "a{1,3}" f <regexp> matches? ] unit-test
-[ f ] [ "aaaa" "a{1,3}" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "[a]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[a]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[abc]" f <regexp> matches? ] unit-test
-[ f ] [ "b" "[a]" f <regexp> matches? ] unit-test
-[ f ] [ "d" "[abc]" f <regexp> matches? ] unit-test
-[ t ] [ "ab" "[abc]{1,2}" f <regexp> matches? ] unit-test
-[ f ] [ "abc" "[abc]{1,2}" f <regexp> matches? ] unit-test
-
-[ f ] [ "" "[^a]" f <regexp> matches? ] unit-test
-[ f ] [ "a" "[^a]" f <regexp> matches? ] unit-test
-[ f ] [ "a" "[^abc]" f <regexp> matches? ] unit-test
-[ t ] [ "b" "[^a]" f <regexp> matches? ] unit-test
-[ t ] [ "d" "[^abc]" f <regexp> matches? ] unit-test
-[ f ] [ "ab" "[^abc]{1,2}" f <regexp> matches? ] unit-test
-[ f ] [ "abc" "[^abc]{1,2}" f <regexp> matches? ] unit-test
-
-[ t ] [ "]" "[]]" f <regexp> matches? ] unit-test
-[ f ] [ "]" "[^]]" f <regexp> matches? ] unit-test
-
-! [ "^" "[^]" f <regexp> matches? ] must-fail
-[ t ] [ "^" "[]^]" f <regexp> matches? ] unit-test
-[ t ] [ "]" "[]^]" f <regexp> matches? ] unit-test
-
-[ t ] [ "[" "[[]" f <regexp> matches? ] unit-test
-[ f ] [ "^" "[^^]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[^^]" f <regexp> matches? ] unit-test
-
-[ t ] [ "-" "[-]" f <regexp> matches? ] unit-test
-[ f ] [ "a" "[-]" f <regexp> matches? ] unit-test
-[ f ] [ "-" "[^-]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[^-]" f <regexp> matches? ] unit-test
-
-[ t ] [ "-" "[-a]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[-a]" f <regexp> matches? ] unit-test
-[ t ] [ "-" "[a-]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[a-]" f <regexp> matches? ] unit-test
-[ f ] [ "b" "[a-]" f <regexp> matches? ] unit-test
-[ f ] [ "-" "[^-]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[^-]" f <regexp> matches? ] unit-test
-
-[ f ] [ "-" "[a-c]" f <regexp> matches? ] unit-test
-[ t ] [ "-" "[^a-c]" f <regexp> matches? ] unit-test
-[ t ] [ "b" "[a-c]" f <regexp> matches? ] unit-test
-[ f ] [ "b" "[^a-c]" f <regexp> matches? ] unit-test
-
-[ t ] [ "-" "[a-c-]" f <regexp> matches? ] unit-test
-[ f ] [ "-" "[^a-c-]" f <regexp> matches? ] unit-test
-
-[ t ] [ "\\" "[\\\\]" f <regexp> matches? ] unit-test
-[ f ] [ "a" "[\\\\]" f <regexp> matches? ] unit-test
-[ f ] [ "\\" "[^\\\\]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[^\\\\]" f <regexp> matches? ] unit-test
-
-[ t ] [ "0" "[\\d]" f <regexp> matches? ] unit-test
-[ f ] [ "a" "[\\d]" f <regexp> matches? ] unit-test
-[ f ] [ "0" "[^\\d]" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[^\\d]" f <regexp> matches? ] unit-test
-
-[ t ] [ "a" "[a-z]{1,}|[A-Z]{2,4}|b*|c|(f|g)*" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[a-z]{1,2}|[A-Z]{3,3}|b*|c|(f|g)*" f <regexp> matches? ] unit-test
-[ t ] [ "a" "[a-z]{1,2}|[A-Z]{3,3}" f <regexp> matches? ] unit-test
-
-[ t ] [ "1000" "\\d{4,6}" f <regexp> matches? ] unit-test
-[ t ] [ "1000" "[0-9]{4,6}" f <regexp> matches? ] unit-test
-
-[ t ] [ "abc" "\\p{Lower}{3}" f <regexp> matches? ] unit-test
-[ f ] [ "ABC" "\\p{Lower}{3}" f <regexp> matches? ] unit-test
-[ t ] [ "ABC" "\\p{Upper}{3}" f <regexp> matches? ] unit-test
-[ f ] [ "abc" "\\p{Upper}{3}" f <regexp> matches? ] unit-test
-
-[ f ] [ "abc" "[\\p{Upper}]{3}" f <regexp> matches? ] unit-test
-[ t ] [ "ABC" "[\\p{Upper}]{3}" f <regexp> matches? ] unit-test
-
-[ t ] [ "" "\\Q\\E" f <regexp> matches? ] unit-test
-[ f ] [ "a" "\\Q\\E" f <regexp> matches? ] unit-test
-[ t ] [ "|*+" "\\Q|*+\\E" f <regexp> matches? ] unit-test
-[ f ] [ "abc" "\\Q|*+\\E" f <regexp> matches? ] unit-test
-
-[ t ] [ "S" "\\0123" f <regexp> matches? ] unit-test
-[ t ] [ "SXY" "\\0123XY" f <regexp> matches? ] unit-test
-[ t ] [ "x" "\\x78" f <regexp> matches? ] unit-test
-[ f ] [ "y" "\\x78" f <regexp> matches? ] unit-test
-[ t ] [ "x" "\\u000078" f <regexp> matches? ] unit-test
-[ f ] [ "y" "\\u000078" f <regexp> matches? ] unit-test
-
-[ t ] [ "ab" "a+b" f <regexp> matches? ] unit-test
-[ f ] [ "b" "a+b" f <regexp> matches? ] unit-test
-[ t ] [ "aab" "a+b" f <regexp> matches? ] unit-test
-[ f ] [ "abb" "a+b" f <regexp> matches? ] unit-test
-
-[ t ] [ "abbbb" "ab*" f <regexp> matches? ] unit-test
-[ t ] [ "a" "ab*" f <regexp> matches? ] unit-test
-[ f ] [ "abab" "ab*" f <regexp> matches? ] unit-test
-
-[ f ] [ "x" "\\." f <regexp> matches? ] unit-test
-[ t ] [ "." "\\." f <regexp> matches? ] unit-test
-
-[ t ] [ "aaaab" "a+ab" f <regexp> matches? ] unit-test
-[ f ] [ "aaaxb" "a+ab" f <regexp> matches? ] unit-test
-[ t ] [ "aaacb" "a+cb" f <regexp> matches? ] unit-test
-[ f ] [ "aaaab" "a++ab" f <regexp> matches? ] unit-test
-[ t ] [ "aaacb" "a++cb" f <regexp> matches? ] unit-test
-
-[ 3 ] [ "aaacb" "a*" f <regexp> match-head ] unit-test
-[ 1 ] [ "aaacb" "a+?" f <regexp> match-head ] unit-test
-[ 2 ] [ "aaacb" "aa?" f <regexp> match-head ] unit-test
-[ 1 ] [ "aaacb" "aa??" f <regexp> match-head ] unit-test
-[ 3 ] [ "aacb" "aa?c" f <regexp> match-head ] unit-test
-[ 3 ] [ "aacb" "aa??c" f <regexp> match-head ] unit-test
-
-[ t ] [ "aaa" "AAA" t <regexp> matches? ] unit-test
-[ f ] [ "aax" "AAA" t <regexp> matches? ] unit-test
-[ t ] [ "aaa" "A*" t <regexp> matches? ] unit-test
-[ f ] [ "aaba" "A*" t <regexp> matches? ] unit-test
-[ t ] [ "b" "[AB]" t <regexp> matches? ] unit-test
-[ f ] [ "c" "[AB]" t <regexp> matches? ] unit-test
-[ t ] [ "c" "[A-Z]" t <regexp> matches? ] unit-test
-[ f ] [ "3" "[A-Z]" t <regexp> matches? ] unit-test
-
-[ ] [ 
-    "(0[lL]?|[1-9]\\d{0,9}(\\d{0,9}[lL])?|0[xX]\\p{XDigit}{1,8}(\\p{XDigit}{0,8}[lL])?|0[0-7]{1,11}([0-7]{0,11}[lL])?|([0-9]+\\.[0-9]*|\\.[0-9]+)([eE][+-]?[0-9]+)?[fFdD]?|[0-9]+([eE][+-]?[0-9]+[fFdD]?|([eE][+-]?[0-9]+)?[fFdD]))"
-    f <regexp> drop
-] unit-test
-
-[ t ] [ "fxxbar" "(?!foo).{3}bar" f <regexp> matches? ] unit-test
-[ f ] [ "foobar" "(?!foo).{3}bar" f <regexp> matches? ] unit-test
-
-[ 3 ] [ "foobar" "foo(?=bar)" f <regexp> match-head ] unit-test
-[ f ] [ "foobxr" "foo(?=bar)" f <regexp> match-head ] unit-test
-
-[ f ] [ "foobxr" "foo\\z" f <regexp> match-head ] unit-test
-[ 3 ] [ "foo" "foo\\z" f <regexp> match-head ] unit-test
-
-[ 3 ] [ "foo bar" "foo\\b" f <regexp> match-head ] unit-test
-[ f ] [ "fooxbar" "foo\\b" f <regexp> matches? ] unit-test
-[ t ] [ "foo" "foo\\b" f <regexp> matches? ] unit-test
-[ t ] [ "foo bar" "foo\\b bar" f <regexp> matches? ] unit-test
-[ f ] [ "fooxbar" "foo\\bxbar" f <regexp> matches? ] unit-test
-[ f ] [ "foo" "foo\\bbar" f <regexp> matches? ] unit-test
-
-[ f ] [ "foo bar" "foo\\B" f <regexp> matches? ] unit-test
-[ 3 ] [ "fooxbar" "foo\\B" f <regexp> match-head ] unit-test
-[ t ] [ "foo" "foo\\B" f <regexp> matches? ] unit-test
-[ f ] [ "foo bar" "foo\\B bar" f <regexp> matches? ] unit-test
-[ t ] [ "fooxbar" "foo\\Bxbar" f <regexp> matches? ] unit-test
-[ f ] [ "foo" "foo\\Bbar" f <regexp> matches? ] unit-test
-
-[ t ] [ "s@f" "[a-z.-]@[a-z]" f <regexp> matches? ] unit-test
-[ f ] [ "a" "[a-z.-]@[a-z]" f <regexp> matches? ] unit-test
-[ t ] [ ".o" "\\.[a-z]" f <regexp> matches? ] unit-test
-
-! Bug in parsing word
-[ t ] [
-    "a"
-    R' a'
-    matches?
-] unit-test
diff --git a/extra/parser-combinators/regexp/regexp.factor b/extra/parser-combinators/regexp/regexp.factor
deleted file mode 100755 (executable)
index 1c94308..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-USING: arrays combinators kernel lists math math.parser
-namespaces parser lexer parser-combinators
-parser-combinators.simple promises quotations sequences strings
-math.order assocs prettyprint.backend prettyprint.custom memoize
-ascii unicode.categories combinators.short-circuit
-accessors make io ;
-IN: parser-combinators.regexp
-
-<PRIVATE
-
-SYMBOL: ignore-case?
-
-: char=-quot ( ch -- quot )
-    ignore-case? get
-    [ ch>upper [ swap ch>upper = ] ] [ [ = ] ] if
-    curry ;
-
-: char-between?-quot ( ch1 ch2 -- quot )
-    ignore-case? get
-    [ [ ch>upper ] bi@ [ [ ch>upper ] 2dip between? ] ]
-    [ [ between? ] ]
-    if 2curry ;
-
-: <@literal ( parser obj -- action ) [ nip ] curry <@ ;
-
-: <@delay ( parser quot -- action ) [ curry ] curry <@ ;
-
-PRIVATE>
-
-: ascii? ( n -- ? ) 
-    0 HEX: 7f between? ;
-
-: octal-digit? ( n -- ? )
-    CHAR: 0 CHAR: 7 between? ;
-
-: decimal-digit? ( n -- ? )
-    CHAR: 0 CHAR: 9 between? ;
-
-: hex-digit? ( n -- ? )
-    dup decimal-digit?
-    over CHAR: a CHAR: f between? or
-    swap CHAR: A CHAR: F between? or ;
-
-: control-char? ( n -- ? )
-    dup 0 HEX: 1f between?
-    swap HEX: 7f = or ;
-
-: punct? ( n -- ? )
-    "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" member? ;
-
-: c-identifier-char? ( ch -- ? )
-    dup alpha? swap CHAR: _ = or ;
-
-: java-blank? ( n -- ? )
-    {
-        CHAR: \s
-        CHAR: \t CHAR: \n CHAR: \r
-        HEX: c HEX: 7 HEX: 1b
-    } member? ;
-
-: java-printable? ( n -- ? )
-    dup alpha? swap punct? or ;
-
-: 'ordinary-char' ( -- parser )
-    [ "\\^*+?|(){}[$" member? not ] satisfy
-    [ char=-quot ] <@ ;
-
-: 'octal-digit' ( -- parser ) [ octal-digit? ] satisfy ;
-
-: 'octal' ( -- parser )
-    "0" token 'octal-digit' 1 3 from-m-to-n &>
-    [ oct> ] <@ ;
-
-: 'hex-digit' ( -- parser ) [ hex-digit? ] satisfy ;
-
-: 'hex' ( -- parser )
-    "x" token 'hex-digit' 2 exactly-n &>
-    "u" token 'hex-digit' 6 exactly-n &> <|>
-    [ hex> ] <@ ;
-
-: satisfy-tokens ( assoc -- parser )
-    [ [ token ] dip <@literal ] { } assoc>map <or-parser> ;
-
-: 'simple-escape-char' ( -- parser )
-    {
-        { "\\" CHAR: \\ }
-        { "t"  CHAR: \t }
-        { "n"  CHAR: \n }
-        { "r"  CHAR: \r }
-        { "f"  HEX: c   }
-        { "a"  HEX: 7   }
-        { "e"  HEX: 1b  }
-    } [ char=-quot ] assoc-map satisfy-tokens ;
-
-: 'predefined-char-class' ( -- parser )
-    {
-        { "d" [ digit? ] }
-        { "D" [ digit? not ] }
-        { "s" [ java-blank? ] }
-        { "S" [ java-blank? not ] }
-        { "w" [ c-identifier-char? ] }
-        { "W" [ c-identifier-char? not ] }
-    } satisfy-tokens ;
-
-: 'posix-character-class' ( -- parser )
-    {
-        { "Lower" [ letter? ] }
-        { "Upper" [ LETTER? ] }
-        { "ASCII" [ ascii? ] }
-        { "Alpha" [ Letter? ] }
-        { "Digit" [ digit? ] }
-        { "Alnum" [ alpha? ] }
-        { "Punct" [ punct? ] }
-        { "Graph" [ java-printable? ] }
-        { "Print" [ java-printable? ] }
-        { "Blank" [ " \t" member? ] }
-        { "Cntrl" [ control-char? ] }
-        { "XDigit" [ hex-digit? ] }
-        { "Space" [ java-blank? ] }
-    } satisfy-tokens "p{" "}" surrounded-by ;
-
-: 'simple-escape' ( -- parser )
-    'octal'
-    'hex' <|>
-    "c" token [ LETTER? ] satisfy &> <|>
-    any-char-parser <|>
-    [ char=-quot ] <@ ;
-
-: 'escape' ( -- parser )
-    "\\" token
-    'simple-escape-char'
-    'predefined-char-class' <|>
-    'posix-character-class' <|>
-    'simple-escape' <|> &> ;
-
-: 'any-char' ( -- parser )
-    "." token [ drop t ] <@literal ;
-
-: 'char' ( -- parser )
-    'any-char' 'escape' 'ordinary-char' <|> <|> [ satisfy ] <@ ;
-
-DEFER: 'regexp'
-
-TUPLE: group-result str ;
-
-C: <group-result> group-result
-
-: 'non-capturing-group' ( -- parser )
-    "?:" token 'regexp' &> ;
-
-: 'positive-lookahead-group' ( -- parser )
-    "?=" token 'regexp' &> [ ensure ] <@ ;
-
-: 'negative-lookahead-group' ( -- parser )
-    "?!" token 'regexp' &> [ ensure-not ] <@ ;
-
-: 'simple-group' ( -- parser )
-    'regexp' [ [ <group-result> ] <@ ] <@ ;
-
-: 'group' ( -- parser )
-    'non-capturing-group'
-    'positive-lookahead-group'
-    'negative-lookahead-group'
-    'simple-group' <|> <|> <|>
-    "(" ")" surrounded-by ;
-
-: 'range' ( -- parser )
-    [ CHAR: ] = not ] satisfy "-" token <&
-    [ CHAR: ] = not ] satisfy <&>
-    [ first2 char-between?-quot ] <@ ;
-
-: 'character-class-term' ( -- parser )
-    'range'
-    'escape' <|>
-    [ "\\]" member? not ] satisfy [ char=-quot ] <@ <|> ;
-
-: 'positive-character-class' ( -- parser )
-    "]" token [ CHAR: ] = ] <@literal 'character-class-term' <*> <&:>
-    'character-class-term' <+> <|>
-    [ [ 1|| ] curry ] <@ ;
-
-: 'negative-character-class' ( -- parser )
-    "^" token 'positive-character-class' &>
-    [ [ not ] append ] <@ ;
-
-: 'character-class' ( -- parser )
-    'negative-character-class' 'positive-character-class' <|>
-    "[" "]" surrounded-by [ satisfy ] <@ ;
-
-: 'escaped-seq' ( -- parser )
-    any-char-parser <*>
-    [ ignore-case? get <token-parser> ] <@
-    "\\Q" "\\E" surrounded-by ;
-
-: 'break' ( quot -- parser )
-    satisfy ensure epsilon just <|> ;
-
-: 'break-escape' ( -- parser )
-    "$" token [ "\r\n" member? ] 'break' <@literal
-    "\\b" token [ blank? ] 'break' <@literal <|>
-    "\\B" token [ blank? not ] 'break' <@literal <|>
-    "\\z" token epsilon just <@literal <|> ;
-
-: 'simple' ( -- parser )
-    'escaped-seq'
-    'break-escape' <|>
-    'group' <|>
-    'character-class' <|>
-    'char' <|> ;
-
-: 'exactly-n' ( -- parser )
-    'integer' [ exactly-n ] <@delay ;
-
-: 'at-least-n' ( -- parser )
-    'integer' "," token <& [ at-least-n ] <@delay ;
-
-: 'at-most-n' ( -- parser )
-    "," token 'integer' &> [ at-most-n ] <@delay ;
-
-: 'from-m-to-n' ( -- parser )
-    'integer' "," token <& 'integer' <&> [ first2 from-m-to-n ] <@delay ;
-
-: 'greedy-interval' ( -- parser )
-    'exactly-n' 'at-least-n' <|> 'at-most-n' <|> 'from-m-to-n' <|> ;
-
-: 'interval' ( -- parser )
-    'greedy-interval'
-    'greedy-interval' "?" token <& [ "reluctant {}" print ] <@ <|>
-    'greedy-interval' "+" token <& [ "possessive {}" print ] <@ <|>
-    "{" "}" surrounded-by ;
-
-: 'repetition' ( -- parser )
-    ! Posessive
-    "*+" token [ <!*> ] <@literal
-    "++" token [ <!+> ] <@literal <|>
-    "?+" token [ <!?> ] <@literal <|>
-    ! Reluctant
-    "*?" token [ <(*)> ] <@literal <|>
-    "+?" token [ <(+)> ] <@literal <|>
-    "??" token [ <(?)> ] <@literal <|>
-    ! Greedy
-    "*" token [ <*> ] <@literal <|>
-    "+" token [ <+> ] <@literal <|>
-    "?" token [ <?> ] <@literal <|> ;
-
-: 'dummy' ( -- parser )
-    epsilon [ ] <@literal ;
-
-MEMO: 'term' ( -- parser )
-    'simple'
-    'repetition' 'interval' 'dummy' <|> <|> <&> [ first2 call ] <@
-    <!+> [ <and-parser> ] <@ ;
-
-LAZY: 'regexp' ( -- parser )
-    'term' "|" token nonempty-list-of [ <or-parser> ] <@ ;
-!    "^" token 'term' "|" token nonempty-list-of [ <or-parser> ] <@
-!        &> [ "caret" print ] <@ <|>
-!    'term' "|" token nonempty-list-of [ <or-parser> ] <@
-!        "$" token <& [ "dollar" print ] <@ <|>
-!    "^" token 'term' "|" token nonempty-list-of [ <or-parser> ] <@ &>
-!        "$" token [ "caret dollar" print ] <@ <& <|> ;
-
-TUPLE: regexp source parser ignore-case? ;
-
-: <regexp> ( string ignore-case? -- regexp )
-    [
-        ignore-case? [
-            dup 'regexp' just parse-1
-        ] with-variable
-    ] keep regexp boa ;
-
-: do-ignore-case ( string regexp -- string regexp )
-    dup ignore-case?>> [ [ >upper ] dip ] when ;
-
-: matches? ( string regexp -- ? )
-    do-ignore-case parser>> just parse nil? not ;
-
-: match-head ( string regexp -- end )
-    do-ignore-case parser>> parse dup nil?
-    [ drop f ] [ car unparsed>> from>> ] if ;
-
-! Literal syntax for regexps
-: parse-options ( string -- ? )
-    #! Lame
-    {
-        { "" [ f ] }
-        { "i" [ t ] }
-    } case ;
-
-: parse-regexp ( accum end -- accum )
-    lexer get dup skip-blank
-    [ [ index-from dup 1+ swap ] 2keep swapd subseq swap ] change-lexer-column
-    lexer get dup still-parsing-line?
-    [ (parse-token) parse-options ] [ drop f ] if
-    <regexp> parsed ;
-
-: R! CHAR: ! parse-regexp ; parsing
-: R" CHAR: " parse-regexp ; parsing
-: R# CHAR: # parse-regexp ; parsing
-: R' CHAR: ' parse-regexp ; parsing
-: R( CHAR: ) parse-regexp ; parsing
-: R/ CHAR: / parse-regexp ; parsing
-: R@ CHAR: @ parse-regexp ; parsing
-: R[ CHAR: ] parse-regexp ; parsing
-: R` CHAR: ` parse-regexp ; parsing
-: R{ CHAR: } parse-regexp ; parsing
-: R| CHAR: | parse-regexp ; parsing
-
-: find-regexp-syntax ( string -- prefix suffix )
-    {
-        { "R/ "  "/"  }
-        { "R! "  "!"  }
-        { "R\" " "\"" }
-        { "R# "  "#"  }
-        { "R' "  "'"  }
-        { "R( "  ")"  }
-        { "R@ "  "@"  }
-        { "R[ "  "]"  }
-        { "R` "  "`"  }
-        { "R{ "  "}"  }
-        { "R| "  "|"  }
-    } swap [ subseq? not nip ] curry assoc-find drop ;
-
-M: regexp pprint*
-    [
-        dup source>>
-        dup find-regexp-syntax swap % swap % %
-        dup ignore-case?>> [ "i" % ] when
-    ] "" make
-    swap present-text ;
diff --git a/extra/parser-combinators/regexp/summary.txt b/extra/parser-combinators/regexp/summary.txt
deleted file mode 100644 (file)
index aa1e1c2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Regular expressions
diff --git a/extra/parser-combinators/regexp/tags.txt b/extra/parser-combinators/regexp/tags.txt
deleted file mode 100755 (executable)
index 65bc471..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-parsing
-text
diff --git a/extra/peg-lexer/authors.txt b/extra/peg-lexer/authors.txt
new file mode 100644 (file)
index 0000000..ce0899f
--- /dev/null
@@ -0,0 +1 @@
+Sam Anklesaria
\ No newline at end of file
diff --git a/extra/peg-lexer/peg-lexer-docs.factor b/extra/peg-lexer/peg-lexer-docs.factor
new file mode 100644 (file)
index 0000000..18a458e
--- /dev/null
@@ -0,0 +1,14 @@
+USING: peg.ebnf help.syntax help.markup strings ;
+IN: peg-lexer
+
+HELP: ON-BNF:
+{ $syntax "ON-BNF: word ... ;ON-BNF" }
+{ $description "Creates a parsing word using a parser for lexer control, adding the resulting ast to the stack.  Parser syntax is as in " { $link POSTPONE: EBNF: } } ;
+
+HELP: create-bnf
+{ $values { "name" string } { "parser" parser } }
+{ $description "Runtime equivalent of " { $link POSTPONE: ON-BNF: } " also useful with manually constructed parsers." } ;
+
+HELP: factor
+{ $values { "input" string } { "ast" "a sequence of tokens" } }
+{ $description "Tokenizer that acts like standard factor lexer, separating tokens by whitespace." } ;
\ No newline at end of file
diff --git a/extra/peg-lexer/peg-lexer-tests.factor b/extra/peg-lexer/peg-lexer-tests.factor
new file mode 100644 (file)
index 0000000..99a1397
--- /dev/null
@@ -0,0 +1,14 @@
+USING: tools.test peg-lexer.test-parsers ;
+IN: peg-lexer.tests
+
+{ V{ "1234" "-end" } } [
+   test1 1234-end
+] unit-test
+
+{ V{ 1234 53 } } [
+   test2 12345
+] unit-test
+
+{ V{ "heavy" "duty" "testing" } } [
+   test3 heavy duty testing
+] unit-test
\ No newline at end of file
diff --git a/extra/peg-lexer/peg-lexer.factor b/extra/peg-lexer/peg-lexer.factor
new file mode 100644 (file)
index 0000000..90d2e0e
--- /dev/null
@@ -0,0 +1,63 @@
+USING: hashtables assocs sequences locals math accessors multiline delegate strings
+delegate.protocols kernel peg peg.ebnf lexer namespaces combinators parser words ;
+IN: peg-lexer
+
+TUPLE: lex-hash hash ;
+CONSULT: assoc-protocol lex-hash hash>> ;
+: <lex-hash> ( a -- lex-hash ) lex-hash boa ;
+
+: pos-or-0 ( neg? -- pos/0 ) dup 0 < [ drop 0 ] when ;
+
+:: prepare-pos ( v i -- c l )
+    [let | n [ i v head-slice ] |
+           v CHAR: \n n last-index -1 or 1+ -
+           n [ CHAR: \n = ] count 1+
+    ] ;
+      
+: store-pos ( v a -- )
+    input swap at prepare-pos
+    lexer get [ (>>line) ] keep (>>column) ;
+
+M: lex-hash set-at
+    swap {
+        { pos [ store-pos ] }
+        [ swap hash>> set-at ]
+    } case ;
+
+:: at-pos ( t l c -- p ) t l head-slice [ length ] map sum l 1- + c + ;
+
+M: lex-hash at*
+    swap {
+      { input [ drop lexer get text>> "\n" join t ] }
+      { pos [ drop lexer get [ text>> ] [ line>> 1- ] [ column>> 1+ ] tri at-pos t ] }
+      [ swap hash>> at* ]
+    } case ;
+
+: with-global-lexer ( quot -- result )
+   [
+       f lrstack set
+       V{ } clone error-stack set H{ } clone \ heads set
+       H{ } clone \ packrat set
+   ] f make-assoc <lex-hash>
+   swap bind ; inline
+
+: parse* ( parser -- ast )
+    compile
+    [ execute [ error-stack get first throw ] unless* ] with-global-lexer
+    ast>> ;
+
+: create-bnf ( name parser -- )
+    reset-tokenizer [ lexer get skip-blank parse* parsed ] curry
+    define-syntax ;
+    
+SYNTAX: ON-BNF:
+    CREATE-WORD reset-tokenizer ";ON-BNF" parse-multiline-string parse-ebnf
+    main swap at create-bnf ;
+
+! Tokenizer like standard factor lexer
+EBNF: factor
+space = " " | "\n" | "\t"
+spaces = space* => [[ drop ignore ]]
+chunk = (!(space) .)+ => [[ >string ]]
+expr = spaces chunk
+;EBNF
\ No newline at end of file
diff --git a/extra/peg-lexer/summary.txt b/extra/peg-lexer/summary.txt
new file mode 100755 (executable)
index 0000000..2de36ba
--- /dev/null
@@ -0,0 +1 @@
+Use peg to write parsing words
diff --git a/extra/peg-lexer/tags.txt b/extra/peg-lexer/tags.txt
new file mode 100644 (file)
index 0000000..44385cf
--- /dev/null
@@ -0,0 +1,2 @@
+extensions
+reflection
diff --git a/extra/peg-lexer/test-parsers/test-parsers.factor b/extra/peg-lexer/test-parsers/test-parsers.factor
new file mode 100644 (file)
index 0000000..83c9f85
--- /dev/null
@@ -0,0 +1,17 @@
+USING: peg-lexer math.parser strings ;
+IN: peg-lexer.test-parsers
+
+ON-BNF: test1
+      num = [1-4]* => [[ >string ]]
+      expr = num ( "-end" | "-done" )
+;ON-BNF
+
+ON-BNF: test2
+      num = [1-4]* => [[ >string string>number ]]
+      expr= num [5-9]
+;ON-BNF
+
+ON-BNF: test3
+      tokenizer = <foreign factor>
+      expr= "heavy" "duty" "testing"
+;ON-BNF
\ No newline at end of file
index eff923dc011eba44d708613286efc92679c34e9d..179e03f1cfbc2bd4ff0e69b2173393db94114b57 100644 (file)
@@ -6,20 +6,20 @@ IN: peg.pl0
 
 #! Grammar for PL/0 based on http://en.wikipedia.org/wiki/PL/0
 
-EBNF: pl0 
+EBNF: pl0
 
-block       =  { "CONST" ident "=" number { "," ident "=" number }* ";" }? 
-               { "VAR" ident { "," ident }* ";" }? 
-               { "PROCEDURE" ident ";" { block ";" }? }* statement 
-statement   =  {  ident ":=" expression 
-                | "CALL" ident 
-                | "BEGIN" statement { ";" statement }* "END" 
-                | "IF" condition "THEN" statement 
-                | "WHILE" condition "DO" statement }?  
+block       =  { "CONST" ident "=" number { "," ident "=" number }* ";" }?
+               { "VAR" ident { "," ident }* ";" }?
+               { "PROCEDURE" ident ";" { block ";" }? }* statement
+statement   =  {  ident ":=" expression
+                | "CALL" ident
+                | "BEGIN" statement { ";" statement }* "END"
+                | "IF" condition "THEN" statement
+                | "WHILE" condition "DO" statement }?
 condition   =  { "ODD" expression }
              | { expression ("=" | "#" | "<=" | "<" | ">=" | ">") expression }
-expression  = {"+" | "-"}? term { {"+" | "-"} term }* 
-term        = factor { {"*" | "/"} factor }* 
+expression  = {"+" | "-"}? term { {"+" | "-"} term }*
+term        = factor { {"*" | "/"} factor }*
 factor      = ident | number | "(" expression ")"
 ident       = (([a-zA-Z])+)   => [[ >string ]]
 digit       = ([0-9])         => [[ digit> ]]
diff --git a/extra/poker/arrays/arrays.factor b/extra/poker/arrays/arrays.factor
new file mode 100644 (file)
index 0000000..bf758f1
--- /dev/null
@@ -0,0 +1,1018 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+IN: poker.arrays
+
+! This is a lookup table for all flush hands. A zero means that specific
+! combination is not possible with this type of hand.
+CONSTANT: flushes-table
+{ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 1599 0 0 0 0 0 0 0 1598 0 0 0 1597 0 1596 8 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1595 0 0 0 0 0 0 0 1594 0 0 0 1593 0 1592 1591 0 0 0 0 0 0 0 0 1590
+0 0 0 1589 0 1588 1587 0 0 0 0 1586 0 1585 1584 0 0 1583 1582 0 7 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 1581 0 0 0 0 0 0 0 1580 0 0 0 1579 0 1578 1577 0 0 0 0 0
+0 0 0 1576 0 0 0 1575 0 1574 1573 0 0 0 0 1572 0 1571 1570 0 0 1569 1568 0 1567
+0 0 0 0 0 0 0 0 0 0 1566 0 0 0 1565 0 1564 1563 0 0 0 0 1562 0 1561 1560 0 0
+1559 1558 0 1557 0 0 0 0 0 0 1556 0 1555 1554 0 0 1553 1552 0 1551 0 0 0 0 1550
+1549 0 1548 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1547 0 0 0 0 0
+0 0 1546 0 0 0 1545 0 1544 1543 0 0 0 0 0 0 0 0 1542 0 0 0 1541 0 1540 1539 0 0
+0 0 1538 0 1537 1536 0 0 1535 1534 0 1533 0 0 0 0 0 0 0 0 0 0 1532 0 0 0 1531 0
+1530 1529 0 0 0 0 1528 0 1527 1526 0 0 1525 1524 0 1523 0 0 0 0 0 0 1522 0 1521
+1520 0 0 1519 1518 0 1517 0 0 0 0 1516 1515 0 1514 0 0 0 1513 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 1512 0 0 0 1511 0 1510 1509 0 0 0 0 1508 0 1507 1506 0 0 1505 1504 0
+1503 0 0 0 0 0 0 1502 0 1501 1500 0 0 1499 1498 0 1497 0 0 0 0 1496 1495 0 1494
+0 0 0 1493 0 0 0 0 0 0 0 0 0 0 1492 0 1491 1490 0 0 1489 1488 0 1487 0 0 0 0
+1486 1485 0 1484 0 0 0 1483 0 0 0 0 0 0 0 0 1482 1481 0 1480 0 0 0 1479 0 0 0 0
+0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1478 0 0 0
+0 0 0 0 1477 0 0 0 1476 0 1475 1474 0 0 0 0 0 0 0 0 1473 0 0 0 1472 0 1471 1470
+0 0 0 0 1469 0 1468 1467 0 0 1466 1465 0 1464 0 0 0 0 0 0 0 0 0 0 1463 0 0 0
+1462 0 1461 1460 0 0 0 0 1459 0 1458 1457 0 0 1456 1455 0 1454 0 0 0 0 0 0 1453
+0 1452 1451 0 0 1450 1449 0 1448 0 0 0 0 1447 1446 0 1445 0 0 0 1444 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 1443 0 0 0 1442 0 1441 1440 0 0 0 0 1439 0 1438 1437 0 0 1436
+1435 0 1434 0 0 0 0 0 0 1433 0 1432 1431 0 0 1430 1429 0 1428 0 0 0 0 1427 1426
+0 1425 0 0 0 1424 0 0 0 0 0 0 0 0 0 0 1423 0 1422 1421 0 0 1420 1419 0 1418 0 0
+0 0 1417 1416 0 1415 0 0 0 1414 0 0 0 0 0 0 0 0 1413 1412 0 1411 0 0 0 1410 0 0
+0 0 0 0 0 1409 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1408 0 0 0 1407 0
+1406 1405 0 0 0 0 1404 0 1403 1402 0 0 1401 1400 0 1399 0 0 0 0 0 0 1398 0 1397
+1396 0 0 1395 1394 0 1393 0 0 0 0 1392 1391 0 1390 0 0 0 1389 0 0 0 0 0 0 0 0 0
+0 1388 0 1387 1386 0 0 1385 1384 0 1383 0 0 0 0 1382 1381 0 1380 0 0 0 1379 0 0
+0 0 0 0 0 0 1378 1377 0 1376 0 0 0 1375 0 0 0 0 0 0 0 1374 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 1373 0 1372 1371 0 0 1370 1369 0 1368 0 0 0 0 1367 1366 0 1365
+0 0 0 1364 0 0 0 0 0 0 0 0 1363 1362 0 1361 0 0 0 1360 0 0 0 0 0 0 0 1359 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 1358 1357 0 1356 0 0 0 1355 0 0 0 0 0 0 0 1354 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1353 0 0 0 0 0 0 0 1352 0 0 0 1351 0 1350
+1349 0 0 0 0 0 0 0 0 1348 0 0 0 1347 0 1346 1345 0 0 0 0 1344 0 1343 1342 0 0
+1341 1340 0 1339 0 0 0 0 0 0 0 0 0 0 1338 0 0 0 1337 0 1336 1335 0 0 0 0 1334 0
+1333 1332 0 0 1331 1330 0 1329 0 0 0 0 0 0 1328 0 1327 1326 0 0 1325 1324 0
+1323 0 0 0 0 1322 1321 0 1320 0 0 0 1319 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1318 0 0 0
+1317 0 1316 1315 0 0 0 0 1314 0 1313 1312 0 0 1311 1310 0 1309 0 0 0 0 0 0 1308
+0 1307 1306 0 0 1305 1304 0 1303 0 0 0 0 1302 1301 0 1300 0 0 0 1299 0 0 0 0 0
+0 0 0 0 0 1298 0 1297 1296 0 0 1295 1294 0 1293 0 0 0 0 1292 1291 0 1290 0 0 0
+1289 0 0 0 0 0 0 0 0 1288 1287 0 1286 0 0 0 1285 0 0 0 0 0 0 0 1284 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1283 0 0 0 1282 0 1281 1280 0 0 0 0 1279 0 1278
+1277 0 0 1276 1275 0 1274 0 0 0 0 0 0 1273 0 1272 1271 0 0 1270 1269 0 1268 0 0
+0 0 1267 1266 0 1265 0 0 0 1264 0 0 0 0 0 0 0 0 0 0 1263 0 1262 1261 0 0 1260
+1259 0 1258 0 0 0 0 1257 1256 0 1255 0 0 0 1254 0 0 0 0 0 0 0 0 1253 1252 0
+1251 0 0 0 1250 0 0 0 0 0 0 0 1249 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1248 0
+1247 1246 0 0 1245 1244 0 1243 0 0 0 0 1242 1241 0 1240 0 0 0 1239 0 0 0 0 0 0
+0 0 1238 1237 0 1236 0 0 0 1235 0 0 0 0 0 0 0 1234 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1233 1232 0 1231 0 0 0 1230 0 0 0 0 0 0 0 1229 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1228 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1227 0 0 0 1226 0 1225 1224 0 0 0 0 1223 0 1222 1221 0 0 1220 1219 0 1218 0
+0 0 0 0 0 1217 0 1216 1215 0 0 1214 1213 0 1212 0 0 0 0 1211 1210 0 1209 0 0 0
+1208 0 0 0 0 0 0 0 0 0 0 1207 0 1206 1205 0 0 1204 1203 0 1202 0 0 0 0 1201
+1200 0 1199 0 0 0 1198 0 0 0 0 0 0 0 0 1197 1196 0 1195 0 0 0 1194 0 0 0 0 0 0
+0 1193 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1192 0 1191 1190 0 0 1189 1188 0
+1187 0 0 0 0 1186 1185 0 1184 0 0 0 1183 0 0 0 0 0 0 0 0 1182 1181 0 1180 0 0 0
+1179 0 0 0 0 0 0 0 1178 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1177 1176 0 1175 0 0 0
+1174 0 0 0 0 0 0 0 1173 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1172 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1171 0 1170 1169 0 0 1168 1167
+0 1166 0 0 0 0 1165 1164 0 1163 0 0 0 1162 0 0 0 0 0 0 0 0 1161 1160 0 1159 0 0
+0 1158 0 0 0 0 0 0 0 1157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1156 1155 0 1154 0 0
+0 1153 0 0 0 0 0 0 0 1152 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1151 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1150 1149 0 1148 0 0 0 1147 0 0 0
+0 0 0 0 1146 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1144 0 0 0 0 0 0 0 1143 0 0 0 1142 0 1141 1140 0 0
+0 0 0 0 0 0 1139 0 0 0 1138 0 1137 1136 0 0 0 0 1135 0 1134 1133 0 0 1132 1131
+0 1130 0 0 0 0 0 0 0 0 0 0 1129 0 0 0 1128 0 1127 1126 0 0 0 0 1125 0 1124 1123
+0 0 1122 1121 0 1120 0 0 0 0 0 0 1119 0 1118 1117 0 0 1116 1115 0 1114 0 0 0 0
+1113 1112 0 1111 0 0 0 1110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1109 0 0 0 1108 0 1107
+1106 0 0 0 0 1105 0 1104 1103 0 0 1102 1101 0 1100 0 0 0 0 0 0 1099 0 1098 1097
+0 0 1096 1095 0 1094 0 0 0 0 1093 1092 0 1091 0 0 0 1090 0 0 0 0 0 0 0 0 0 0
+1089 0 1088 1087 0 0 1086 1085 0 1084 0 0 0 0 1083 1082 0 1081 0 0 0 1080 0 0 0
+0 0 0 0 0 1079 1078 0 1077 0 0 0 1076 0 0 0 0 0 0 0 1075 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 1074 0 0 0 1073 0 1072 1071 0 0 0 0 1070 0 1069 1068 0 0
+1067 1066 0 1065 0 0 0 0 0 0 1064 0 1063 1062 0 0 1061 1060 0 1059 0 0 0 0 1058
+1057 0 1056 0 0 0 1055 0 0 0 0 0 0 0 0 0 0 1054 0 1053 1052 0 0 1051 1050 0
+1049 0 0 0 0 1048 1047 0 1046 0 0 0 1045 0 0 0 0 0 0 0 0 1044 1043 0 1042 0 0 0
+1041 0 0 0 0 0 0 0 1040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1039 0 1038 1037 0
+0 1036 1035 0 1034 0 0 0 0 1033 1032 0 1031 0 0 0 1030 0 0 0 0 0 0 0 0 1029
+1028 0 1027 0 0 0 1026 0 0 0 0 0 0 0 1025 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1024
+1023 0 1022 0 0 0 1021 0 0 0 0 0 0 0 1020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1019 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1018
+0 0 0 1017 0 1016 1015 0 0 0 0 1014 0 1013 1012 0 0 1011 1010 0 1009 0 0 0 0 0
+0 1008 0 1007 1006 0 0 1005 1004 0 1003 0 0 0 0 1002 1001 0 1000 0 0 0 999 0 0
+0 0 0 0 0 0 0 0 998 0 997 996 0 0 995 994 0 993 0 0 0 0 992 991 0 990 0 0 0 989
+0 0 0 0 0 0 0 0 988 987 0 986 0 0 0 985 0 0 0 0 0 0 0 984 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 983 0 982 981 0 0 980 979 0 978 0 0 0 0 977 976 0 975 0 0 0 974 0
+0 0 0 0 0 0 0 973 972 0 971 0 0 0 970 0 0 0 0 0 0 0 969 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 968 967 0 966 0 0 0 965 0 0 0 0 0 0 0 964 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+963 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 962 0
+961 960 0 0 959 958 0 957 0 0 0 0 956 955 0 954 0 0 0 953 0 0 0 0 0 0 0 0 952
+951 0 950 0 0 0 949 0 0 0 0 0 0 0 948 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 947 946 0
+945 0 0 0 944 0 0 0 0 0 0 0 943 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 942 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 941 940 0 939 0 0 0 938 0 0 0
+0 0 0 0 937 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 936 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 935 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 934 0 0 0 933 0 932 931 0 0 0 0 930 0 929 928 0 0 927 926 0 925 0 0
+0 0 0 0 924 0 923 922 0 0 921 920 0 919 0 0 0 0 918 917 0 916 0 0 0 915 0 0 0 0
+0 0 0 0 0 0 914 0 913 912 0 0 911 910 0 909 0 0 0 0 908 907 0 906 0 0 0 905 0 0
+0 0 0 0 0 0 904 903 0 902 0 0 0 901 0 0 0 0 0 0 0 900 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 899 0 898 897 0 0 896 895 0 894 0 0 0 0 893 892 0 891 0 0 0 890 0 0 0
+0 0 0 0 0 889 888 0 887 0 0 0 886 0 0 0 0 0 0 0 885 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 884 883 0 882 0 0 0 881 0 0 0 0 0 0 0 880 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 879
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 878 0 877
+876 0 0 875 874 0 873 0 0 0 0 872 871 0 870 0 0 0 869 0 0 0 0 0 0 0 0 868 867 0
+866 0 0 0 865 0 0 0 0 0 0 0 864 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 863 862 0 861 0
+0 0 860 0 0 0 0 0 0 0 859 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 858 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 857 856 0 855 0 0 0 854 0 0 0 0 0 0
+0 853 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 852 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 851 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+850 0 849 848 0 0 847 846 0 845 0 0 0 0 844 843 0 842 0 0 0 841 0 0 0 0 0 0 0 0
+840 839 0 838 0 0 0 837 0 0 0 0 0 0 0 836 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 835
+834 0 833 0 0 0 832 0 0 0 0 0 0 0 831 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 830 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 829 828 0 827 0 0 0 826
+0 0 0 0 0 0 0 825 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 824 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 823 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 822 821 0 820 0 0 0 819 0 0 0 0 0 0 0 818 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+817 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 816 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 10 0 0 0 0 0 0 0 815 0 0 0 814 0 813 812 0 0 0 0 0 0 0 0 811 0 0 0 810 0 809
+808 0 0 0 0 807 0 806 805 0 0 804 803 0 802 0 0 0 0 0 0 0 0 0 0 801 0 0 0 800 0
+799 798 0 0 0 0 797 0 796 795 0 0 794 793 0 792 0 0 0 0 0 0 791 0 790 789 0 0
+788 787 0 786 0 0 0 0 785 784 0 783 0 0 0 782 0 0 0 0 0 0 0 0 0 0 0 0 0 0 781 0
+0 0 780 0 779 778 0 0 0 0 777 0 776 775 0 0 774 773 0 772 0 0 0 0 0 0 771 0 770
+769 0 0 768 767 0 766 0 0 0 0 765 764 0 763 0 0 0 762 0 0 0 0 0 0 0 0 0 0 761 0
+760 759 0 0 758 757 0 756 0 0 0 0 755 754 0 753 0 0 0 752 0 0 0 0 0 0 0 0 751
+750 0 749 0 0 0 748 0 0 0 0 0 0 0 747 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 746 0 0 0 745 0 744 743 0 0 0 0 742 0 741 740 0 0 739 738 0 737 0 0 0 0 0 0
+736 0 735 734 0 0 733 732 0 731 0 0 0 0 730 729 0 728 0 0 0 727 0 0 0 0 0 0 0 0
+0 0 726 0 725 724 0 0 723 722 0 721 0 0 0 0 720 719 0 718 0 0 0 717 0 0 0 0 0 0
+0 0 716 715 0 714 0 0 0 713 0 0 0 0 0 0 0 712 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 711 0 710 709 0 0 708 707 0 706 0 0 0 0 705 704 0 703 0 0 0 702 0 0 0 0 0 0 0
+0 701 700 0 699 0 0 0 698 0 0 0 0 0 0 0 697 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 696
+695 0 694 0 0 0 693 0 0 0 0 0 0 0 692 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 691 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 690 0 0 0
+689 0 688 687 0 0 0 0 686 0 685 684 0 0 683 682 0 681 0 0 0 0 0 0 680 0 679 678
+0 0 677 676 0 675 0 0 0 0 674 673 0 672 0 0 0 671 0 0 0 0 0 0 0 0 0 0 670 0 669
+668 0 0 667 666 0 665 0 0 0 0 664 663 0 662 0 0 0 661 0 0 0 0 0 0 0 0 660 659 0
+658 0 0 0 657 0 0 0 0 0 0 0 656 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 655 0 654
+653 0 0 652 651 0 650 0 0 0 0 649 648 0 647 0 0 0 646 0 0 0 0 0 0 0 0 645 644 0
+643 0 0 0 642 0 0 0 0 0 0 0 641 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 640 639 0 638 0
+0 0 637 0 0 0 0 0 0 0 636 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 635 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 634 0 633 632 0 0 631 630 0 629
+0 0 0 0 628 627 0 626 0 0 0 625 0 0 0 0 0 0 0 0 624 623 0 622 0 0 0 621 0 0 0 0
+0 0 0 620 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 619 618 0 617 0 0 0 616 0 0 0 0 0 0 0
+615 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 614 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 613 612 0 611 0 0 0 610 0 0 0 0 0 0 0 609 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+607 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 606 0 0 0 605 0
+604 603 0 0 0 0 602 0 601 600 0 0 599 598 0 597 0 0 0 0 0 0 596 0 595 594 0 0
+593 592 0 591 0 0 0 0 590 589 0 588 0 0 0 587 0 0 0 0 0 0 0 0 0 0 586 0 585 584
+0 0 583 582 0 581 0 0 0 0 580 579 0 578 0 0 0 577 0 0 0 0 0 0 0 0 576 575 0 574
+0 0 0 573 0 0 0 0 0 0 0 572 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 571 0 570 569 0
+0 568 567 0 566 0 0 0 0 565 564 0 563 0 0 0 562 0 0 0 0 0 0 0 0 561 560 0 559 0
+0 0 558 0 0 0 0 0 0 0 557 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 555 0 554 0 0 0
+553 0 0 0 0 0 0 0 552 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 551 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 550 0 549 548 0 0 547 546 0 545 0 0
+0 0 544 543 0 542 0 0 0 541 0 0 0 0 0 0 0 0 540 539 0 538 0 0 0 537 0 0 0 0 0 0
+0 536 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 535 534 0 533 0 0 0 532 0 0 0 0 0 0 0 531
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 530 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 529 528 0 527 0 0 0 526 0 0 0 0 0 0 0 525 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 524 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 523
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 522 0 521 520 0 0 519 518 0
+517 0 0 0 0 516 515 0 514 0 0 0 513 0 0 0 0 0 0 0 0 512 511 0 510 0 0 0 509 0 0
+0 0 0 0 0 508 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 507 506 0 505 0 0 0 504 0 0 0 0 0
+0 0 503 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 502 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 501 500 0 499 0 0 0 498 0 0 0 0 0 0 0 497 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 496 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 495 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 494 493 0 492 0 0 0 491
+0 0 0 0 0 0 0 490 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 489 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 488 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 487 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 486 0 0 0 485 0 484 483 0 0 0 0 482 0 481
+480 0 0 479 478 0 477 0 0 0 0 0 0 476 0 475 474 0 0 473 472 0 471 0 0 0 0 470
+469 0 468 0 0 0 467 0 0 0 0 0 0 0 0 0 0 466 0 465 464 0 0 463 462 0 461 0 0 0 0
+460 459 0 458 0 0 0 457 0 0 0 0 0 0 0 0 456 455 0 454 0 0 0 453 0 0 0 0 0 0 0
+452 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 451 0 450 449 0 0 448 447 0 446 0 0 0 0
+445 444 0 443 0 0 0 442 0 0 0 0 0 0 0 0 441 440 0 439 0 0 0 438 0 0 0 0 0 0 0
+437 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 436 435 0 434 0 0 0 433 0 0 0 0 0 0 0 432 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 431 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 430 0 429 428 0 0 427 426 0 425 0 0 0 0 424 423 0 422 0 0 0
+421 0 0 0 0 0 0 0 0 420 419 0 418 0 0 0 417 0 0 0 0 0 0 0 416 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 415 414 0 413 0 0 0 412 0 0 0 0 0 0 0 411 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 410 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 409
+408 0 407 0 0 0 406 0 0 0 0 0 0 0 405 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 404 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 403 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 402 0 401 400 0 0 399 398 0 397 0 0 0 0 396 395 0
+394 0 0 0 393 0 0 0 0 0 0 0 0 392 391 0 390 0 0 0 389 0 0 0 0 0 0 0 388 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 387 386 0 385 0 0 0 384 0 0 0 0 0 0 0 383 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 382 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 381 380 0 379 0 0 0 378 0 0 0 0 0 0 0 377 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 376
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 375 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 374 373 0 372 0 0 0 371 0 0 0 0 0 0 0 370 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 369 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 368 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 367 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 366 0 365 364 0 0 363 362 0 361 0 0 0 0 360 359 0 358 0 0 0 357 0 0 0 0 0
+0 0 0 356 355 0 354 0 0 0 353 0 0 0 0 0 0 0 352 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+351 350 0 349 0 0 0 348 0 0 0 0 0 0 0 347 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 346 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 345 344 0 343 0 0 0
+342 0 0 0 0 0 0 0 341 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 340 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 339 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 338 337 0 336 0 0 0 335 0 0 0 0 0 0 0 334 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 332 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 331 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 330 329 0 328 0 0 0
+327 0 0 0 0 0 0 0 326 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 325 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 324 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 323 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 }
+
+! This is a lookup table for all non-flush hands consisting of five unique
+! ranks (i.e. either Straights or High Card hands). A zero means that specific
+! combination is not possible with this type of hand.
+CONSTANT: unique5-table
+{ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1608 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 7462 0 0 0 0 0 0 0 7461 0 0 0 7460 0 7459 1607 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 7458 0 0 0 0 0 0 0 7457 0 0 0 7456 0 7455 7454 0 0 0 0 0 0
+0 0 7453 0 0 0 7452 0 7451 7450 0 0 0 0 7449 0 7448 7447 0 0 7446 7445 0 1606 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7444 0 0 0 0 0 0 0 7443 0 0 0 7442 0 7441
+7440 0 0 0 0 0 0 0 0 7439 0 0 0 7438 0 7437 7436 0 0 0 0 7435 0 7434 7433 0 0
+7432 7431 0 7430 0 0 0 0 0 0 0 0 0 0 7429 0 0 0 7428 0 7427 7426 0 0 0 0 7425 0
+7424 7423 0 0 7422 7421 0 7420 0 0 0 0 0 0 7419 0 7418 7417 0 0 7416 7415 0
+7414 0 0 0 0 7413 7412 0 7411 0 0 0 1605 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 7410 0 0 0 0 0 0 0 7409 0 0 0 7408 0 7407 7406 0 0 0 0 0 0 0 0 7405 0 0 0
+7404 0 7403 7402 0 0 0 0 7401 0 7400 7399 0 0 7398 7397 0 7396 0 0 0 0 0 0 0 0
+0 0 7395 0 0 0 7394 0 7393 7392 0 0 0 0 7391 0 7390 7389 0 0 7388 7387 0 7386 0
+0 0 0 0 0 7385 0 7384 7383 0 0 7382 7381 0 7380 0 0 0 0 7379 7378 0 7377 0 0 0
+7376 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7375 0 0 0 7374 0 7373 7372 0 0 0 0 7371 0
+7370 7369 0 0 7368 7367 0 7366 0 0 0 0 0 0 7365 0 7364 7363 0 0 7362 7361 0
+7360 0 0 0 0 7359 7358 0 7357 0 0 0 7356 0 0 0 0 0 0 0 0 0 0 7355 0 7354 7353 0
+0 7352 7351 0 7350 0 0 0 0 7349 7348 0 7347 0 0 0 7346 0 0 0 0 0 0 0 0 7345
+7344 0 7343 0 0 0 7342 0 0 0 0 0 0 0 1604 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 7341 0 0 0 0 0 0 0 7340 0 0 0 7339 0 7338 7337 0 0 0 0 0
+0 0 0 7336 0 0 0 7335 0 7334 7333 0 0 0 0 7332 0 7331 7330 0 0 7329 7328 0 7327
+0 0 0 0 0 0 0 0 0 0 7326 0 0 0 7325 0 7324 7323 0 0 0 0 7322 0 7321 7320 0 0
+7319 7318 0 7317 0 0 0 0 0 0 7316 0 7315 7314 0 0 7313 7312 0 7311 0 0 0 0 7310
+7309 0 7308 0 0 0 7307 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7306 0 0 0 7305 0 7304 7303
+0 0 0 0 7302 0 7301 7300 0 0 7299 7298 0 7297 0 0 0 0 0 0 7296 0 7295 7294 0 0
+7293 7292 0 7291 0 0 0 0 7290 7289 0 7288 0 0 0 7287 0 0 0 0 0 0 0 0 0 0 7286 0
+7285 7284 0 0 7283 7282 0 7281 0 0 0 0 7280 7279 0 7278 0 0 0 7277 0 0 0 0 0 0
+0 0 7276 7275 0 7274 0 0 0 7273 0 0 0 0 0 0 0 7272 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 7271 0 0 0 7270 0 7269 7268 0 0 0 0 7267 0 7266 7265 0 0 7264
+7263 0 7262 0 0 0 0 0 0 7261 0 7260 7259 0 0 7258 7257 0 7256 0 0 0 0 7255 7254
+0 7253 0 0 0 7252 0 0 0 0 0 0 0 0 0 0 7251 0 7250 7249 0 0 7248 7247 0 7246 0 0
+0 0 7245 7244 0 7243 0 0 0 7242 0 0 0 0 0 0 0 0 7241 7240 0 7239 0 0 0 7238 0 0
+0 0 0 0 0 7237 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7236 0 7235 7234 0 0 7233
+7232 0 7231 0 0 0 0 7230 7229 0 7228 0 0 0 7227 0 0 0 0 0 0 0 0 7226 7225 0
+7224 0 0 0 7223 0 0 0 0 0 0 0 7222 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7221 7220 0
+7219 0 0 0 7218 0 0 0 0 0 0 0 7217 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1603 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 7216 0 0 0 0 0 0 0 7215 0 0 0 7214 0 7213 7212 0 0 0 0 0 0 0 0 7211 0 0 0
+7210 0 7209 7208 0 0 0 0 7207 0 7206 7205 0 0 7204 7203 0 7202 0 0 0 0 0 0 0 0
+0 0 7201 0 0 0 7200 0 7199 7198 0 0 0 0 7197 0 7196 7195 0 0 7194 7193 0 7192 0
+0 0 0 0 0 7191 0 7190 7189 0 0 7188 7187 0 7186 0 0 0 0 7185 7184 0 7183 0 0 0
+7182 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7181 0 0 0 7180 0 7179 7178 0 0 0 0 7177 0
+7176 7175 0 0 7174 7173 0 7172 0 0 0 0 0 0 7171 0 7170 7169 0 0 7168 7167 0
+7166 0 0 0 0 7165 7164 0 7163 0 0 0 7162 0 0 0 0 0 0 0 0 0 0 7161 0 7160 7159 0
+0 7158 7157 0 7156 0 0 0 0 7155 7154 0 7153 0 0 0 7152 0 0 0 0 0 0 0 0 7151
+7150 0 7149 0 0 0 7148 0 0 0 0 0 0 0 7147 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 7146 0 0 0 7145 0 7144 7143 0 0 0 0 7142 0 7141 7140 0 0 7139 7138 0 7137
+0 0 0 0 0 0 7136 0 7135 7134 0 0 7133 7132 0 7131 0 0 0 0 7130 7129 0 7128 0 0
+0 7127 0 0 0 0 0 0 0 0 0 0 7126 0 7125 7124 0 0 7123 7122 0 7121 0 0 0 0 7120
+7119 0 7118 0 0 0 7117 0 0 0 0 0 0 0 0 7116 7115 0 7114 0 0 0 7113 0 0 0 0 0 0
+0 7112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7111 0 7110 7109 0 0 7108 7107 0
+7106 0 0 0 0 7105 7104 0 7103 0 0 0 7102 0 0 0 0 0 0 0 0 7101 7100 0 7099 0 0 0
+7098 0 0 0 0 0 0 0 7097 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7096 7095 0 7094 0 0 0
+7093 0 0 0 0 0 0 0 7092 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7091 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7090 0 0 0 7089 0 7088
+7087 0 0 0 0 7086 0 7085 7084 0 0 7083 7082 0 7081 0 0 0 0 0 0 7080 0 7079 7078
+0 0 7077 7076 0 7075 0 0 0 0 7074 7073 0 7072 0 0 0 7071 0 0 0 0 0 0 0 0 0 0
+7070 0 7069 7068 0 0 7067 7066 0 7065 0 0 0 0 7064 7063 0 7062 0 0 0 7061 0 0 0
+0 0 0 0 0 7060 7059 0 7058 0 0 0 7057 0 0 0 0 0 0 0 7056 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 7055 0 7054 7053 0 0 7052 7051 0 7050 0 0 0 0 7049 7048 0 7047 0
+0 0 7046 0 0 0 0 0 0 0 0 7045 7044 0 7043 0 0 0 7042 0 0 0 0 0 0 0 7041 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 7040 7039 0 7038 0 0 0 7037 0 0 0 0 0 0 0 7036 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 7035 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 7034 0 7033 7032 0 0 7031 7030 0 7029 0 0 0 0 7028 7027 0 7026
+0 0 0 7025 0 0 0 0 0 0 0 0 7024 7023 0 7022 0 0 0 7021 0 0 0 0 0 0 0 7020 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 7019 7018 0 7017 0 0 0 7016 0 0 0 0 0 0 0 7015 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 7014 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 7013 7012 0 7011 0 0 0 7010 0 0 0 0 0 0 0 7009 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 7008 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1602 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 7007 0 0 0 0 0 0 0 7006 0 0 0 7005 0 7004 7003 0 0 0 0 0 0 0 0 7002 0 0 0
+7001 0 7000 6999 0 0 0 0 6998 0 6997 6996 0 0 6995 6994 0 6993 0 0 0 0 0 0 0 0
+0 0 6992 0 0 0 6991 0 6990 6989 0 0 0 0 6988 0 6987 6986 0 0 6985 6984 0 6983 0
+0 0 0 0 0 6982 0 6981 6980 0 0 6979 6978 0 6977 0 0 0 0 6976 6975 0 6974 0 0 0
+6973 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6972 0 0 0 6971 0 6970 6969 0 0 0 0 6968 0
+6967 6966 0 0 6965 6964 0 6963 0 0 0 0 0 0 6962 0 6961 6960 0 0 6959 6958 0
+6957 0 0 0 0 6956 6955 0 6954 0 0 0 6953 0 0 0 0 0 0 0 0 0 0 6952 0 6951 6950 0
+0 6949 6948 0 6947 0 0 0 0 6946 6945 0 6944 0 0 0 6943 0 0 0 0 0 0 0 0 6942
+6941 0 6940 0 0 0 6939 0 0 0 0 0 0 0 6938 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 6937 0 0 0 6936 0 6935 6934 0 0 0 0 6933 0 6932 6931 0 0 6930 6929 0 6928
+0 0 0 0 0 0 6927 0 6926 6925 0 0 6924 6923 0 6922 0 0 0 0 6921 6920 0 6919 0 0
+0 6918 0 0 0 0 0 0 0 0 0 0 6917 0 6916 6915 0 0 6914 6913 0 6912 0 0 0 0 6911
+6910 0 6909 0 0 0 6908 0 0 0 0 0 0 0 0 6907 6906 0 6905 0 0 0 6904 0 0 0 0 0 0
+0 6903 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6902 0 6901 6900 0 0 6899 6898 0
+6897 0 0 0 0 6896 6895 0 6894 0 0 0 6893 0 0 0 0 0 0 0 0 6892 6891 0 6890 0 0 0
+6889 0 0 0 0 0 0 0 6888 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6887 6886 0 6885 0 0 0
+6884 0 0 0 0 0 0 0 6883 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6882 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6881 0 0 0 6880 0 6879
+6878 0 0 0 0 6877 0 6876 6875 0 0 6874 6873 0 6872 0 0 0 0 0 0 6871 0 6870 6869
+0 0 6868 6867 0 6866 0 0 0 0 6865 6864 0 6863 0 0 0 6862 0 0 0 0 0 0 0 0 0 0
+6861 0 6860 6859 0 0 6858 6857 0 6856 0 0 0 0 6855 6854 0 6853 0 0 0 6852 0 0 0
+0 0 0 0 0 6851 6850 0 6849 0 0 0 6848 0 0 0 0 0 0 0 6847 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 6846 0 6845 6844 0 0 6843 6842 0 6841 0 0 0 0 6840 6839 0 6838 0
+0 0 6837 0 0 0 0 0 0 0 0 6836 6835 0 6834 0 0 0 6833 0 0 0 0 0 0 0 6832 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6831 6830 0 6829 0 0 0 6828 0 0 0 0 0 0 0 6827 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 6826 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 6825 0 6824 6823 0 0 6822 6821 0 6820 0 0 0 0 6819 6818 0 6817
+0 0 0 6816 0 0 0 0 0 0 0 0 6815 6814 0 6813 0 0 0 6812 0 0 0 0 0 0 0 6811 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 6810 6809 0 6808 0 0 0 6807 0 0 0 0 0 0 0 6806 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6805 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 6804 6803 0 6802 0 0 0 6801 0 0 0 0 0 0 0 6800 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 6799 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6798 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6797 0 0 0
+6796 0 6795 6794 0 0 0 0 6793 0 6792 6791 0 0 6790 6789 0 6788 0 0 0 0 0 0 6787
+0 6786 6785 0 0 6784 6783 0 6782 0 0 0 0 6781 6780 0 6779 0 0 0 6778 0 0 0 0 0
+0 0 0 0 0 6777 0 6776 6775 0 0 6774 6773 0 6772 0 0 0 0 6771 6770 0 6769 0 0 0
+6768 0 0 0 0 0 0 0 0 6767 6766 0 6765 0 0 0 6764 0 0 0 0 0 0 0 6763 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6762 0 6761 6760 0 0 6759 6758 0 6757 0 0 0 0 6756 6755
+0 6754 0 0 0 6753 0 0 0 0 0 0 0 0 6752 6751 0 6750 0 0 0 6749 0 0 0 0 0 0 0
+6748 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6747 6746 0 6745 0 0 0 6744 0 0 0 0 0 0 0
+6743 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6742 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 6741 0 6740 6739 0 0 6738 6737 0 6736 0 0 0 0 6735
+6734 0 6733 0 0 0 6732 0 0 0 0 0 0 0 0 6731 6730 0 6729 0 0 0 6728 0 0 0 0 0 0
+0 6727 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6726 6725 0 6724 0 0 0 6723 0 0 0 0 0 0
+0 6722 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6721 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 6720 6719 0 6718 0 0 0 6717 0 0 0 0 0 0 0 6716 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6715 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 6714 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6713 0
+6712 6711 0 0 6710 6709 0 6708 0 0 0 0 6707 6706 0 6705 0 0 0 6704 0 0 0 0 0 0
+0 0 6703 6702 0 6701 0 0 0 6700 0 0 0 0 0 0 0 6699 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 6698 6697 0 6696 0 0 0 6695 0 0 0 0 0 0 0 6694 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 6693 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6692
+6691 0 6690 0 0 0 6689 0 0 0 0 0 0 0 6688 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6687 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6686 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6685 6684 0 6683 0 0 0 6682 0 0 0 0 0 0 0
+6681 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6680 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 6679 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1601
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1609 0 0 0 0 0 0 0 6678 0 0 0 6677
+0 6676 6675 0 0 0 0 0 0 0 0 6674 0 0 0 6673 0 6672 6671 0 0 0 0 6670 0 6669
+6668 0 0 6667 6666 0 6665 0 0 0 0 0 0 0 0 0 0 6664 0 0 0 6663 0 6662 6661 0 0 0
+0 6660 0 6659 6658 0 0 6657 6656 0 6655 0 0 0 0 0 0 6654 0 6653 6652 0 0 6651
+6650 0 6649 0 0 0 0 6648 6647 0 6646 0 0 0 6645 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6644 0 0 0 6643 0 6642 6641 0 0 0 0 6640 0 6639 6638 0 0 6637 6636 0 6635 0 0 0
+0 0 0 6634 0 6633 6632 0 0 6631 6630 0 6629 0 0 0 0 6628 6627 0 6626 0 0 0 6625
+0 0 0 0 0 0 0 0 0 0 6624 0 6623 6622 0 0 6621 6620 0 6619 0 0 0 0 6618 6617 0
+6616 0 0 0 6615 0 0 0 0 0 0 0 0 6614 6613 0 6612 0 0 0 6611 0 0 0 0 0 0 0 6610
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6609 0 0 0 6608 0 6607 6606 0 0 0 0
+6605 0 6604 6603 0 0 6602 6601 0 6600 0 0 0 0 0 0 6599 0 6598 6597 0 0 6596
+6595 0 6594 0 0 0 0 6593 6592 0 6591 0 0 0 6590 0 0 0 0 0 0 0 0 0 0 6589 0 6588
+6587 0 0 6586 6585 0 6584 0 0 0 0 6583 6582 0 6581 0 0 0 6580 0 0 0 0 0 0 0 0
+6579 6578 0 6577 0 0 0 6576 0 0 0 0 0 0 0 6575 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 6574 0 6573 6572 0 0 6571 6570 0 6569 0 0 0 0 6568 6567 0 6566 0 0 0 6565 0
+0 0 0 0 0 0 0 6564 6563 0 6562 0 0 0 6561 0 0 0 0 0 0 0 6560 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 6559 6558 0 6557 0 0 0 6556 0 0 0 0 0 0 0 6555 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 6554 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 6553 0 0 0 6552 0 6551 6550 0 0 0 0 6549 0 6548 6547 0 0 6546
+6545 0 6544 0 0 0 0 0 0 6543 0 6542 6541 0 0 6540 6539 0 6538 0 0 0 0 6537 6536
+0 6535 0 0 0 6534 0 0 0 0 0 0 0 0 0 0 6533 0 6532 6531 0 0 6530 6529 0 6528 0 0
+0 0 6527 6526 0 6525 0 0 0 6524 0 0 0 0 0 0 0 0 6523 6522 0 6521 0 0 0 6520 0 0
+0 0 0 0 0 6519 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6518 0 6517 6516 0 0 6515
+6514 0 6513 0 0 0 0 6512 6511 0 6510 0 0 0 6509 0 0 0 0 0 0 0 0 6508 6507 0
+6506 0 0 0 6505 0 0 0 0 0 0 0 6504 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6503 6502 0
+6501 0 0 0 6500 0 0 0 0 0 0 0 6499 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6498 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6497 0 6496 6495 0 0
+6494 6493 0 6492 0 0 0 0 6491 6490 0 6489 0 0 0 6488 0 0 0 0 0 0 0 0 6487 6486
+0 6485 0 0 0 6484 0 0 0 0 0 0 0 6483 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6482 6481
+0 6480 0 0 0 6479 0 0 0 0 0 0 0 6478 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6477 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6476 6475 0 6474 0 0 0
+6473 0 0 0 0 0 0 0 6472 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6471 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6470 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 6469 0 0 0 6468 0 6467 6466 0 0 0 0 6465 0 6464
+6463 0 0 6462 6461 0 6460 0 0 0 0 0 0 6459 0 6458 6457 0 0 6456 6455 0 6454 0 0
+0 0 6453 6452 0 6451 0 0 0 6450 0 0 0 0 0 0 0 0 0 0 6449 0 6448 6447 0 0 6446
+6445 0 6444 0 0 0 0 6443 6442 0 6441 0 0 0 6440 0 0 0 0 0 0 0 0 6439 6438 0
+6437 0 0 0 6436 0 0 0 0 0 0 0 6435 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6434 0
+6433 6432 0 0 6431 6430 0 6429 0 0 0 0 6428 6427 0 6426 0 0 0 6425 0 0 0 0 0 0
+0 0 6424 6423 0 6422 0 0 0 6421 0 0 0 0 0 0 0 6420 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 6419 6418 0 6417 0 0 0 6416 0 0 0 0 0 0 0 6415 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 6414 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6413
+0 6412 6411 0 0 6410 6409 0 6408 0 0 0 0 6407 6406 0 6405 0 0 0 6404 0 0 0 0 0
+0 0 0 6403 6402 0 6401 0 0 0 6400 0 0 0 0 0 0 0 6399 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 6398 6397 0 6396 0 0 0 6395 0 0 0 0 0 0 0 6394 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 6393 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6392
+6391 0 6390 0 0 0 6389 0 0 0 0 0 0 0 6388 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6387 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6386 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6385 0 6384 6383 0 0 6382 6381 0 6380 0 0
+0 0 6379 6378 0 6377 0 0 0 6376 0 0 0 0 0 0 0 0 6375 6374 0 6373 0 0 0 6372 0 0
+0 0 0 0 0 6371 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6370 6369 0 6368 0 0 0 6367 0 0
+0 0 0 0 0 6366 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6365 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6364 6363 0 6362 0 0 0 6361 0 0 0 0 0 0 0
+6360 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6359 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 6358 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6357 6356 0 6355 0 0 0 6354 0 0 0 0 0 0 0 6353 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6352 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6351 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6350 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6349 0
+0 0 6348 0 6347 6346 0 0 0 0 6345 0 6344 6343 0 0 6342 6341 0 6340 0 0 0 0 0 0
+6339 0 6338 6337 0 0 6336 6335 0 6334 0 0 0 0 6333 6332 0 6331 0 0 0 6330 0 0 0
+0 0 0 0 0 0 0 6329 0 6328 6327 0 0 6326 6325 0 6324 0 0 0 0 6323 6322 0 6321 0
+0 0 6320 0 0 0 0 0 0 0 0 6319 6318 0 6317 0 0 0 6316 0 0 0 0 0 0 0 6315 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 6314 0 6313 6312 0 0 6311 6310 0 6309 0 0 0 0 6308
+6307 0 6306 0 0 0 6305 0 0 0 0 0 0 0 0 6304 6303 0 6302 0 0 0 6301 0 0 0 0 0 0
+0 6300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6299 6298 0 6297 0 0 0 6296 0 0 0 0 0 0
+0 6295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6293 0 6292 6291 0 0 6290 6289 0 6288 0 0 0 0
+6287 6286 0 6285 0 0 0 6284 0 0 0 0 0 0 0 0 6283 6282 0 6281 0 0 0 6280 0 0 0 0
+0 0 0 6279 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6278 6277 0 6276 0 0 0 6275 0 0 0 0
+0 0 0 6274 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6273 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6272 6271 0 6270 0 0 0 6269 0 0 0 0 0 0 0 6268 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 6267 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 6266 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6265
+0 6264 6263 0 0 6262 6261 0 6260 0 0 0 0 6259 6258 0 6257 0 0 0 6256 0 0 0 0 0
+0 0 0 6255 6254 0 6253 0 0 0 6252 0 0 0 0 0 0 0 6251 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 6250 6249 0 6248 0 0 0 6247 0 0 0 0 0 0 0 6246 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 6245 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6244
+6243 0 6242 0 0 0 6241 0 0 0 0 0 0 0 6240 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6239 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6238 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6237 6236 0 6235 0 0 0 6234 0 0 0 0 0 0 0
+6233 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6232 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 6231 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6230
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 6229 0 6228 6227 0 0 6226 6225 0 6224 0 0 0 0 6223 6222 0
+6221 0 0 0 6220 0 0 0 0 0 0 0 0 6219 6218 0 6217 0 0 0 6216 0 0 0 0 0 0 0 6215
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6214 6213 0 6212 0 0 0 6211 0 0 0 0 0 0 0 6210
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6209 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 6208 6207 0 6206 0 0 0 6205 0 0 0 0 0 0 0 6204 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 6203 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 6202 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6201 6200 0 6199 0
+0 0 6198 0 0 0 0 0 0 0 6197 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6196 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6195 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 6194 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6193 6192 0 6191 0 0 0 6190 0 0 0 0 0 0
+0 6189 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6188 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6187 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6186 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 1600 }
+
+! This is a lookup table for the perfect hash adjustment values.
+CONSTANT: adjustments-table
+{ 0 5628 7017 1298 2918 2442 8070 6383 6383 7425 2442 5628 8044 7425 3155 6383
+2918 7452 1533 6849 5586 7452 7452 1533 2209 6029 2794 3509 7992 7733 7452 131
+6029 4491 1814 7452 6110 3155 7077 6675 532 1334 7555 5325 3056 1403 1403 3969
+4491 1403 7592 522 8070 1403 0 1905 3584 2918 922 3304 6675 0 7622 7017 3210
+2139 1403 5225 0 3969 7992 5743 5499 5499 5345 7452 522 305 3056 7017 7017 2139
+1338 3056 7452 1403 6799 3204 3290 4099 1814 2191 4099 5743 1570 1334 7363 1905
+0 6799 4400 1480 6029 1905 0 7525 2028 2794 131 7646 3155 4986 1858 2442 7992
+1607 3584 4986 706 6029 5345 7622 6322 5196 1905 6847 218 1785 0 4099 2981 6849
+4751 3950 7733 3056 5499 4055 6849 1533 131 5196 2918 3879 5325 2794 6029 0 0
+322 7452 6178 2918 2320 6675 3056 6675 1533 6029 1428 2280 2171 6788 7452 3325
+107 4262 311 5562 7857 6110 2139 4942 4600 1905 0 3083 5345 7452 6675 0 6112
+4099 7017 1338 6799 2918 1232 3584 522 6029 5325 1403 6759 6849 508 6675 2987
+7745 6870 896 7452 1232 4400 12 2981 3850 4491 6849 0 6675 747 4491 7525 6675
+7452 7992 6921 7323 6849 3056 1199 2139 6029 6029 190 4351 7891 4400 7134 1533
+1194 3950 6675 5345 6383 7622 131 1905 2883 6383 1533 5345 2794 4303 1403 0
+1338 2794 992 4871 6383 4099 2794 3889 6184 3304 1905 6383 3950 3056 522 1810
+3975 7622 7452 522 6799 5866 7084 7622 6528 2798 7452 1810 7907 642 5345 1905
+6849 6675 7745 2918 4751 3229 2139 6029 5207 6601 2139 7452 5890 1428 5628 7622
+2139 3146 2400 578 941 7672 1814 3210 1533 4491 12 2918 1900 7425 2794 2987
+3465 1377 3822 3969 3210 859 5499 6878 1377 3056 4027 8065 8065 5207 4400 4303
+3210 3210 0 6675 357 5628 5512 1905 3452 1403 7646 859 6788 3210 2139 378 5663
+7733 870 0 4491 4813 2110 578 2139 3056 4099 1905 1298 4672 2191 3950 5499 3969
+4974 6323 6029 7414 6383 0 4974 3210 795 4099 131 5345 5345 6576 1810 1621 4400
+2918 1905 2442 2679 6322 7452 2110 1403 6383 2653 5132 6856 7841 2794 6110 2028
+6675 7425 6999 7441 6029 183 6675 4400 859 1403 2794 5985 5345 1533 322 4400
+1227 5890 4474 4491 3574 8166 6849 7086 5345 5345 5459 3584 6675 3969 7579 8044
+2295 2577 1480 5743 3304 5499 330 4303 6863 3822 4600 4751 5628 3822 2918 6675
+2400 6663 1403 6849 6029 3145 6110 3210 747 3229 3056 2918 7733 330 4055 7322
+5628 2987 3056 1905 2903 669 5325 2845 4099 5225 6283 4099 5000 642 4055 5345
+8034 2918 1041 5769 7051 1538 2918 3366 608 4303 3921 0 2918 1905 218 6687 5963
+859 3083 2987 896 5056 1905 2918 4415 7966 7646 2883 5628 7017 8029 6528 4474
+6322 5562 6669 4610 7006 }
+
+! This is a lookup table for the perfect hash final hand values.
+CONSTANT: values-table
+{ 148 2934 166 5107 4628 166 166 166 166 3033 166 4692 166 5571 2225 166 5340
+3423 166 3191 1752 166 5212 166 166 3520 166 166 166 1867 166 3313 166 3461 166
+166 3174 1737 5010 5008 166 4344 2868 3877 166 4089 166 5041 4748 4073 4066
+5298 3502 1812 166 5309 166 233 3493 166 166 3728 5236 4252 4010 2149 166 164
+4580 3039 4804 3874 166 6170 2812 166 4334 166 166 166 166 166 166 1862 224
+2131 6081 166 2710 166 166 166 4765 166 1964 5060 166 1897 166 3987 166 166
+5566 2021 166 45 166 166 3283 3932 166 166 3519 166 166 291 166 166 5132 2800
+166 166 166 5531 4054 166 3509 166 166 4908 3028 1756 1910 4671 2729 5224 166
+121 3327 3317 166 181 2371 5541 166 1787 2666 5134 5698 166 5480 3870 166 3823
+166 3165 5343 5123 5089 166 2422 3724 166 2735 1953 5724 4444 4871 166 166 5001
+5512 3133 5171 166 2216 166 4877 4542 166 166 166 5270 166 166 166 1922 69 3547
+166 166 166 166 166 231 4547 5155 3357 3464 166 72 3332 166 4392 5971 3896 4451
+3173 2569 166 4466 2518 1698 2850 5349 166 166 4457 5062 166 2202 1650 2191 166
+1950 2583 166 5293 2032 5893 166 3994 5392 3878 96 166 166 3195 166 4001 1900
+2513 6027 166 166 166 166 5407 166 166 2332 5125 5891 3096 3172 166 166 3065
+166 166 4535 166 166 166 4553 3131 3693 166 2255 2613 166 166 166 166 2866 166
+166 166 2940 5333 3199 166 2628 4312 166 166 1794 4681 2058 3606 166 166 3542
+2166 4696 2520 166 4739 166 2563 166 166 3681 166 166 166 4127 1967 2972 166
+5227 166 166 5551 4255 56 166 5553 3219 4367 166 3218 4749 2886 3695 3711 2228
+166 166 166 2268 5054 3749 4825 166 4933 4992 4530 166 4892 3400 166 197 166
+6078 166 166 3971 166 166 5357 1852 3377 166 5196 3740 5320 166 166 3099 166
+4562 6061 3294 166 166 166 166 3266 3627 2567 166 228 2773 166 166 53 1833 2401
+124 166 4272 3922 5959 2903 3923 166 6155 166 166 166 166 216 166 5247 166 5591
+166 166 82 87 4526 166 166 5439 166 4935 166 3187 1869 166 1764 5500 6023 3356
+166 3350 2457 2455 166 1637 166 3342 166 166 3355 5154 166 276 166 166 166 3371
+5969 166 1665 166 166 166 166 166 166 166 4092 1712 3122 5086 166 166 4906 166
+2591 166 166 166 1894 2997 166 4476 4384 166 4747 4109 2655 166 5978 1636 4898
+166 166 166 166 166 166 166 5207 166 166 3712 3876 91 5876 3786 5998 166 166
+166 4391 166 166 2832 2220 4435 166 166 5796 3156 6112 166 1643 1821 3129 166
+4200 166 5857 166 166 2351 5902 1855 5043 166 3167 5191 3996 5718 4876 3071
+2965 5735 5930 6149 2345 3297 3822 166 166 307 6019 1859 2981 4914 3320 6165
+2328 140 2372 308 166 2280 5081 166 3275 166 159 2399 2327 5489 4690 6059 4492
+4269 6058 166 19 166 3323 5708 128 4812 2949 166 166 2890 2630 5237 166 256
+3673 4621 5380 166 3353 166 1651 2573 1635 4011 3429 3370 3720 166 166 6108
+3848 5104 2851 1998 166 166 5106 20 166 2633 166 166 166 166 5662 125 3651 1731
+4702 166 3197 166 2947 3046 4196 2185 6100 166 2602 2908 2487 166 5232 166 4028
+5919 166 2680 3608 3252 166 4899 166 166 166 166 2529 166 166 166 166 166 2534
+166 2299 4076 166 3643 166 3921 166 166 166 1939 2124 1829 2436 3892 166 3481
+271 5307 1697 166 166 5098 2906 5545 166 5980 3203 166 1903 4626 4674 6118 6097
+5926 4136 1677 3232 4720 166 166 166 229 2012 3620 166 3798 166 166 2609 3489
+3809 166 166 166 166 166 166 166 5826 166 166 166 4903 166 166 166 166 6168 166
+5052 5044 5644 2375 2677 4012 3062 5831 4752 166 4125 2610 2062 3238 292 2533
+5872 51 166 1947 4225 166 2288 4845 166 5788 166 5717 166 166 5549 5619 166
+4165 166 2721 2311 5501 4416 4383 166 166 3068 5499 5936 166 4204 4766 4688
+1870 5220 166 166 166 166 237 2523 6039 3061 2793 3998 166 2545 2309 3144 3679
+3969 166 166 166 4379 3574 205 2808 5822 166 166 2188 4823 4990 5561 5711 166
+5627 6034 5253 3783 5047 4405 166 59 1755 3178 318 166 4710 2933 3409 6062 2821
+166 6099 166 4178 166 166 4122 36 4779 166 166 4323 3073 5410 2101 166 166 44
+5690 166 3265 166 5222 5909 1838 166 4755 2215 166 4082 166 166 3210 5140 3124
+5238 166 5913 2321 166 2416 5976 3918 5078 4218 5703 4897 6011 5685 2214 166
+166 6180 5175 1715 166 166 3760 4497 1808 4826 166 2540 166 166 5513 4971 5915
+166 166 2525 166 4480 42 232 2412 2797 3229 5263 2852 5543 2126 3562 166 2872
+4695 5985 5136 2714 4262 5473 166 4160 4347 166 166 166 166 5271 166 166 5108
+166 166 166 166 5437 4875 3963 4362 5820 5559 4890 4728 166 166 2692 166 4870
+3591 5472 166 2690 166 5854 3817 166 280 166 166 113 4128 3396 166 4264 5058
+2283 166 2281 4916 5671 166 2708 166 166 4589 166 166 4689 166 1686 166 166 166
+166 166 1774 166 166 166 5651 3777 2234 166 3864 18 3589 4592 4777 166 166 5254
+4245 166 166 166 4368 5172 3522 166 4306 153 5230 166 5598 5420 311 2414 4159
+2985 5137 166 2179 1801 166 4595 2083 2020 166 3602 2170 4259 3048 166 166 4193
+2350 166 166 2702 166 4521 166 166 2496 166 4593 2006 166 166 2292 4135 166
+6069 4623 166 166 4827 3995 4291 3243 166 166 166 5622 166 3539 166 166 4915
+4373 2479 3775 6008 5838 4321 1612 5530 166 3773 4267 4086 3081 2261 166 166
+4785 4641 5292 166 4820 5612 5556 166 166 166 4396 6084 3414 166 3331 2380 5921
+4315 2340 166 5511 166 4713 3754 2912 2553 166 3468 5388 166 1932 3540 5834 166
+166 3186 5258 166 4107 166 166 166 166 166 166 166 166 2108 12 2368 2789 166
+166 4148 1878 166 166 2324 4179 2945 2531 166 166 166 4485 3765 2308 166 2754
+166 6102 166 1921 260 2241 166 2592 166 166 166 4964 166 3055 5261 4943 2916
+166 201 5728 166 5759 4314 4730 6024 166 4926 4762 1834 2055 166 40 166 5416
+166 3722 2360 1928 166 4889 4590 5550 3498 166 6003 2029 4106 4346 3758 166
+2753 103 1891 5067 166 3398 2079 5784 3074 3787 166 166 3936 166 5766 166 4847
+3928 5119 166 5181 4602 2605 5712 4523 166 166 4717 166 2227 2181 166 4678 166
+166 4901 166 4980 166 166 166 166 5806 2894 5631 4995 2608 166 166 166 3917 166
+3417 166 2795 1655 3189 3364 166 4839 3510 4212 5641 6091 138 166 166 3343 4620
+2722 4566 166 3518 3424 166 166 1653 166 5057 166 5375 4833 166 4273 4348 166
+166 166 4912 166 3662 166 4281 166 5169 166 5883 2737 2572 4685 4068 166 4214
+166 166 2409 166 166 4571 166 5624 5722 5949 166 3675 166 166 5109 3428 166 166
+5446 166 3290 166 3309 166 166 4776 166 166 166 166 166 166 5617 2860 166 166
+166 166 3629 1741 166 166 183 4973 3047 2854 75 2035 3652 2159 166 4150 6037
+3225 4519 1902 2678 2413 1961 166 166 166 166 4972 1847 166 5636 4017 166 3345
+166 4520 166 2861 166 3092 6060 157 2542 2298 4496 166 2607 6110 5707 2314 166
+166 273 166 5952 166 4957 322 6065 2272 6140 2438 3458 3287 166 166 166 166
+2684 288 3354 166 166 3983 1702 166 166 166 2393 2435 4202 3308 5805 5085 166
+166 1938 166 166 2171 5892 2337 166 4648 3116 2486 4363 3567 166 166 2822 2041
+166 4703 3956 5192 166 3975 5720 3647 2134 5932 166 166 5160 263 166 166 166
+4549 166 166 1701 3086 166 166 4737 166 2252 166 170 166 166 166 2301 5478 166
+166 5979 3007 166 166 166 4104 166 2469 2700 166 4998 3376 166 1840 166 166
+4470 166 5235 3930 166 166 166 6031 166 166 166 3827 4700 166 166 166 166 166
+166 4103 3976 166 166 166 166 5027 4322 5130 166 4741 2132 4118 3080 4137 166
+6179 166 166 166 166 166 6120 4188 166 2251 166 3253 166 4887 166 4293 5241 166
+166 166 166 166 166 5076 166 166 4177 166 221 166 2757 5377 166 43 166 166 3180
+5540 166 213 4541 166 166 166 166 166 1641 166 4578 4639 166 166 1683 2139 1689
+5249 5773 5226 166 2820 166 5516 5045 166 4896 5657 5189 166 5770 2725 5148 166
+166 166 2929 166 3479 166 166 4564 3752 4305 4232 166 5906 1779 166 2709 4941
+4342 166 4882 166 4277 2322 166 4879 1610 3038 166 3762 2054 5652 166 4524 3820
+4806 166 166 104 3416 4869 4243 4854 166 4114 166 2121 166 3463 3556 166 4795
+166 2118 3920 166 166 4667 5046 166 166 2088 4360 5787 2198 4233 5552 3970 3523
+2037 5791 166 166 4299 2336 166 166 166 4173 4588 3626 5187 166 3363 4611 294
+4962 5243 2719 6022 4976 3559 166 2662 5779 6151 166 3527 166 5404 6132 1839
+166 3090 166 2253 166 5441 5518 6049 166 166 6136 3026 3474 5960 166 3937 4105
+166 2348 2039 4738 166 5233 3882 3840 166 278 190 166 5751 4313 166 3855 166
+166 6171 166 166 5381 3941 166 166 166 166 3334 166 2038 6088 166 1918 5037
+2325 2378 4894 3514 3715 5168 166 166 4083 2873 166 166 166 2693 166 3543 166
+2577 3013 166 166 4594 2622 166 166 166 3401 166 166 5447 5328 5547 6133 2335
+3739 166 166 166 166 5614 3492 3610 3466 166 5336 4354 166 4662 166 166 4283
+166 166 303 5904 166 2717 166 166 2276 5564 2386 5661 2040 166 1630 4652 166
+4840 166 110 5329 3979 5734 2550 166 166 6007 5999 2978 4771 5360 166 4023 166
+166 5920 4065 166 3880 166 5422 1813 166 6166 73 166 166 3669 5762 5077 166
+2953 85 166 3517 166 116 166 2738 3710 166 1634 166 166 166 2290 3001 166 166
+3037 2400 3410 166 1791 4231 166 3546 5009 5299 2807 166 166 1675 1619 2374
+3093 5302 3278 2330 5301 2343 2307 3274 5017 2265 3700 2465 166 139 4292 166
+5056 3952 166 4528 2388 1886 166 166 3016 3698 5881 166 2379 3223 166 166 3847
+2407 5493 3183 3307 166 265 166 2421 6161 2057 5363 3863 2474 166 166 5427 166
+2140 2955 166 3070 4237 5018 5988 5570 275 4862 2357 166 195 166 2593 6047 166
+2878 166 166 2781 3004 4180 166 5593 166 5973 2544 5064 166 4324 4701 166 3084
+166 166 5372 4725 166 5650 166 166 2786 166 3781 3583 3682 1850 4420 3296 5173
+4461 166 166 166 2984 166 93 166 166 4336 5943 2922 3300 166 4843 166 166 166
+166 2094 166 2939 166 4656 166 5146 166 166 166 166 2104 3977 4660 5312 166
+1865 166 5487 5558 3380 166 1957 3162 3281 166 3588 3268 2099 166 166 2319 4913
+4187 5503 5782 150 166 52 5450 166 166 166 2941 5877 166 4031 5393 166 3931
+4166 3135 3445 166 5053 5430 4836 166 5315 3389 4636 166 166 3441 166 166 3767
+2961 166 4761 4604 3179 166 166 4751 2148 2015 166 123 5013 166 2936 166 2063
+166 5823 166 5096 166 166 4198 166 166 166 3845 166 166 238 166 2703 3541 166
+4813 166 4477 2349 4197 5996 3324 4789 3063 166 166 5504 5273 2805 13 166 5601
+5402 4119 5206 166 166 4251 3704 4176 1963 2882 166 202 3125 3318 112 166 3362
+4835 3420 3974 5099 166 4433 166 166 166 1766 2663 166 166 4683 166 166 5485 47
+5101 5341 5765 3390 1648 4341 3945 6045 1645 166 5578 2594 166 166 3772 166 166
+3196 3603 166 5399 166 5075 166 5911 4632 4781 5313 270 166 2346 166 166 166
+1986 166 166 4958 166 166 166 4048 166 3076 166 166 4891 166 166 57 166 220 166
+166 166 4117 166 166 166 166 5194 2658 166 166 2942 6071 4182 166 2976 5816 166
+166 166 166 3985 4211 2514 166 166 166 2504 3446 1711 166 166 2107 5190 166 34
+166 3912 5382 3003 166 166 166 2999 2404 4734 4455 2087 166 2405 156 166 2830
+3303 296 3295 2067 4268 166 166 5642 166 166 1901 166 5133 166 166 166 166 3176
+2973 4677 166 166 6164 3000 2396 2734 5697 5989 166 2823 5265 5852 166 166 2623
+2625 2287 4844 1758 166 166 166 166 166 6073 166 5379 2389 5279 2444 5515 166
+4038 166 4948 5640 166 166 3572 4258 166 166 166 5204 166 4603 5797 166 166 166
+1725 4600 166 166 5498 166 4152 166 172 4758 166 2598 2489 2076 4366 2568 166
+4352 3782 166 166 3059 3946 5138 5727 4484 5694 166 3796 166 166 166 166 5334
+1778 2245 166 4517 4419 2250 182 5856 166 2835 4495 1858 2033 6014 6086 3211
+166 166 154 2145 166 129 3661 2661 5860 6143 2640 3890 6160 166 166 2747 166
+166 2291 282 2476 166 166 3825 166 1925 166 4489 166 166 166 4034 166 166 166
+166 166 166 122 4708 4919 2373 2453 5419 5954 297 5290 166 1978 166 4932 3501
+166 3085 3386 166 5405 4512 166 3209 5740 4020 5495 5815 314 166 3190 4824 166
+166 3448 207 1623 6096 5878 166 1836 166 166 2728 166 5278 3419 3012 5618 5266
+3078 166 166 2244 166 4569 6068 166 3336 166 5677 6052 5079 166 5453 5245 5799
+166 1982 166 5958 4619 5821 166 5285 284 1631 5710 6070 5365 2189 3242 166 2752
+5483 5297 6150 5522 166 1815 166 166 166 5801 166 166 5398 166 166 166 2967
+2515 3169 166 166 2562 166 1617 2069 166 166 6154 166 3721 166 5327 166 166 166
+5592 166 166 2286 1716 3903 166 2395 286 3587 6146 3286 4186 5882 5894 5737
+6032 5879 2761 4829 3788 166 166 3233 5356 5693 166 2429 2449 141 3444 5186 166
+166 3477 4080 4584 166 166 3670 1851 3824 4337 3886 2792 166 5867 166 166 3557
+3147 166 166 2200 166 2505 166 4310 4865 5656 5992 5672 166 5199 135 3023 2994
+4472 166 166 166 2019 4319 3472 166 166 166 29 206 3944 3027 5804 4731 5449 166
+2825 3310 166 6172 5202 166 2516 3644 4557 166 166 166 166 2671 4427 3432 3276
+5584 5536 4645 3202 166 2612 166 4249 2425 3259 4622 166 2411 4303 4206 166 166
+166 3734 6063 118 166 166 3641 166 166 166 4937 1871 3421 2208 166 166 166 166
+4881 166 166 166 166 3298 166 61 166 166 166 3293 6145 71 3619 166 166 3383
+1624 320 2187 4113 166 166 166 166 166 5080 2344 5625 2358 1621 4230 5579 5359
+295 4248 5267 3883 6124 187 5112 2122 166 166 166 5142 6004 166 5322 6175 3639
+3182 4425 166 175 166 166 166 5778 3939 3484 166 166 5832 5248 5935 4467 5858
+166 5038 166 166 3102 166 4880 166 166 166 166 3418 1666 5338 3680 5291 4441
+3385 166 5733 4503 2774 166 2631 4153 166 2000 166 166 5345 166 166 4298 1804
+4707 166 1613 1952 2111 166 166 166 166 166 2897 166 166 4044 166 166 166 166
+2863 5475 166 166 166 1704 166 3609 2782 2018 166 5361 166 3694 3733 166 2785
+1969 166 166 2834 1868 3779 1877 60 166 4143 3902 166 4361 3188 2498 6009 166
+115 166 3138 166 4575 6080 133 2030 166 166 166 2306 2136 3043 3447 2142 166
+3799 1646 5269 3640 166 2674 5502 166 5467 166 5069 166 166 4654 4581 5274 5036
+4364 166 3115 166 2128 4544 5433 2086 2584 4413 166 166 5385 166 234 166 1625
+166 166 166 5139 2511 4974 2766 166 166 166 2095 3990 217 166 2988 4061 166 209
+4883 166 166 166 166 166 4326 166 5465 2859 166 2887 166 2231 166 1658 166 2246
+166 1844 166 166 3087 2871 3872 1660 48 166 166 3622 166 1709 166 166 6177 6173
+166 3569 166 166 166 241 3660 3631 166 166 5319 5141 174 166 166 4412 166 5145
+166 1919 166 5276 166 2385 166 1618 166 166 2501 166 166 1734 5966 3145 166
+1690 4025 1664 4559 2433 2392 3552 4006 1896 166 166 2546 4450 5396 4221 4046
+166 166 2642 166 4448 166 2784 3480 4807 166 166 3534 166 166 5272 166 166 2831
+4263 166 166 166 166 4414 5628 3486 166 3748 166 4598 3719 3598 3611 166 4792
+5059 4110 166 2656 166 166 84 5429 166 166 166 281 1955 166 166 166 3616 4997
+166 166 166 166 3230 166 166 166 166 166 166 77 166 166 166 1800 166 4236 166
+166 166 166 166 5757 2530 1662 166 4607 1659 166 1685 3341 166 1699 4058 3407
+1854 4417 3034 166 166 166 166 5568 166 3206 166 5529 166 166 166 2116 3487 144
+166 166 166 5523 5373 5321 166 6064 2921 166 1696 2473 166 166 3716 5689 166
+4608 3879 166 166 166 2156 166 4358 2446 166 3958 166 5520 4340 4848 166 3285
+166 2665 166 3459 1905 5115 68 5730 166 3127 5029 4370 166 3753 166 3674 6025
+4490 166 4183 166 94 166 166 4051 3766 3140 4907 3857 166 166 4596 166 3888
+3040 2507 5643 166 166 4311 2618 5582 166 166 3678 166 1988 166 166 4464 166
+166 166 166 4278 3677 2173 5256 166 166 5162 166 5178 1644 5094 166 2557 5506
+166 166 166 4927 5348 1797 166 166 39 166 3866 3655 236 5403 2175 3361 166 1976
+5993 226 166 4643 166 5339 4098 2653 4969 166 3346 4984 4635 166 166 166 166
+4981 188 166 166 28 4088 166 166 166 25 3663 2696 166 4679 5114 5802 166 166
+166 166 166 3810 5749 166 1673 4276 166 3756 4184 166 5630 166 166 166 4531 212
+5663 166 166 2746 166 5386 3618 3594 1887 166 166 5443 166 1726 4094 5065 4756
+166 166 5308 5225 2081 166 166 3064 166 166 1981 3637 4355 1626 166 166 4686
+166 5793 180 5066 2938 3819 4904 3601 166 166 2495 5025 5768 2621 4650 3041 166
+5897 3633 166 166 4375 166 5714 1667 3273 3950 1668 166 5855 166 2364 166 1881
+166 2646 5460 166 2770 4951 5414 166 4442 2113 5726 298 5934 2053 166 166 4053
+166 166 4514 4697 166 166 5198 2707 166 5605 166 166 5218 2596 166 2110 166
+1806 2160 166 166 2212 166 3636 166 166 4377 4021 3707 4502 166 4195 166 166
+166 4108 3725 3676 166 2084 166 166 166 166 4216 166 166 6156 166 2896 166 166
+166 166 166 166 3826 2870 3793 166 166 5927 166 2759 166 4613 2297 5638 166
+2842 5031 4793 5184 166 166 2008 166 257 2881 117 6051 3044 4079 2833 166 6117
+166 3236 5469 166 166 2874 6076 166 1799 80 41 166 1864 166 5709 1611 5026 5176
+168 3269 4081 166 166 1970 4550 166 4250 4101 4565 5950 5845 97 4064 166 5394
+4374 4343 166 166 4658 3248 166 208 1735 4047 2843 166 166 166 166 2794 166 166
+5844 166 166 3094 2177 5436 3646 166 3564 4682 166 5948 5835 162 2059 5151 2034
+1926 5941 5903 5177 166 166 166 4801 3439 1780 166 166 3280 3434 166 166 4498
+5565 4043 166 4432 4722 3959 166 3746 166 166 177 166 166 2748 166 4483 166 166
+4144 166 166 166 166 2066 2915 166 2049 2130 4684 166 49 3506 5391 166 2590
+6103 1714 2410 3053 3837 4301 166 3255 2644 166 166 4014 166 2475 4788 2876 166
+166 166 166 166 166 4140 166 166 321 166 1966 166 166 2855 3111 3800 166 4446
+2551 166 166 166 2824 166 166 166 2164 3010 2226 166 4857 166 2582 5118 4582
+5917 166 166 3338 3482 3328 166 4817 166 5371 3830 166 3009 1633 3329 4052 166
+3701 4983 4500 4487 4878 166 166 5482 3544 166 3057 2026 4398 2847 3532 3262
+3399 166 166 166 4478 4167 166 3411 2599 5362 166 2711 166 166 166 166 3452
+2522 5586 5548 3279 2538 166 166 166 4161 166 2123 166 166 2660 166 166 1706
+166 15 3537 5051 5869 166 3025 166 4447 3744 120 166 166 166 204 2810 166 5124
+2376 5306 166 166 4493 166 166 166 5289 6046 166 2762 2541 1857 2467 5163 166
+166 166 166 5830 166 2172 3359 166 2928 166 166 166 6129 166 5445 166 166 5924
+6144 166 102 166 166 1678 166 4491 5705 166 1753 166 3873 5725 4145 1909 166
+2155 166 166 1848 3315 1874 166 4945 2524 166 3263 2362 1785 166 166 166 152
+2102 5723 5131 5754 4032 4029 166 4295 3391 166 166 166 5282 1747 3159 2235
+5583 1786 3630 6111 2974 4797 3623 166 2071 4929 166 2603 3964 3378 166 166
+2654 151 3940 4527 4518 166 2430 1884 3812 166 2867 166 166 166 2756 5418 166
+2354 4606 166 2153 166 4855 166 166 1720 166 3213 3926 166 5158 4349 166 4828
+166 166 2031 166 2300 166 166 166 2211 4954 3121 4754 2485 166 166 166 3593 166
+2718 5317 2765 5120 166 2527 166 1994 5947 166 166 166 6085 2302 100 79 2982
+3705 2180 2043 166 1872 1671 166 3729 166 4944 3665 2217 2119 166 5615 166 1620
+166 166 166 166 35 3913 2760 166 3688 3672 4042 166 166 5117 4227 166 4445 2458
+3803 4554 4988 166 166 3141 3491 166 166 166 166 5095 4668 5567 166 166 2885
+1790 2996 166 166 166 166 3737 166 2470 166 166 4339 166 166 166 4920 166 166
+3697 5471 166 166 3538 4558 3467 5262 5609 3858 166 166 5007 2780 2791 2236
+5668 3134 166 166 5776 3470 3291 166 2532 166 166 166 3805 264 166 3227 166 166
+166 2334 166 5087 101 166 3634 58 2813 166 166 166 3222 4704 4488 4508 5459
+2117 5873 166 1828 166 166 166 166 166 2105 166 5613 5761 2920 3098 166 166
+3277 166 166 166 166 83 166 166 166 3967 166 5574 166 4985 30 3426 166 179 3014
+4015 246 2556 4449 3723 5611 3436 166 4240 3642 166 4536 2048 5810 166 1971 166
+5557 5323 5022 191 5492 166 4837 4426 2537 2271 3177 5674 166 2796 1995 166
+3906 166 4403 3862 4716 2406 3948 4670 4309 166 2575 5358 2951 166 3666 3612
+5577 4579 4743 166 6072 6036 4563 2586 166 5836 166 166 5752 166 3563 166 2909
+3251 92 166 4711 4149 166 166 3052 5122 2904 2635 1990 166 166 166 166 166 166
+166 166 4213 166 3103 3142 2683 6105 2209 3175 4215 166 166 166 166 166 166 166
+5303 4075 5374 166 4174 4154 1895 4538 2764 166 5817 6113 4033 166 6090 166
+2990 166 3164 166 166 166 247 166 6083 3412 166 5738 166 3599 166 1904 2162
+2547 3960 166 166 3154 55 166 5991 4921 2879 166 166 5347 166 166 166 2712 4787
+166 1908 166 166 166 3184 166 166 166 4572 3846 3657 166 166 5481 166 166 3397
+1856 4978 166 3900 3570 3802 166 166 2075 4408 166 6079 2313 166 166 5756 166
+166 2070 166 166 3137 166 166 3686 166 166 166 166 67 5019 166 1742 166 5354
+166 5149 166 2931 4946 6006 166 166 2865 4902 3029 1722 3449 166 1987 166 62
+5626 166 166 166 2670 1657 5599 3056 166 3791 5020 166 1979 4437 1899 166 166
+196 2636 166 143 3475 4317 2512 2415 5033 5024 2112 2864 3551 166 1688 33 4585
+3648 4399 166 166 166 166 166 1824 166 166 166 166 166 166 4513 166 2478 4407
+166 166 2492 4130 4318 2980 5746 166 2606 4063 4123 166 255 166 166 4680 166
+3586 5975 3935 166 5528 166 3158 166 166 2614 5035 166 3488 3214 166 166 166
+5413 3713 166 5875 4329 5250 166 166 3741 166 54 1885 3839 166 4924 166 166 166
+4158 166 166 2152 1661 166 166 4327 166 3933 166 5666 166 166 2580 166 3404
+4111 2862 4438 166 166 4072 166 166 3938 2958 4302 166 3851 166 268 166 166
+1975 222 3204 3438 4616 166 4275 3101 2648 3989 5215 166 4229 166 5440 166 5093
+2639 166 166 4439 166 2316 4239 166 166 166 166 166 1817 4486 166 3272 166 166
+4085 2078 2902 166 166 166 4381 1853 3054 166 166 5005 2669 166 2856 2706 166
+166 166 4185 166 1748 166 166 166 5771 166 166 3915 166 166 2205 6122 166 166
+1632 5400 166 2477 4740 166 166 166 1802 166 2472 3953 166 1849 2604 3780 2560
+4786 2566 3576 166 4768 166 1951 251 5068 166 166 166 2619 166 166 166 5432 166
+166 5260 5758 3908 166 4141 166 5777 166 166 166 166 166 3961 5143 166 3889
+3747 3743 166 2818 166 166 166 3867 166 166 3742 4763 2948 5533 166 3966 3555
+3843 3503 6005 166 4687 2790 4479 5828 3769 5688 166 166 166 166 3109 166 166
+166 166 4574 81 166 166 4576 3369 166 166 166 4207 166 5072 2210 166 184 166
+4673 166 166 166 166 166 166 1628 3590 1916 4784 4970 166 1832 166 166 3584
+3384 166 166 2880 1783 166 166 166 166 6115 6121 2157 5428 5859 4861 5635 4331
+5839 4223 313 166 166 6152 2168 166 4112 6089 6012 166 5294 3207 166 166 4884
+166 4655 166 166 166 1743 166 4077 166 4631 166 166 2957 1945 4936 166 166 5389
+166 166 5955 166 166 1639 2207 4129 166 3582 5560 6147 3088 166 166 4529 5259
+3118 166 3106 2853 166 1845 5660 166 3325 3973 2461 2163 166 3083 4190 166 166
+5505 166 166 3226 5507 109 6141 3991 166 4939 166 166 5889 3986 166 3664 4353
+2056 166 5071 166 166 4376 166 1958 2028 166 166 1793 166 5252 3536 166 166
+3525 3580 166 166 166 1782 5174 2011 1826 3352 3231 166 166 4986 2068 2801 166
+2500 166 5061 166 2263 2632 1993 166 2715 4424 166 166 6042 4661 166 5074 5479
+4822 166 166 166 166 5600 5853 166 1907 166 166 166 3808 166 5997 5032 4605 166
+1732 166 166 166 3015 5454 166 166 166 3806 5444 2238 1946 166 166 3221 4922
+166 6092 166 166 4007 166 3425 4282 2571 166 1749 166 166 38 4744 4900 4257 214
+5687 166 2490 2979 2924 166 4714 219 5344 3836 3302 78 1984 2986 2960 166 2869
+3507 3335 4967 2892 2723 4849 5070 166 166 4629 3815 166 4453 4760 166 3224 130
+166 166 166 166 166 3408 2494 2691 166 4325 2932 5165 5573 166 4769 166 5411
+5637 2050 166 166 2305 166 166 4834 24 4693 3554 2491 1738 166 166 166 23 2758
+3072 2564 4800 5537 3545 4133 166 166 166 5982 166 203 166 166 290 185 166 3774
+1929 3379 166 166 166 166 3002 166 3738 166 166 3344 4942 5353 2777 2839 4712
+1830 2664 166 5884 3516 166 5494 4169 2391 3319 166 166 5918 2597 166 4821 2787
+5719 166 166 166 1687 6148 3257 254 166 5180 6153 5964 306 166 6123 166 5208
+166 3163 5938 1736 166 2502 4910 166 166 2549 166 2900 3632 3270 166 2082 5953
+166 107 5750 166 166 166 5527 1751 4168 2950 166 2659 166 4189 1943 2595 166
+4191 166 166 166 166 2998 2296 5221 3617 166 5435 2451 2009 3005 2242 3768 3658
+166 166 166 166 166 2481 2256 166 166 4074 166 3120 166 4409 1759 166 166 1679
+3659 3499 5219 4501 3082 2047 166 166 166 4560 2768 5251 166 166 166 2437 3993
+3215 2447 166 166 166 2993 4963 166 3045 166 166 166 166 166 166 166 5521 166
+166 4868 166 3895 166 6131 3949 3306 3785 166 166 4895 4831 166 1772 166 166
+5928 166 2137 4805 2462 310 2667 3561 166 166 2312 4931 5255 166 166 166 5670
+166 2285 166 4672 5310 166 2103 2174 166 166 166 166 5417 166 4726 4203 166 166
+166 5581 166 5665 166 166 5747 166 166 2509 1973 2749 5463 166 166 4567 5014
+166 3322 3051 166 4090 166 3709 3887 3478 166 166 166 166 3565 3934 166 32 166
+166 166 2239 166 3947 3849 166 2022 166 2169 166 4691 98 166 3804 4155 1640
+4002 166 2138 1739 3730 5970 2274 4873 3119 166 4925 3577 3699 4049 3982 166
+5161 1744 166 166 166 5704 4979 2686 5383 5744 2289 166 166 166 3927 2539 166
+166 166 2585 166 4723 3755 4509 166 4961 2194 2535 166 176 166 4494 166 4171
+166 266 166 3454 5369 166 166 5899 5284 166 3607 3566 5514 166 1843 166 3997
+4599 2743 166 2857 2497 2751 166 166 166 3511 5742 166 166 166 4504 166 166 166
+5082 4401 166 166 5431 166 166 1949 4539 166 166 4852 166 166 3457 166 3433
+4669 166 1692 2454 3258 6159 166 166 166 166 166 2788 4350 3249 3816 4893 166
+4846 166 4993 1708 4138 166 2895 2891 166 1860 166 2480 1927 3853 166 166 166
+5100 166 3143 5159 166 4286 5182 5246 4975 166 2905 166 4917 5102 2044 6016
+5673 2005 5090 166 4634 3333 166 5702 3413 1762 6094 4284 4431 2641 166 4463
+5691 166 166 3442 3473 4192 2046 166 3838 166 3217 3349 166 2243 166 3490 166
+166 166 5922 166 166 166 4885 1798 2884 2750 5004 2741 166 166 5649 166 4410
+166 166 3382 166 166 1913 1703 5532 3770 166 5116 2645 2634 4357 5901 166 166
+5538 166 166 166 6028 166 166 5840 4102 2704 2091 5287 166 4757 2282 166 2650
+3528 64 253 3732 166 166 166 166 166 3465 166 166 166 5848 3110 111 166 166
+3403 2926 6030 3366 1948 4430 5509 3250 3972 2587 3579 166 6048 250 5275 4242
+2615 3112 3558 166 166 2342 166 5157 1917 2733 5647 1934 5675 166 3981 2923
+5213 5326 37 166 5288 3069 166 1923 5755 166 166 166 1888 166 6041 5895 5376
+3727 3901 166 5589 166 166 4609 166 166 166 4706 166 4482 1622 166 171 166 166
+4646 4151 2755 4614 166 2072 5409 4469 1647 4434 4633 1915 166 3615 4808 166
+3388 166 5280 2731 166 166 2417 166 14 166 4533 5126 166 2778 3022 166 166 166
+4830 4764 166 166 166 4982 166 4265 166 2466 5678 147 1883 166 166 166 114 4000
+2427 3597 166 4853 5981 166 2023 2519 166 1937 2221 4676 166 4522 5716 166 2432
+5731 166 6020 6163 4351 2442 4380 166 4390 1882 6139 4246 262 166 1676 5781
+2352 1956 200 166 166 5800 6184 166 2355 149 5962 5524 4238 166 5150 166 5888
+2423 166 5739 3192 4142 166 166 166 3201 161 4460 2459 158 166 166 166 166 2689
+166 166 166 166 1889 166 166 3374 166 70 166 2772 166 2995 166 2384 4989 166
+3299 166 166 166 166 3614 3645 3415 3160 1727 3735 5201 1693 3531 166 166 1776
+3871 166 166 166 166 86 3553 166 166 166 3392 166 166 2232 166 4977 2333 3394
+2875 2027 5736 166 1719 166 4952 2061 2150 5526 166 4637 166 4333 166 166 4733
+4809 3911 166 3460 166 5355 3126 4181 4436 300 166 3841 166 4770 126 5654 166
+166 166 1730 166 166 166 5610 166 6002 2197 3807 6109 166 166 166 166 166 5395
+4004 166 46 166 166 2570 4736 5318 4247 166 166 166 2293 3031 4591 166 245 166
+5510 1616 3117 4163 166 166 4759 3462 4819 4947 166 3128 5946 2278 2969 166 166
+5183 166 166 1729 173 2448 166 230 2971 166 166 5397 166 4093 3348 1866 4280
+166 6067 3794 166 166 166 4729 166 3456 166 2394 166 4953 166 166 2258 4863 166
+166 4060 166 5468 305 166 6134 166 166 2326 166 3453 2167 2845 166 166 166 5597
+166 166 166 166 5462 2809 5994 2899 166 166 166 5153 166 166 1638 166 166 4938
+3795 166 3842 166 166 166 2769 3194 166 4745 5508 5604 3910 166 166 4147 3239
+166 166 3548 3859 2092 166 2705 166 166 3625 4131 166 3513 166 166 2987 4555
+3107 166 166 166 166 5713 4698 3079 166 5342 166 166 2673 2517 2745 1795 166
+166 166 166 166 166 2463 166 166 2445 5425 6138 166 2687 3254 5871 166 2387
+4300 166 166 3529 1996 166 2369 3818 6126 1615 2643 65 4297 166 5324 3311 3852
+166 3868 4199 3978 166 166 166 5466 166 166 244 166 5929 6157 2390 5639 2267
+2073 4610 5774 2521 4556 166 4545 4307 2426 2450 166 5783 4968 6176 4156 166
+166 4126 3549 166 3581 5701 3234 166 4013 1879 166 6104 5874 166 166 3485 4279
+2528 5576 166 3992 166 3980 4934 166 2176 4228 5164 3784 1933 4120 5055 166 166
+5015 166 166 166 2310 1754 166 6087 166 166 4548 5268 2930 166 3656 166 3042
+5229 166 4016 2195 166 166 166 199 1745 3717 166 166 74 2668 252 4124 4657 5223
+166 2186 3628 166 166 166 4222 3114 2841 5103 3171 5135 166 166 2273 166 3899
+5332 5842 3575 2579 2431 2464 2229 3604 4561 2977 2815 166 3916 166 5825 166
+1694 166 4030 166 5841 166 3881 1831 166 5525 3011 166 5535 5217 316 4116 166
+166 2204 166 3136 3650 166 5813 1875 4511 4475 166 1999 166 2277 166 3024 5484
+5546 166 3988 5676 166 2213 2264 5214 166 4940 5974 166 4750 6077 166 1652 3148
+166 166 166 166 2554 166 6167 5257 5300 166 166 166 166 5408 166 166 3402 2141
+166 4663 5633 3312 166 2814 4930 1959 166 166 166 3861 166 166 302 2624 166 166
+166 1629 1724 166 3909 5281 166 2001 4395 5352 4428 2694 4850 166 166 5242 5910
+166 166 166 166 166 3212 166 2045 166 166 166 166 166 166 3017 4960 4456 166
+5616 6093 2151 166 166 166 315 3381 166 166 166 4330 166 6158 4721 6075 166 166
+166 4543 2303 166 166 3301 166 5000 3929 2543 3437 166 166 166 3422 166 5987
+5729 2428 166 4035 5588 3714 3834 5264 5743 166 3305 4886 6107 5156 166 166 166
+166 166 1672 5849 5827 5049 6101 2178 2420 3289 166 166 4274 6017 2257 166 4172
+3451 2367 2382 166 2964 4918 3241 2347 6082 99 2383 166 4454 163 2460 165 304
+1818 5580 166 312 5790 293 5794 5519 5083 3360 5748 166 3750 5034 166 166 166
+1863 3168 166 166 166 5111 166 166 166 166 2183 4510 166 166 3495 4382 4235
+4462 166 4056 5885 17 5028 1614 6038 166 2488 5632 3089 166 1940 66 4039 3999
+235 166 166 3829 3954 166 2365 269 166 166 166 166 166 166 4418 1796 4709 2004
+166 3596 5786 166 2819 4624 3152 2968 2838 166 5575 1767 5603 166 4386 5890 166
+1768 4201 3560 166 166 166 2184 2262 2966 2716 1765 2611 2983 166 4164 4084 142
+5314 166 166 4071 166 2578 2849 3600 166 166 166 166 5401 4814 3431 166 5088
+5084 198 166 3578 3764 166 2097 166 166 5390 4443 166 3166 166 4816 166 166 166
+166 3130 5963 1788 2129 1837 4100 6128 166 4586 5945 4772 166 5741 3151 3247
+5645 4507 5833 3904 6013 2506 3050 4175 1705 3019 166 5942 166 2418 3430 2230
+5745 166 2093 166 166 166 166 4666 3246 192 2010 4003 3533 5851 166 3621 3684
+3066 166 166 166 5073 3856 166 166 2224 166 2637 4270 166 166 5679 166 5792
+5850 166 2589 3060 2196 3476 3150 2025 166 166 166 2657 166 3685 3790 5587 2817
+3692 166 166 166 2359 2260 5896 2158 119 2816 5753 166 2739 5772 166 2919 2147
+1985 4271 4838 4991 166 166 166 5244 166 319 166 166 2779 4732 4994 5424 166
+166 3968 3049 3393 4473 4959 5967 5864 5170 4209 166 4810 4815 4205 2339 5023
+2279 5050 166 5837 132 166 166 166 2247 21 4775 166 166 5286 166 4170 4099 4803
+5767 166 166 166 5811 2240 5699 2499 166 4802 166 5785 166 166 166 3181 3435
+166 3339 166 5669 3865 2249 5002 166 4694 5461 4753 166 3157 166 1960 166 166
+166 2440 166 5818 5534 2439 1717 166 3789 2959 166 2943 166 2576 166 2002 2007
+1819 3256 4402 5311 3832 160 166 166 2803 166 3264 166 5863 166 2017 166 2798
+166 166 166 166 5607 4965 166 166 166 4537 4378 5944 3494 5457 5602 1942 5900
+5780 4411 5147 166 4966 2115 155 2827 1980 5063 166 285 5912 3304 2963 5179
+3220 166 166 166 2190 3708 5476 1944 2366 3893 166 166 166 3759 166 5434 2740
+1707 4244 5426 166 166 166 3155 166 4285 166 166 166 166 5721 166 3833 6001 301
+166 166 2574 186 2724 166 1873 3667 166 5216 166 2935 2100 4987 166 2284 166
+166 2911 3828 4009 166 2065 166 5496 6130 5563 4387 166 3771 3469 2989 2222
+4577 3965 4296 2975 3813 3240 166 4780 4481 3387 2338 166 6183 166 166 166 166
+166 2675 1761 2600 5167 3170 4773 2165 5166 166 2223 4642 166 166 4540 166 166
+166 3897 166 2483 1809 5477 3844 4067 2508 2275 166 166 166 166 166 3497 5458
+166 249 2956 166 4651 166 283 166 166 4955 4062 2315 2304 3261 2361 4791 4389
+1997 166 3455 166 166 166 166 166 166 4746 5695 5296 105 1841 3368 166 166 166
+5228 166 3496 4423 2024 3907 4774 166 166 166 166 166 2294 2193 166 166 166 166
+166 166 166 166 4393 166 166 2127 166 4573 166 5350 166 5016 3372 166 5653 166
+5972 4719 166 166 166 166 166 5370 166 6142 166 166 3691 2828 166 2601 166 2937
+2060 3654 3097 2341 5325 4568 4096 2776 166 2946 166 166 166 5843 1777 5295
+2837 4261 4397 5006 5808 4866 166 1713 5732 2954 166 166 27 166 4308 5629 2652
+2434 4474 166 4928 166 4727 3811 166 166 5234 166 6010 166 4911 166 4570 166
+6000 3450 5304 3919 166 166 4008 3942 166 272 2363 2064 3595 3505 166 166 3957
+1695 2452 4659 166 1792 166 131 5968 166 3731 3905 4115 166 166 2468 166 2727
+166 3526 4724 166 4388 3149 5539 5092 4440 6162 166 166 193 4429 2493 166 166
+3683 166 6029 166 277 166 166 166 5240 2408 166 309 2561 210 166 5200 166 166
+166 1930 5692 2697 166 166 166 3330 5331 3860 166 166 4335 166 50 3605 4289
+1763 166 166 166 166 3521 166 166 166 3668 166 166 166 166 166 3271 1656 166
+166 4782 166 2962 166 5907 166 3245 3375 2944 5933 166 166 5406 5655 3139 5423
+166 4359 5231 2548 166 3831 2858 5488 166 5824 166 166 166 3885 4372 166 166
+4024 166 4811 2970 166 4219 211 166 3471 166 166 166 166 3854 166 3358 2877 166
+166 5205 2804 166 166 166 4452 166 166 166 166 3776 166 166 3075 4208 166 5623
+1974 166 2647 166 3235 166 166 166 5211 166 166 4304 2206 166 4157 2182 166
+1816 2626 166 2893 2248 166 166 166 166 1983 5648 166 194 166 2106 4328 166
+4742 166 166 5572 2329 3314 166 6181 166 166 26 166 6026 166 166 2114 1669 4735
+166 166 4256 166 1861 166 5470 2317 166 4404 2482 166 5305 4415 5986 4949 5412
+166 1728 166 1898 166 166 4909 1989 166 166 166 2836 2051 274 166 2799 166 5865
+1663 4705 5121 2555 166 4316 4287 1880 1825 166 3689 166 1733 5012 166 166 2237
+4471 1682 2910 166 5366 166 166 166 166 4532 166 2802 166 166 166 4057 2471 166
+2889 166 166 4026 5682 3091 166 1977 166 2901 6137 5658 88 2318 1965 166 5914
+166 166 4468 1822 166 6050 5956 2201 166 4644 2918 166 3703 166 166 3524 4220
+2913 4210 166 166 2090 166 1906 1911 166 166 3671 2370 166 2552 166 3763 2259
+1924 166 5940 166 166 166 3185 3821 4069 261 2381 3244 166 166 5715 166 2052
+5905 166 2403 166 3030 2199 166 3550 166 166 1846 166 166 95 166 289 3208 2559
+5195 5091 1654 166 1781 1892 166 4516 2629 166 1700 3067 166 166 166 2080 1680
+166 166 166 5700 166 1820 5491 166 4226 166 166 166 166 4653 166 3508 227 5364
+166 2098 166 299 166 5795 166 166 166 166 3690 4134 5517 4534 5042 4874 5798
+4234 166 166 166 166 3702 166 166 3638 3108 3850 166 166 166 16 166 1775 166
+4022 166 223 4095 166 5127 4266 166 189 166 166 5203 166 1805 3884 3778 166 166
+2146 4818 166 2848 3440 4506 5886 3006 218 166 2377 166 4091 5925 166 4320 166
+2701 3036 166 166 166 4715 166 3801 166 3161 166 2077 166 4254 3032 243 1814
+166 166 166 166 166 166 166 166 1835 166 4394 166 5769 4923 166 2917 166 166
+178 166 166 1723 166 5887 166 4956 2952 166 4665 3925 3443 3123 166 166 166 166
+166 166 5144 166 4288 2074 2192 5442 6043 1746 2016 5995 2203 166 5686 5659
+3193 166 4055 166 166 2233 3571 5809 5984 2323 166 166 1740 89 4356 6053 6106
+3282 4796 166 6116 6056 2353 2829 166 5807 2042 166 166 166 1670 5937 4465 5646
+166 5562 3008 166 2419 3736 166 4132 169 166 166 166 2402 166 166 1968 2398 166
+1684 1827 4551 2679 3875 166 5585 3835 2295 166 1991 1803 2992 166 166 5847
+2649 166 76 5415 166 2269 2397 5387 5337 4422 166 2672 4832 4617 166 166 166
+166 4552 166 4612 1750 166 1931 166 1691 2424 4194 6018 166 166 4458 4856 166
+2089 3814 166 2844 166 3592 166 4867 5128 166 2685 166 166 2616 1972 2617 3943
+4664 166 4999 166 166 145 3635 166 166 4851 166 3483 5039 166 3649 3924 166 166
+166 3105 4260 166 6098 166 3568 267 2456 3653 2096 166 166 166 3512 166 3405
+166 3504 166 166 166 4005 2144 1769 166 5474 1920 5554 215 2443 3351 166 5961
+166 166 166 166 242 2331 166 166 5931 166 166 5862 166 1710 166 166 166 3321
+166 4139 166 166 3515 2732 2510 5544 166 166 2783 166 166 166 4018 4649 5789
+166 166 166 166 166 2726 6074 166 166 166 5684 166 166 3395 166 3100 166 5763
+3757 1992 166 3198 2003 166 166 4675 166 1893 5621 166 2270 166 166 166 5421
+5590 5664 4045 166 3687 4406 2699 1811 167 4036 5384 166 166 4601 1823 4041 239
+1954 166 146 166 166 3077 5152 5814 1649 5681 166 5868 166 166 3792 4860 166
+5335 5110 1718 166 166 166 166 3718 3365 2826 166 166 5021 4783 166 5569 5812
+166 166 1876 166 3260 166 1789 5667 4224 166 166 4385 166 166 2620 166 4162
+2883 2143 5497 166 166 5316 5680 166 166 248 4050 166 6021 166 2898 4618 166
+166 166 166 166 5368 166 5378 1842 1914 3696 3962 166 4345 2581 1773 2109 166
+4371 166 166 3761 5277 5870 3146 166 166 166 5764 127 3058 4059 4718 166 5097
+5040 5351 3205 166 166 4996 2991 2014 166 5846 2558 2688 5595 4027 3347 2125
+5696 5608 166 166 3228 3745 5775 166 1757 4647 166 5977 3020 166 240 2565 166
+4459 166 3367 166 166 166 3104 166 166 166 166 166 166 259 5486 2846 166 166
+166 4778 2713 166 3955 5683 2682 2914 5898 166 166 166 4400 317 166 5185 3021
+5983 4332 3891 166 3095 5003 166 166 166 5367 166 279 1784 4019 2736 4905 2651
+5346 166 4841 166 5606 166 166 2806 166 5239 166 166 3237 5490 166 225 166 166
+2254 166 2742 4587 22 166 166 166 5555 166 108 2927 2218 166 2120 166 5452 4087
+4369 166 166 166 166 166 4583 4338 6035 2840 4365 3624 11 1770 166 4630 166
+3216 166 166 166 4638 4699 3535 2536 4627 166 166 5760 1935 166 166 5210 166
+2219 2484 4597 5193 4799 3706 166 166 166 166 3337 3113 5951 4294 166 4040 3200
+4217 5861 2767 3530 4499 2775 4121 134 5939 5880 5908 3869 166 166 3316 6095
+2441 3288 166 3751 4794 166 166 5803 6169 2356 6182 6135 6127 166 3018 166 1674
+166 166 4097 166 5923 287 5965 5129 166 4078 166 166 6114 6015 5990 3573 166
+4146 2681 90 6055 4864 166 166 6119 3284 6054 5456 5113 6125 166 6057 166 3292
+166 166 166 166 166 6185 5105 1760 166 166 166 2720 166 2695 5448 166 1936 166
+1807 3406 166 166 2161 1642 166 5030 166 2036 5451 3427 166 166 166 166 3797
+166 1627 166 4515 166 166 166 4241 166 166 166 2771 166 31 5197 2638 3035 166
+166 3914 166 166 4546 166 166 166 4253 3500 166 166 2526 166 2698 166 3726 2744
+137 166 166 2676 166 5594 166 166 166 4842 166 63 2888 3585 4798 166 5011 166
+5634 5464 166 166 5620 3894 4070 166 2730 166 166 1810 2503 5957 1721 6066 5188
+166 166 1890 4505 1771 5455 166 3132 3984 166 166 2811 1962 166 166 4872 106
+3898 3267 166 2085 166 4950 6040 4525 6044 5866 3613 2907 4615 2135 258 166
+1681 1941 4888 166 4859 6178 6174 4858 5209 1912 3340 166 4640 5706 166 2763
+3153 3951 166 5542 5596 5819 5330 5048 4037 166 6033 4625 3326 2013 5283 136
+3373 2154 166 166 166 4421 166 5438 2627 2266 2320 166 2588 4790 4290 166 4767
+5829 2925 5916 2133 166 }
diff --git a/extra/poker/authors.txt b/extra/poker/authors.txt
new file mode 100644 (file)
index 0000000..fbbb745
--- /dev/null
@@ -0,0 +1 @@
+Aaron Schaefer
\ No newline at end of file
diff --git a/extra/poker/poker-docs.factor b/extra/poker/poker-docs.factor
new file mode 100644 (file)
index 0000000..09019a2
--- /dev/null
@@ -0,0 +1,30 @@
+USING: help.markup help.syntax strings ;
+IN: poker
+
+HELP: <hand>
+{ $values { "str" string } { "hand" "a new hand" } }
+{ $description "Creates a new poker hand containing the cards specified in " { $snippet "str" } "." }
+{ $examples
+    { $example "USING: kernel math.order poker prettyprint ;"
+        "\"AC KC QC JC TC\" \"7C 6D 5H 4S 2C\" [ <hand> ] bi@ <=> ." "+lt+" }
+    { $example "USING: kernel poker prettyprint ;"
+        "\"TC 9C 8C 7C 6C\" \"TH 9H 8H 7H 6H\" [ <hand> ] bi@ = ." "t" }
+}
+{ $notes "Cards may be specified in any order. Hands are directly comparable to each other on the basis of their computed value. Two hands are considered equal when they would tie in a game (despite being composed of different cards)." } ;
+
+HELP: >cards
+{ $values { "hand" "a hand" } { "str" string } }
+{ $description "Outputs a string representation of a hand's cards." }
+{ $examples
+    { $example "USING: poker prettyprint ;"
+        "\"AC KC QC JC TC\" <hand> >cards ." "\"AC KC QC JC TC\"" }
+} ;
+
+HELP: >value
+{ $values { "hand" "a hand" } { "str" string } }
+{ $description "Outputs a string representation of a hand's value." }
+{ $examples
+    { $example "USING: poker prettyprint ;"
+        "\"AC KC QC JC TC\" <hand> >value ." "\"Straight Flush\"" }
+}
+{ $notes "This should not be used as a basis for hand comparison." } ;
diff --git a/extra/poker/poker-tests.factor b/extra/poker/poker-tests.factor
new file mode 100644 (file)
index 0000000..ad371a6
--- /dev/null
@@ -0,0 +1,28 @@
+USING: accessors poker poker.private tools.test math.order kernel ;
+IN: poker.tests
+
+[ 134236965 ] [ "KD" >ckf ] unit-test
+[ 529159 ] [ "5s" >ckf ] unit-test
+[ 33589533 ] [ "jc" >ckf ] unit-test
+
+[ 7462 ] [ "7C 5D 4H 3S 2C" <hand> value>> ] unit-test
+[ 1601 ] [ "KD QS JC TH 9S" <hand> value>> ] unit-test
+[ 11 ] [ "AC AD AH AS KC" <hand> value>> ] unit-test
+[ 9 ] [ "6C 5C 4C 3C 2C" <hand> value>> ] unit-test
+[ 1 ] [ "AC KC QC JC TC" <hand> value>> ] unit-test
+
+[ "High Card" ] [ "7C 5D 4H 3S 2C" <hand> >value ] unit-test
+[ "Straight" ] [ "KD QS JC TH 9S" <hand> >value ] unit-test
+[ "Four of a Kind" ] [ "AC AD AH AS KC" <hand> >value ] unit-test
+[ "Straight Flush" ] [ "6C 5C 4C 3C 2C" <hand> >value ] unit-test
+
+[ "6C 5C 4C 3C 2C" ] [ "6C 5C 4C 3C 2C" <hand> >cards ] unit-test
+
+[ +gt+ ] [ "7C 5D 4H 3S 2C" "KD QS JC TH 9S" [ <hand> ] bi@ <=> ] unit-test
+[ +lt+ ] [ "AC AD AH AS KC" "KD QS JC TH 9S" [ <hand> ] bi@ <=> ] unit-test
+[ +eq+ ] [ "7C 5D 4H 3S 2C" "7D 5D 4D 3C 2S" [ <hand> ] bi@ <=> ] unit-test
+
+[ t ] [ "7C 5D 4H 3S 2C" "2C 3S 4H 5D 7C" [ <hand> ] bi@ = ] unit-test
+
+[ t ] [ "7C 5D 4H 3S 2C" "7D 5D 4D 3C 2S" [ <hand> ] bi@ = ] unit-test
+[ f ] [ "7C 5D 4H 3S 2C" "7D 5D 4D 3C 2S" [ <hand> ] bi@ eq? ] unit-test
diff --git a/extra/poker/poker.factor b/extra/poker/poker.factor
new file mode 100644 (file)
index 0000000..2a7fe73
--- /dev/null
@@ -0,0 +1,191 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors ascii binary-search combinators kernel locals math
+    math.bitwise math.order poker.arrays sequences splitting ;
+IN: poker
+
+! The algorithm used is based on Cactus Kev's Poker Hand Evaluator with
+! the Senzee Perfect Hash Optimization:
+!     http://www.suffecool.net/poker/evaluator.html
+!     http://www.senzee5.com/2006/06/some-perfect-hash.html
+
+<PRIVATE
+
+! Bitfield Format for Card Values:
+
+!     +-------------------------------------+
+!     | xxxbbbbb bbbbbbbb ssssrrrr xxpppppp |
+!     +-------------------------------------+
+!       xxxAKQJT 98765432 CDHSrrrr xxpppppp
+!     +-------------------------------------+
+!     | 00001000 00000000 01001011 00100101 |  King of Diamonds
+!     | 00000000 00001000 00010011 00000111 |  Five of Spades
+!     | 00000010 00000000 10001001 00011101 |  Jack of Clubs
+
+! p = prime number value of rank (deuce = 2, trey = 3, four = 5, ..., ace = 41)
+! r = rank of card (deuce = 0, trey = 1, four = 2, ..., ace = 12)
+! s = bit turned on depending on suit of card
+! b = bit turned on depending on rank of card
+! x = bit turned off, not used
+
+CONSTANT: CLUB     8
+CONSTANT: DIAMOND  4
+CONSTANT: HEART    2
+CONSTANT: SPADE    1
+
+CONSTANT: DEUCE  0
+CONSTANT: TREY   1
+CONSTANT: FOUR   2
+CONSTANT: FIVE   3
+CONSTANT: SIX    4
+CONSTANT: SEVEN  5
+CONSTANT: EIGHT  6
+CONSTANT: NINE   7
+CONSTANT: TEN    8
+CONSTANT: JACK   9
+CONSTANT: QUEEN  10
+CONSTANT: KING   11
+CONSTANT: ACE    12
+
+CONSTANT: STRAIGHT_FLUSH   1
+CONSTANT: FOUR_OF_A_KIND   2
+CONSTANT: FULL_HOUSE       3
+CONSTANT: FLUSH            4
+CONSTANT: STRAIGHT         5
+CONSTANT: THREE_OF_A_KIND  6
+CONSTANT: TWO_PAIR         7
+CONSTANT: ONE_PAIR         8
+CONSTANT: HIGH_CARD        9
+
+CONSTANT: RANK_STR { "2" "3" "4" "5" "6" "7" "8" "9" "T" "J" "Q" "K" "A" }
+
+CONSTANT: VALUE_STR { "" "Straight Flush" "Four of a Kind" "Full House" "Flush"
+    "Straight" "Three of a Kind" "Two Pair" "One Pair" "High Card" }
+
+: card-rank-prime ( rank -- n )
+    RANK_STR index { 2 3 5 7 11 13 17 19 23 29 31 37 41 } nth ;
+
+: card-rank ( rank -- n )
+    {
+        { "2" [ DEUCE ] }
+        { "3" [ TREY  ] }
+        { "4" [ FOUR  ] }
+        { "5" [ FIVE  ] }
+        { "6" [ SIX   ] }
+        { "7" [ SEVEN ] }
+        { "8" [ EIGHT ] }
+        { "9" [ NINE  ] }
+        { "T" [ TEN   ] }
+        { "J" [ JACK  ] }
+        { "Q" [ QUEEN ] }
+        { "K" [ KING  ] }
+        { "A" [ ACE   ] }
+    } case ;
+
+: card-suit ( suit -- n )
+    {
+        { "C" [ CLUB    ] }
+        { "D" [ DIAMOND ] }
+        { "H" [ HEART   ] }
+        { "S" [ SPADE   ] }
+    } case ;
+
+: card-rank-bit ( rank -- n )
+    RANK_STR index 1 swap shift ;
+
+: card-bitfield ( rank rank suit rank -- n )
+    {
+        { card-rank-bit 16 }
+        { card-suit 12 }
+        { card-rank 8 }
+        { card-rank-prime 0 }
+    } bitfield ;
+
+:: (>ckf) ( rank suit -- n )
+    rank rank suit rank card-bitfield ;
+
+: >ckf ( str -- n )
+    #! Cactus Kev Format
+    >upper 1 cut (>ckf) ;
+
+: flush? ( cards -- ? )
+    HEX: F000 [ bitand ] reduce 0 = not ;
+
+: rank-bits ( cards -- q )
+    0 [ bitor ] reduce -16 shift ;
+
+: lookup ( cards table -- value )
+    [ rank-bits ] dip nth ;
+
+: unique5? ( cards -- ? )
+    unique5-table lookup 0 > ;
+
+: map-product ( seq quot -- n )
+    [ 1 ] 2dip [ dip * ] curry [ swap ] prepose each ; inline
+
+: prime-bits ( cards -- q )
+    [ HEX: FF bitand ] map-product ;
+
+: perfect-hash-find ( q -- value )
+    #! magic to convert a hand's unique identifying bits to the
+    #! proper index for fast lookup in a table of hand values
+    HEX: E91AAA35 +
+    dup -16 shift bitxor
+    dup   8 shift w+
+    dup  -4 shift bitxor
+    [ -8 shift HEX: 1FF bitand adjustments-table nth ]
+    [ dup 2 shift w+ -19 shift ] bi
+    bitxor values-table nth ;
+
+: hand-value ( cards -- value )
+    {
+        { [ dup flush?   ] [ flushes-table lookup ] }
+        { [ dup unique5? ] [ unique5-table lookup ] }
+        [ prime-bits perfect-hash-find ]
+    } cond ;
+
+: >card-rank ( card -- str )
+    -8 shift HEX: F bitand RANK_STR nth ;
+
+: >card-suit ( card -- str )
+    {
+        { [ dup 15 bit? ] [ drop "C" ] }
+        { [ dup 14 bit? ] [ drop "D" ] }
+        { [ dup 13 bit? ] [ drop "H" ] }
+        [ drop "S" ]
+    } cond ;
+
+: hand-rank ( hand -- rank )
+    value>> {
+        { [ dup 6185 > ] [ drop HIGH_CARD ] }        ! 1277 high card
+        { [ dup 3325 > ] [ drop ONE_PAIR ] }         ! 2860 one pair
+        { [ dup 2467 > ] [ drop TWO_PAIR ] }         !  858 two pair
+        { [ dup 1609 > ] [ drop THREE_OF_A_KIND ] }  !  858 three-kind
+        { [ dup 1599 > ] [ drop STRAIGHT ] }         !   10 straights
+        { [ dup 322 > ]  [ drop FLUSH ] }            ! 1277 flushes
+        { [ dup 166 > ]  [ drop FULL_HOUSE ] }       !  156 full house
+        { [ dup 10 > ]   [ drop FOUR_OF_A_KIND ] }   !  156 four-kind
+        [ drop STRAIGHT_FLUSH ]                      !   10 straight-flushes
+    } cond ;
+
+PRIVATE>
+
+TUPLE: hand
+    { cards sequence }
+    { value integer } ;
+
+M: hand <=> [ value>> ] compare ;
+M: hand equal?
+    over hand? [ [ value>> ] bi@ = ] [ 2drop f ] if ;
+
+: <hand> ( str -- hand )
+    " " split [ >ckf ] map
+    dup hand-value hand boa ;
+
+: >cards ( hand -- str )
+    cards>> [
+        [ >card-rank ] [ >card-suit ] bi append
+    ] map " " join ;
+
+: >value ( hand -- str )
+    hand-rank VALUE_STR nth ;
diff --git a/extra/poker/summary.txt b/extra/poker/summary.txt
new file mode 100644 (file)
index 0000000..c8efe85
--- /dev/null
@@ -0,0 +1 @@
+5-card poker hand evaluator
index 8d2461a510972947306a36688820cddb34c25124..1cab2756192b690b3ded1aa9fb4a207714873760 100644 (file)
@@ -4,3 +4,4 @@ IN: project-euler.001.tests
 [ 233168 ] [ euler001 ] unit-test
 [ 233168 ] [ euler001a ] unit-test
 [ 233168 ] [ euler001b ] unit-test
+[ 233168 ] [ euler001c ] unit-test
index 1e49be9a608d38038a1a8c57a7641dda8e8b73a4..20e08242c5e3a0f00091f7e6a5d6e36a0cd5a20a 100644 (file)
@@ -1,6 +1,6 @@
-! Copyright (c) 2007 Aaron Schaefer.
+! Copyright (c) 2007, 2008 Aaron Schaefer, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.ranges sequences ;
+USING: kernel math math.functions math.ranges sequences project-euler.common ;
 IN: project-euler.001
 
 ! http://projecteuler.net/index.php?section=problems&id=1
@@ -51,4 +51,11 @@ PRIVATE>
 ! [ euler001b ] 100 ave-time
 ! 0 ms run / 0 ms GC ave time - 100 trials
 
-MAIN: euler001
+
+: euler001c ( -- answer )
+    1000 [ { 3 5 } [ divisor? ] with any? ] filter sum ;
+
+! [ euler001c ] 100 ave-time
+! 0 ms ave run time - 0.06 SD (100 trials)
+
+SOLUTION: euler001
index 136ebbb6da79a76d64d08d6517072b890aaae7c8..9995e434e7cec04337409aa2c633f36f757e71b3 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer, Alexander Solovyov, Vishal Talwar.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math sequences ;
+USING: kernel math sequences project-euler.common ;
 IN: project-euler.002
 
 ! http://projecteuler.net/index.php?section=problems&id=2
@@ -77,4 +77,4 @@ PRIVATE>
 ! [ euler002b ] 100 ave-time
 ! 0 ms ave run time - 0.0 SD (100 trials)
 
-MAIN: euler002b
+SOLUTION: euler002b
index 09374bcee302d26c26b4e01bc00e5a5460e25a40..36dc862de68eb66e0645d36e7d80ddc4ca8dec90 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math.primes.factors sequences ;
+USING: math.primes.factors sequences project-euler.common ;
 IN: project-euler.003
 
 ! http://projecteuler.net/index.php?section=problems&id=3
@@ -22,4 +22,4 @@ IN: project-euler.003
 ! [ euler003 ] 100 ave-time
 ! 1 ms ave run time - 0.49 SD (100 trials)
 
-MAIN: euler003
+SOLUTION: euler003
index e1918f5fa6b5fb92b1a6f36e01b5852ac5a2584b..fe09914d9f2edc125dd065df911e0383b825eab2 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007 Aaron Schaefer, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: hashtables kernel math math.ranges project-euler.common sequences
-    sorting sets ;
+USING: hashtables kernel math math.functions math.ranges project-euler.common
+    sequences sorting sets ;
 IN: project-euler.004
 
 ! http://projecteuler.net/index.php?section=problems&id=4
@@ -21,7 +21,7 @@ IN: project-euler.004
 <PRIVATE
 
 : source-004 ( -- seq )
-    100 999 [a,b] [ 10 mod 0 = not ] filter ;
+    100 999 [a,b] [ 10 divisor? not ] filter ;
 
 : max-palindrome ( seq -- palindrome )
     natural-sort [ palindrome? ] find-last nip ;
@@ -34,4 +34,4 @@ PRIVATE>
 ! [ euler004 ] 100 ave-time
 ! 1164 ms ave run time - 39.35 SD (100 trials)
 
-MAIN: euler004
+SOLUTION: euler004
index 8b446f237628f8545c1e1454ea0b1c5f7b071c8c..7fef29a6b9d73be55a9c70923485db6c50df537e 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math math.functions sequences ;
+USING: math math.functions sequences project-euler.common ;
 IN: project-euler.005
 
 ! http://projecteuler.net/index.php?section=problems&id=5
@@ -23,4 +23,4 @@ IN: project-euler.005
 ! [ euler005 ] 100 ave-time
 ! 0 ms ave run time - 0.14 SD (100 trials)
 
-MAIN: euler005
+SOLUTION: euler005
index 21493536583ae4a4287c602adde37f9e645e78df..00a5c447713e87b36b3d46c8828ba8209e481777 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.ranges sequences ;
+USING: kernel math math.ranges sequences project-euler.common ;
 IN: project-euler.006
 
 ! http://projecteuler.net/index.php?section=problems&id=6
@@ -40,4 +40,4 @@ PRIVATE>
 ! [ euler006 ] 100 ave-time
 ! 0 ms ave run time - 0.24 SD (100 trials)
 
-MAIN: euler006
+SOLUTION: euler006
index f40108e4d7105ff2b98453d4a07c2ba7da61f978..1827d0fa069709428ef0a2ebd0e75e0a97aee388 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: lists math math.primes.lists ;
+USING: lists math math.primes.lists project-euler.common ;
 IN: project-euler.007
 
 ! http://projecteuler.net/index.php?section=problems&id=7
@@ -17,13 +17,10 @@ IN: project-euler.007
 ! SOLUTION
 ! --------
 
-: nth-prime ( n -- n )
-    1- lprimes lnth ;
-
 : euler007 ( -- answer )
     10001 nth-prime ;
 
 ! [ euler007 ] 100 ave-time
 ! 5 ms ave run time - 1.13 SD (100 trials)
 
-MAIN: euler007
+SOLUTION: euler007
index 1e8dade646d603ff2460d6c879ba7572f8b2889c..dcc669b125be518c03482baa1e3edb53f4faf2c4 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: grouping math.order math.parser sequences ;
+USING: grouping math.order math.parser sequences project-euler.common ;
 IN: project-euler.008
 
 ! http://projecteuler.net/index.php?section=problems&id=8
@@ -69,4 +69,4 @@ PRIVATE>
 ! [ euler008 ] 100 ave-time
 ! 2 ms ave run time - 0.79 SD (100 trials)
 
-MAIN: euler008
+SOLUTION: euler008
index a1040d2bf2687a6a5f4c33008fada47acd97619e..f75950520d810b60efc29aa80a73eff96f266cbe 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel make math sequences sorting ;
+USING: kernel make math sequences sorting project-euler.common ;
 IN: project-euler.009
 
 ! http://projecteuler.net/index.php?section=problems&id=9
@@ -50,4 +50,4 @@ PRIVATE>
 ! [ euler009 ] 100 ave-time
 ! 1 ms ave run time - 0.73 SD (100 trials)
 
-MAIN: euler009
+SOLUTION: euler009
index 593f9cc0e898fc6dd19e09c907a8708bd49253ab..648699e1dbd0a9c9405709769fdae5501515f816 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer, Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math.primes sequences ;
+USING: math.primes sequences project-euler.common ;
 IN: project-euler.010
 
 ! http://projecteuler.net/index.php?section=problems&id=10
@@ -22,4 +22,4 @@ IN: project-euler.010
 ! [ euler010 ] 100 ave-time
 ! 15 ms ave run time - 0.41 SD (100 trials)
 
-MAIN: euler010
+SOLUTION: euler010
index 122eec2c2e6904c1dfc6a9cf7fb38b98e0d6aea0..9d98ac67668817bbf2cdc514fdcabaaa2dfd602f 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: grouping kernel make math.order sequences ;
+USING: grouping kernel make math.order sequences project-euler.common ;
 IN: project-euler.011
 
 ! http://projecteuler.net/index.php?section=problems&id=11
@@ -101,4 +101,4 @@ PRIVATE>
 ! [ euler011 ] 100 ave-time
 ! 3 ms ave run time - 0.77 SD (100 trials)
 
-MAIN: euler011
+SOLUTION: euler011
index ff482c6812ca3a7cd154a9afeeac06c6d29d79d8..d2679f6309eade32c9880dc7bbb410cf5f388a07 100644 (file)
@@ -39,4 +39,4 @@ IN: project-euler.012
 ! [ euler012 ] 10 ave-time
 ! 6573 ms ave run time - 346.27 SD (10 trials)
 
-MAIN: euler012
+SOLUTION: euler012
index 857bd62cc40c7bce093c8796396a8c3b73aa282b..25aad2d749223f1d86d06f72f8b90a3e34d4e7f6 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math.parser sequences ;
+USING: math.parser sequences project-euler.common ;
 IN: project-euler.013
 
 ! http://projecteuler.net/index.php?section=problems&id=13
@@ -230,4 +230,4 @@ PRIVATE>
 ! [ euler013 ] 100 ave-time
 ! 0 ms ave run time - 0.31 SD (100 trials)
 
-MAIN: euler013
+SOLUTION: euler013
index e93e3d11bc803019d601fc4844cc3cd8a3c05ced..b0305d5c3941daeb3154244dc6677e7e34068e90 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators.short-circuit kernel make math math.ranges sequences ;
+USING: combinators.short-circuit kernel make math math.functions math.ranges
+    sequences project-euler.common ;
 IN: project-euler.014
 
 ! http://projecteuler.net/index.php?section=problems&id=14
@@ -58,7 +59,7 @@ PRIVATE>
 <PRIVATE
 
 : worth-calculating? ( n -- ? )
-    1- 3 { [ mod 0 = ] [ / even? ] } 2&& ;
+    1- 3 { [ divisor? ] [ / even? ] } 2&& ;
 
 PRIVATE>
 
@@ -72,4 +73,4 @@ PRIVATE>
 
 ! TODO: try using memoization
 
-MAIN: euler014a
+SOLUTION: euler014a
index fb720c7e7c76545484921e6d267ee9f4e0ad6b72..03823deab41d378e5ffa0a79dcd96bcb7db3c775 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.combinatorics ;
+USING: kernel math math.combinatorics project-euler.common ;
 IN: project-euler.015
 
 ! http://projecteuler.net/index.php?section=problems&id=15
@@ -30,4 +30,4 @@ PRIVATE>
 ! [ euler015 ] 100 ave-time
 ! 0 ms ave run time - 0.2 SD (100 trials)
 
-MAIN: euler015
+SOLUTION: euler015
index 216fcb3523382cd33d62ffd72f7ad1911aafbaa2..b81619b980df6bcd3b75038c31e00b9dc2b9bfb0 100644 (file)
@@ -22,4 +22,4 @@ IN: project-euler.016
 ! [ euler016 ] 100 ave-time
 ! 0 ms ave run time - 0.67 SD (100 trials)
 
-MAIN: euler016
+SOLUTION: euler016
index 21e277da00455db69539965a2a0b1d6969288d45..53513691ff795147030153c9568818e9042a7d0e 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2007, 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: ascii kernel math.ranges math.text.english sequences ;
+USING: ascii kernel math.ranges math.text.english sequences
+project-euler.common ;
 IN: project-euler.017
 
 ! http://projecteuler.net/index.php?section=problems&id=17
@@ -28,4 +29,4 @@ IN: project-euler.017
 ! [ euler017 ] 100 ave-time
 ! 15 ms ave run time - 1.71 SD (100 trials)
 
-MAIN: euler017
+SOLUTION: euler017
index 21831b90d49b1217735a9f183dc2dd726757e231..a4aded7096c28bac286382f637e15a3f9065b5a2 100644 (file)
@@ -86,4 +86,4 @@ PRIVATE>
 ! [ euler018a ] 100 ave-time
 ! 0 ms ave run time - 0.39 SD (100 trials)
 
-MAIN: euler018a
+SOLUTION: euler018a
index 4b750ac1805bb11aa9e7b3323e802be8276cd03e..fc9cdacad794ee00615395fef42884e1dff3c297 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007 Samuel Tardieu, Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: calendar combinators kernel math math.ranges namespaces sequences
-    math.order ;
+    math.order project-euler.common ;
 IN: project-euler.019
 
 ! http://projecteuler.net/index.php?section=problems&id=19
@@ -63,4 +63,4 @@ PRIVATE>
 ! [ euler019a ] 100 ave-time
 ! 17 ms ave run time - 2.13 SD (100 trials)
 
-MAIN: euler019
+SOLUTION: euler019
index e75747b57c80dd3d70a5e68015c615e76ff31c31..85aeebb5adc1c5d95282c13b79c4999b0a5eaef0 100644 (file)
@@ -22,4 +22,4 @@ IN: project-euler.020
 ! [ euler020 ] 100 ave-time
 ! 0 ms ave run time - 0.55 (100 trials)
 
-MAIN: euler020
+SOLUTION: euler020
index 55060a7c71aeb442004aede598864f58921fb047..0401aad9be97579003073d1cf2887543989869ef 100644 (file)
@@ -35,4 +35,4 @@ IN: project-euler.021
 ! [ euler021 ] 100 ave-time
 ! 335 ms ave run time - 18.63 SD (100 trials)
 
-MAIN: euler021
+SOLUTION: euler021
index a12838406ab6d8f9fe973d3ab6b4fa03eaff7c12..1b675d41c47333ff9171c85a652ae12ca873b70a 100644 (file)
@@ -42,4 +42,4 @@ PRIVATE>
 ! [ euler022 ] 100 ave-time
 ! 74 ms ave run time - 5.13 SD (100 trials)
 
-MAIN: euler022
+SOLUTION: euler022
index 80aa40f449bbe9f8d61bd66a12dda1a6722ef887..7c28ebfa6cd9aacac09ac74c6e9c6e47bf91e85d 100644 (file)
@@ -58,4 +58,4 @@ PRIVATE>
 ! [ euler023 ] time
 ! 52780 ms run / 3839 ms GC
 
-MAIN: euler023
+SOLUTION: euler023
index c10ce418c4e471cefe8b7730c7a7ae18ce82a1ea..f6b4d497c070ae45150178a0166e5b42e1c09717 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math.combinatorics math.parser ;
+USING: kernel math.combinatorics math.parser project-euler.common ;
 IN: project-euler.024
 
 ! http://projecteuler.net/index.php?section=problems&id=24
@@ -28,4 +28,4 @@ IN: project-euler.024
 ! [ euler024 ] 100 ave-time
 ! 0 ms ave run time - 0.27 SD (100 trials)
 
-MAIN: euler024
+SOLUTION: euler024
index a2934c23c71f8c5771e07c7e3c41e3b8369d3863..80a933dc63a74a106aca65fbd1dcdf2b7a4e4188 100644 (file)
@@ -78,4 +78,4 @@ PRIVATE>
 ! [ euler025a ] 100 ave-time
 ! 0 ms ave run time - 0.17 SD (100 trials)
 
-MAIN: euler025a
+SOLUTION: euler025a
index cf30d0ee4288a8793a9663bc96a1b4ac87c59ffd..8e0cf37fa2724b6ad466989052747d93c0d6812e 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions math.primes math.ranges sequences ;
+USING: kernel math math.functions math.primes math.ranges sequences project-euler.common ;
 IN: project-euler.026
 
 ! http://projecteuler.net/index.php?section=problems&id=26
@@ -68,4 +68,4 @@ PRIVATE>
 ! [ euler026 ] 100 ave-time
 ! 290 ms ave run time - 19.2 SD (100 trials)
 
-MAIN: euler026
+SOLUTION: euler026
index 5bf753074e4c05295e39f9ad4dd5d7d7d85d98ca..4bcfb66a9405d73726179abfbca50f8d673c20ee 100644 (file)
@@ -1,6 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.primes project-euler.common sequences ;
+USING: kernel math math.primes project-euler.common sequences
+project-euler.common ;
 IN: project-euler.027
 
 ! http://projecteuler.net/index.php?section=problems&id=27
@@ -72,4 +73,4 @@ PRIVATE>
 
 ! TODO: generalize max-consecutive/max-product (from #26) into a new word
 
-MAIN: euler027
+SOLUTION: euler027
index cd359c70a9bbadde9b0c124d2d5724cbc7bfd7ea..6dc284f802150b8dac480874ef51592b4fc1bb23 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.ranges sequences ;
+USING: kernel math math.ranges sequences project-euler.common ;
 IN: project-euler.028
 
 ! http://projecteuler.net/index.php?section=problems&id=28
@@ -43,4 +43,4 @@ PRIVATE>
 ! [ euler028 ] 100 ave-time
 ! 0 ms ave run time - 0.39 SD (100 trials)
 
-MAIN: euler028
+SOLUTION: euler028
index 2586e6182ae4c9eaaf18eab6a4a0c0ee336b2e4c..73773e1887d146ab5e83b77e0883b64e03d0cb75 100644 (file)
@@ -34,4 +34,4 @@ IN: project-euler.029
 ! [ euler029 ] 100 ave-time
 ! 704 ms ave run time - 28.07 SD (100 trials)
 
-MAIN: euler029
+SOLUTION: euler029
index 63693f96d8a38f2119e9cf475f2432a5701083d5..54d48660d5af251e7caf7124892f12c0bebd9122 100644 (file)
@@ -43,4 +43,4 @@ PRIVATE>
 ! [ euler030 ] 100 ave-time
 ! 1700 ms ave run time - 64.84 SD (100 trials)
 
-MAIN: euler030
+SOLUTION: euler030
index 1b6d1c83eb26a75eb1b2f61c283d6b619189951d..f5648721498d301199f572c877efe6988df542f3 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math ;
+USING: kernel math project-euler.common ;
 IN: project-euler.031
 
 ! http://projecteuler.net/index.php?section=problems&id=31
@@ -60,4 +60,4 @@ PRIVATE>
 
 ! TODO: generalize to eliminate duplication; use a sequence to specify denominations?
 
-MAIN: euler031
+SOLUTION: euler031
index 07c643659c723c911b74e0b17022869db43cdd14..5ff5234679c318fbaf47874f9e9e3e5424c05c3c 100755 (executable)
@@ -75,4 +75,4 @@ PRIVATE>
 ! [ euler032a ] 10 ave-time
 ! 2624 ms ave run time - 131.91 SD (10 trials)
 
-MAIN: euler032a
+SOLUTION: euler032a
index d0c79c220a151e2e2ae0bdb093bb65bc218a2084..780015ab77b8b6e90a96559036c2d69b0c4a20f8 100644 (file)
@@ -33,7 +33,7 @@ IN: project-euler.033
     10 99 [a,b] dup cartesian-product [ first2 < ] filter ;
 
 : safe? ( ax xb -- ? )
-    [ 10 /mod ] bi@ -roll = rot zero? not and nip ;
+    [ 10 /mod ] bi@ [ = ] dip zero? not and nip ;
 
 : ax/xb ( ax xb -- z/f )
     2dup safe? [ [ 10 /mod ] bi@ 2nip / ] [ 2drop f ] if ;
@@ -52,4 +52,4 @@ PRIVATE>
 ! [ euler033 ] 100 ave-time
 ! 7 ms ave run time - 1.31 SD (100 trials)
 
-MAIN: euler033
+SOLUTION: euler033
index 11b7efa8b55fedae275d5b4fd11ef4458510e07f..f7a4865da7aea861aa52fed58245a3b040498add 100644 (file)
@@ -44,4 +44,4 @@ PRIVATE>
 ! [ euler034 ] 10 ave-time
 ! 5506 ms ave run time - 144.0 SD (10 trials)
 
-MAIN: euler034
+SOLUTION: euler034
index 517e5211d20e4d1461b7c145406f5ed4c296159b..378461842312e15d9f4815690281e5abc03e6c8a 100755 (executable)
@@ -58,4 +58,4 @@ PRIVATE>
 ! TODO: try using bit arrays or other methods outlined here:
 !     http://home.comcast.net/~babdulbaki/Circular_Primes.html
 
-MAIN: euler035
+SOLUTION: euler035
index f5afeceb21fd3858af6b727fa875f5f5492a5a5a..e6c257969e60ac8624be1e7c8f52a103cb8c65eb 100644 (file)
@@ -36,4 +36,4 @@ PRIVATE>
 ! [ euler036 ] 100 ave-time
 ! 1703 ms ave run time - 96.6 SD (100 trials)
 
-MAIN: euler036
+SOLUTION: euler036
index 4562c4588f90c7f559455cf85dcb651a3dff62a7..e59f506962127c33e90511122312e0eb3dc81041 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.parser math.primes sequences ;
+USING: kernel math math.parser math.primes sequences project-euler.common ;
 IN: project-euler.037
 
 ! http://projecteuler.net/index.php?section=problems&id=37
@@ -49,4 +49,4 @@ PRIVATE>
 ! [ euler037 ] 100 ave-time
 ! 130 ms ave run time - 6.27 SD (100 trials)
 
-MAIN: euler037
+SOLUTION: euler037
index 2df993b341dda71ca60781fa780be60fe1d90d9c..3c6e2eac0275d365a452b4b816344c4f2b841984 100755 (executable)
@@ -53,4 +53,4 @@ PRIVATE>
 ! [ euler038 ] 100 ave-time
 ! 11 ms ave run time - 1.5 SD (100 trials)
 
-MAIN: euler038
+SOLUTION: euler038
index 6b5601566762f0e0be2721afef150948594abd44..dee3f9804c15dde9c4ebd4d579c82e513297b71d 100755 (executable)
@@ -62,4 +62,4 @@ PRIVATE>
 ! [ euler039 ] 100 ave-time
 ! 1 ms ave run time - 0.37 SD (100 trials)
 
-MAIN: euler039
+SOLUTION: euler039
index 6b8a3f267ac59321573886fdb00bc5e0e180ff5d..86fb34629e03ba974b1ff85eb7eb975638d86306 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.parser sequences strings ;
+USING: kernel math math.parser sequences strings project-euler.common ;
 IN: project-euler.040
 
 ! http://projecteuler.net/index.php?section=problems&id=40
@@ -48,4 +48,4 @@ PRIVATE>
 ! [ euler040 ] 100 ave-time
 ! 444 ms ave run time - 23.64 SD (100 trials)
 
-MAIN: euler040
+SOLUTION: euler040
index d6d428a11f5a191c1440d1e70ad90e51771bebca..751ddd345052beddbdbd871a29fef2e55bf1a7d1 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math.combinatorics math.parser math.primes sequences ;
+USING: kernel math.combinatorics math.parser math.primes sequences project-euler.common ;
 IN: project-euler.041
 
 ! http://projecteuler.net/index.php?section=problems&id=41
@@ -37,4 +37,4 @@ IN: project-euler.041
 ! [ euler041 ] 100 ave-time
 ! 64 ms ave run time - 4.22 SD (100 trials)
 
-MAIN: euler041
+SOLUTION: euler041
index c8236db1185c2de5332ebd26fcdc91d2005669f1..8c74cc9b312a0ee67e23d2714f0e59b7cb850a34 100644 (file)
@@ -71,4 +71,4 @@ PRIVATE>
 ! [ euler042a ] 100 ave-time
 ! 21 ms ave run time - 2.2 SD (100 trials)
 
-MAIN: euler042a
+SOLUTION: euler042a
index 21e9ec8e60c1024facd98e59c137fb831eb44e61..75241499e11fc90387fd3944d4ec2c3b68f33fd4 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators.short-circuit kernel math math.combinatorics math.parser
-    math.ranges project-euler.common sequences sets sorting ;
+USING: combinators.short-circuit kernel math math.functions math.combinatorics
+    math.parser math.ranges project-euler.common sequences sets sorting ;
 IN: project-euler.043
 
 ! http://projecteuler.net/index.php?section=problems&id=43
@@ -36,7 +36,7 @@ IN: project-euler.043
 <PRIVATE
 
 : subseq-divisible? ( n index seq -- ? )
-    [ 1- dup 3 + ] dip subseq 10 digits>integer swap mod zero? ;
+    [ 1- dup 3 + ] dip subseq 10 digits>integer swap divisor? ;
 
 : interesting? ( seq -- ? )
     {
@@ -97,4 +97,4 @@ PRIVATE>
 ! [ euler043a ] 100 ave-time
 ! 10 ms ave run time - 1.37 SD (100 trials)
 
-MAIN: euler043a
+SOLUTION: euler043a
index 46b20253ee48392458b80a3c2f63e88dcbe6a9e5..8fc979e8bcf3257627b4d07723c69be91aa24afd 100644 (file)
@@ -45,4 +45,4 @@ PRIVATE>
 
 ! TODO: this solution is ugly and not very efficient...find a better algorithm
 
-MAIN: euler044
+SOLUTION: euler044
index ca5cd83f41aba82ca15d84e5c34a3e8fc713f7a5..939b8416bb3b9083f0c7e5509d82aba37c02fb0e 100644 (file)
@@ -46,4 +46,4 @@ PRIVATE>
 ! [ euler045 ] 100 ave-time
 ! 12 ms ave run time - 1.71 SD (100 trials)
 
-MAIN: euler045
+SOLUTION: euler045
index b5ff6a9b816c2a884137658acbb1690592d26b8e..e4b8dcc955518ad86bf8f71bfbed1b4457574b3c 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions math.primes math.ranges sequences ;
+USING: kernel math math.functions math.primes math.ranges sequences project-euler.common ;
 IN: project-euler.046
 
 ! http://projecteuler.net/index.php?section=problems&id=46
@@ -49,4 +49,4 @@ PRIVATE>
 ! [ euler046 ] 100 ave-time
 ! 37 ms ave run time - 3.39 SD (100 trials)
 
-MAIN: euler046
+SOLUTION: euler046
index 9caaa8776f79c28e445d2db4b099f14d934ebbc9..e251045cd4d324970f692564e36237ba4cd031e4 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays kernel math math.primes math.primes.factors
-    math.ranges namespaces sequences ;
+    math.ranges namespaces sequences project-euler.common ;
 IN: project-euler.047
 
 ! http://projecteuler.net/index.php?section=problems&id=47
@@ -93,4 +93,4 @@ PRIVATE>
 ! TODO: I don't like that you have to specify the upper bound, maybe try making
 ! this lazy so it could also short-circuit when it finds the answer?
 
-MAIN: euler047a
+SOLUTION: euler047a
index baa1a430e86ed9d8374e3fc535f0984867c9cfc1..e56b9e9548bd99a70e19e4262234e9b183b6b3ce 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions sequences ;
+USING: kernel math math.functions sequences project-euler.common ;
 IN: project-euler.048
 
 ! http://projecteuler.net/index.php?section=problems&id=48
@@ -22,4 +22,4 @@ IN: project-euler.048
 ! [ euler048 ] 100 ave-time
 ! 276 ms run / 1 ms GC ave time - 100 trials
 
-MAIN: euler048
+SOLUTION: euler048
diff --git a/extra/project-euler/049/049-tests.factor b/extra/project-euler/049/049-tests.factor
new file mode 100644 (file)
index 0000000..679647a
--- /dev/null
@@ -0,0 +1,4 @@
+USING: project-euler.049 tools.test ;
+IN: project-euler.049.tests
+
+[ 296962999629 ] [ euler049 ] unit-test
diff --git a/extra/project-euler/049/049.factor b/extra/project-euler/049/049.factor
new file mode 100644 (file)
index 0000000..15dd7ed
--- /dev/null
@@ -0,0 +1,74 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays byte-arrays fry hints kernel math math.combinatorics
+    math.functions math.parser math.primes project-euler.common sequences sets ;
+IN: project-euler.049
+
+! http://projecteuler.net/index.php?section=problems&id=49
+
+! DESCRIPTION
+! -----------
+
+! The arithmetic sequence, 1487, 4817, 8147, in which each of the terms
+! increases by 3330, is unusual in two ways: (i) each of the three terms are
+! prime, and, (ii) each of the 4-digit numbers are permutations of one another.
+
+! There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes,
+! exhibiting this property, but there is one other 4-digit increasing sequence.
+
+! What 12-digit number do you form by concatenating the three terms in this
+! sequence?
+
+
+! SOLUTION
+! --------
+
+<PRIVATE
+
+: count-digits ( n -- byte-array )
+    10 <byte-array> [
+        '[ 10 /mod _ [ 1+ ] change-nth dup 0 > ] loop drop
+    ] keep ;
+
+HINTS: count-digits fixnum ;
+
+: permutations? ( n m -- ? )
+    [ count-digits ] bi@ = ;
+
+: collect-permutations ( seq -- seq )
+    [ V{ } clone ] [ dup ] bi* [
+        dupd '[ _ permutations? ] filter
+        [ diff ] keep pick push
+    ] each drop ;
+
+: potential-sequences ( -- seq )
+    1000 9999 primes-between
+    collect-permutations [ length 3 >= ] filter ;
+
+: arithmetic-terms ( m n -- seq )
+    2dup [ swap - ] keep + 3array ;
+
+: (find-unusual-terms) ( n seq -- seq/f )
+    [ [ arithmetic-terms ] with map ] keep
+    '[ _ [ peek ] dip member? ] find nip ;
+
+: find-unusual-terms ( seq -- seq/? )
+    unclip-slice over (find-unusual-terms) [
+        nip
+    ] [
+        dup length 3 >= [ find-unusual-terms ] [ drop f ] if
+    ] if* ;
+
+: 4digit-concat ( seq -- str )
+    0 [ [ 10000 * ] dip + ] reduce ;
+
+PRIVATE>
+
+: euler049 ( -- answer )
+    potential-sequences [ find-unusual-terms ] map sift
+    [ { 1487 4817 8147 } = not ] find nip 4digit-concat ;
+
+! [ euler049 ] 100 ave-time
+! 206 ms ave run time - 10.25 SD (100 trials)
+
+SOLUTION: euler049
index f8ce68d17396d6056a81afd52903c63cbfd660a2..0c5b288b658c0424304553755b1d68b9a5b2fce1 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel locals math math.primes sequences ;
+USING: arrays kernel locals math math.primes sequences project-euler.common ;
 IN: project-euler.050
 
 ! http://projecteuler.net/index.php?section=problems&id=50
@@ -87,4 +87,4 @@ PRIVATE>
 ! [ euler050 ] 100 ave-time
 ! 291 ms run / 20.6 ms GC ave time - 100 trials
 
-MAIN: euler050
+SOLUTION: euler050
index 6245a794af257dfd4f3b46b3970b8076b192521e..c25b1adcc073c3c7e2cdbd100af456307bc58bc9 100644 (file)
@@ -1,8 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators.short-circuit kernel math
-    project-euler.common sequences sorting
-    grouping ;
+USING: combinators.short-circuit kernel math math.functions
+    project-euler.common sequences sorting grouping ;
 IN: project-euler.052
 
 ! http://projecteuler.net/index.php?section=problems&id=52
@@ -31,7 +30,7 @@ IN: project-euler.052
     [ number>digits natural-sort ] map all-equal? ;
 
 : candidate? ( n -- ? )
-    { [ odd? ] [ 3 mod 0 = ] } 1&& ;
+    { [ odd? ] [ 3 divisor? ] } 1&& ;
 
 : next-all-same ( x n -- n )
     dup candidate? [
@@ -49,4 +48,4 @@ PRIVATE>
 ! [ euler052 ] 100 ave-time
 ! 92 ms ave run time - 6.29 SD (100 trials)
 
-MAIN: euler052
+SOLUTION: euler052
index d264bca4bff1a8b80a174551976c15aa2de98f52..111b8147fb59807cb18c03ec2e8234b92891e0e8 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.combinatorics math.ranges sequences ;
+USING: kernel math math.combinatorics math.ranges sequences project-euler.common ;
 IN: project-euler.053
 
 ! http://projecteuler.net/index.php?section=problems&id=53
@@ -32,4 +32,4 @@ IN: project-euler.053
 ! [ euler053 ] 100 ave-time
 ! 52 ms ave run time - 4.44 SD (100 trials)
 
-MAIN: euler053
+SOLUTION: euler053
diff --git a/extra/project-euler/054/054-tests.factor b/extra/project-euler/054/054-tests.factor
new file mode 100644 (file)
index 0000000..31e915c
--- /dev/null
@@ -0,0 +1,4 @@
+USING: project-euler.054 tools.test ;
+IN: project-euler.054.tests
+
+[ 376 ] [ euler054 ] unit-test
diff --git a/extra/project-euler/054/054.factor b/extra/project-euler/054/054.factor
new file mode 100644 (file)
index 0000000..5cf4273
--- /dev/null
@@ -0,0 +1,84 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays io.encodings.ascii io.files kernel math.order poker
+    project-euler.common sequences ;
+IN: project-euler.054
+
+! http://projecteuler.net/index.php?section=problems&id=54
+
+! DESCRIPTION
+! -----------
+
+! In the card game poker, a hand consists of five cards and are ranked, from
+! lowest to highest, in the following way:
+
+!     * High Card: Highest value card.
+!     * One Pair: Two cards of the same value.
+!     * Two Pairs: Two different pairs.
+!     * Three of a Kind: Three cards of the same value.
+!     * Straight: All cards are consecutive values.
+!     * Flush: All cards of the same suit.
+!     * Full House: Three of a kind and a pair.
+!     * Four of a Kind: Four cards of the same value.
+!     * Straight Flush: All cards are consecutive values of same suit.
+!     * Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
+
+! The cards are valued in the order:
+!     2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
+
+! If two players have the same ranked hands then the rank made up of the
+! highest value wins; for example, a pair of eights beats a pair of fives (see
+! example 1 below). But if two ranks tie, for example, both players have a pair
+! of queens, then highest cards in each hand are compared (see example 4
+! below); if the highest cards tie then the next highest cards are compared,
+! and so on.
+
+! Consider the following five hands dealt to two players:
+
+!     Hand   Player 1            Player 2              Winner
+!     ---------------------------------------------------------
+!     1      5H 5C 6S 7S KD      2C 3S 8S 8D TD
+!            Pair of Fives       Pair of Eights        Player 2
+
+!     2      5D 8C 9S JS AC      2C 5C 7D 8S QH
+!            Highest card Ace    Highest card Queen    Player 1
+
+!     3      2D 9C AS AH AC      3D 6D 7D TD QD
+!            Three Aces          Flush with Diamonds   Player 2
+
+!     4      4D 6S 9H QH QC      3D 6D 7H QD QS
+!            Pair of Queens      Pair of Queens
+!            Highest card Nine   Highest card Seven    Player 1
+
+!     5      2H 2D 4C 4D 4S      3C 3D 3S 9S 9D
+!            Full House          Full House
+!            With Three Fours    With Three Threes     Player 1
+
+! The file, poker.txt, contains one-thousand random hands dealt to two players.
+! Each line of the file contains ten cards (separated by a single space): the
+! first five are Player 1's cards and the last five are Player 2's cards. You
+! can assume that all hands are valid (no invalid characters or repeated
+! cards), each player's hand is in no specific order, and in each hand there is
+! a clear winner.
+
+! How many hands does Player 1 win?
+
+
+! SOLUTION
+! --------
+
+<PRIVATE
+
+: source-054 ( -- seq )
+    "resource:extra/project-euler/054/poker.txt" ascii file-lines
+    [ [ 14 head-slice ] [ 14 tail-slice* ] bi 2array ] map ;
+
+PRIVATE>
+
+: euler054 ( -- answer )
+    source-054 [ [ <hand> ] map first2 before? ] count ;
+
+! [ euler054 ] 100 ave-time
+! 34 ms ave run time - 2.65 SD (100 trials)
+
+SOLUTION: euler054
diff --git a/extra/project-euler/054/poker.txt b/extra/project-euler/054/poker.txt
new file mode 100644 (file)
index 0000000..231e249
--- /dev/null
@@ -0,0 +1,1000 @@
+8C TS KC 9H 4S 7D 2S 5D 3S AC\r
+5C AD 5D AC 9C 7C 5H 8D TD KS\r
+3H 7H 6S KC JS QH TD JC 2D 8S\r
+TH 8H 5C QS TC 9H 4D JC KS JS\r
+7C 5H KC QH JD AS KH 4C AD 4S\r
+5H KS 9C 7D 9H 8D 3S 5D 5C AH\r
+6H 4H 5C 3H 2H 3S QH 5S 6S AS\r
+TD 8C 4H 7C TC KC 4C 3H 7S KS\r
+7C 9C 6D KD 3H 4C QS QC AC KH\r
+JC 6S 5H 2H 2D KD 9D 7C AS JS\r
+AD QH TH 9D 8H TS 6D 3S AS AC\r
+2H 4S 5C 5S TC KC JD 6C TS 3C\r
+QD AS 6H JS 2C 3D 9H KC 4H 8S\r
+KD 8S 9S 7C 2S 3S 6D 6S 4H KC\r
+3C 8C 2D 7D 4D 9S 4S QH 4H JD\r
+8C KC 7S TC 2D TS 8H QD AC 5C\r
+3D KH QD 6C 6S AD AS 8H 2H QS\r
+6S 8D 4C 8S 6C QH TC 6D 7D 9D\r
+2S 8D 8C 4C TS 9S 9D 9C AC 3D\r
+3C QS 2S 4H JH 3D 2D TD 8S 9H\r
+5H QS 8S 6D 3C 8C JD AS 7H 7D\r
+6H TD 9D AS JH 6C QC 9S KD JC\r
+AH 8S QS 4D TH AC TS 3C 3D 5C\r
+5S 4D JS 3D 8H 6C TS 3S AD 8C\r
+6D 7C 5D 5H 3S 5C JC 2H 5S 3D\r
+5H 6H 2S KS 3D 5D JD 7H JS 8H\r
+KH 4H AS JS QS QC TC 6D 7C KS\r
+3D QS TS 2H JS 4D AS 9S JC KD\r
+QD 5H 4D 5D KH 7H 3D JS KD 4H\r
+2C 9H 6H 5C 9D 6C JC 2D TH 9S\r
+7D 6D AS QD JH 4D JS 7C QS 5C\r
+3H KH QD AD 8C 8H 3S TH 9D 5S\r
+AH 9S 4D 9D 8S 4H JS 3C TC 8D\r
+2C KS 5H QD 3S TS 9H AH AD 8S\r
+5C 7H 5D KD 9H 4D 3D 2D KS AD\r
+KS KC 9S 6D 2C QH 9D 9H TS TC\r
+9C 6H 5D QH 4D AD 6D QC JS KH\r
+9S 3H 9D JD 5C 4D 9H AS TC QH\r
+2C 6D JC 9C 3C AD 9S KH 9D 7D\r
+KC 9C 7C JC JS KD 3H AS 3C 7D\r
+QD KH QS 2C 3S 8S 8H 9H 9C JC\r
+QH 8D 3C KC 4C 4H 6D AD 9H 9D\r
+3S KS QS 7H KH 7D 5H 5D JD AD\r
+2H 2C 6H TH TC 7D 8D 4H 8C AS\r
+4S 2H AC QC 3S 6D TH 4D 4C KH\r
+4D TC KS AS 7C 3C 6D 2D 9H 6C\r
+8C TD 5D QS 2C 7H 4C 9C 3H 9H\r
+5H JH TS 7S TD 6H AD QD 8H 8S\r
+5S AD 9C 8C 7C 8D 5H 9D 8S 2S\r
+4H KH KS 9S 2S KC 5S AD 4S 7D\r
+QS 9C QD 6H JS 5D AC 8D 2S AS\r
+KH AC JC 3S 9D 9S 3C 9C 5S JS\r
+AD 3C 3D KS 3S 5C 9C 8C TS 4S\r
+JH 8D 5D 6H KD QS QD 3D 6C KC\r
+8S JD 6C 3S 8C TC QC 3C QH JS\r
+KC JC 8H 2S 9H 9C JH 8S 8C 9S\r
+8S 2H QH 4D QC 9D KC AS TH 3C\r
+8S 6H TH 7C 2H 6S 3C 3H AS 7S\r
+QH 5S JS 4H 5H TS 8H AH AC JC\r
+9D 8H 2S 4S TC JC 3C 7H 3H 5C\r
+3D AD 3C 3S 4C QC AS 5D TH 8C\r
+6S 9D 4C JS KH AH TS JD 8H AD\r
+4C 6S 9D 7S AC 4D 3D 3S TC JD\r
+AD 7H 6H 4H JH KC TD TS 7D 6S\r
+8H JH TC 3S 8D 8C 9S 2C 5C 4D\r
+2C 9D KC QH TH QS JC 9C 4H TS\r
+QS 3C QD 8H KH 4H 8D TD 8S AC\r
+7C 3C TH 5S 8H 8C 9C JD TC KD\r
+QC TC JD TS 8C 3H 6H KD 7C TD\r
+JH QS KS 9C 6D 6S AS 9H KH 6H\r
+2H 4D AH 2D JH 6H TD 5D 4H JD\r
+KD 8C 9S JH QD JS 2C QS 5C 7C\r
+4S TC 7H 8D 2S 6H 7S 9C 7C KC\r
+8C 5D 7H 4S TD QC 8S JS 4H KS\r
+AD 8S JH 6D TD KD 7C 6C 2D 7D\r
+JC 6H 6S JS 4H QH 9H AH 4C 3C\r
+6H 5H AS 7C 7S 3D KH KC 5D 5C\r
+JC 3D TD AS 4D 6D 6S QH JD KS\r
+8C 7S 8S QH 2S JD 5C 7H AH QD\r
+8S 3C 6H 6C 2C 8D TD 7D 4C 4D\r
+5D QH KH 7C 2S 7H JS 6D QC QD\r
+AD 6C 6S 7D TH 6H 2H 8H KH 4H\r
+KS JS KD 5D 2D KH 7D 9C 8C 3D\r
+9C 6D QD 3C KS 3S 7S AH JD 2D\r
+AH QH AS JC 8S 8H 4C KC TH 7D\r
+JC 5H TD 7C 5D KD 4C AD 8H JS\r
+KC 2H AC AH 7D JH KH 5D 7S 6D\r
+9S 5S 9C 6H 8S TD JD 9H 6C AC\r
+7D 8S 6D TS KD 7H AC 5S 7C 5D\r
+AH QC JC 4C TC 8C 2H TS 2C 7D\r
+KD KC 6S 3D 7D 2S 8S 3H 5S 5C\r
+8S 5D 8H 4C 6H KC 3H 7C 5S KD\r
+JH 8C 3D 3C 6C KC TD 7H 7C 4C\r
+JC KC 6H TS QS TD KS 8H 8C 9S\r
+6C 5S 9C QH 7D AH KS KC 9S 2C\r
+4D 4S 8H TD 9C 3S 7D 9D AS TH\r
+6S 7D 3C 6H 5D KD 2C 5C 9D 9C\r
+2H KC 3D AD 3H QD QS 8D JC 4S\r
+8C 3H 9C 7C AD 5D JC 9D JS AS\r
+5D 9H 5C 7H 6S 6C QC JC QD 9S\r
+JC QS JH 2C 6S 9C QC 3D 4S TC\r
+4H 5S 8D 3D 4D 2S KC 2H JS 2C\r
+TD 3S TH KD 4D 7H JH JS KS AC\r
+7S 8C 9S 2D 8S 7D 5C AD 9D AS\r
+8C 7H 2S 6C TH 3H 4C 3S 8H AC\r
+KD 5H JC 8H JD 2D 4H TD JH 5C\r
+3D AS QH KS 7H JD 8S 5S 6D 5H\r
+9S 6S TC QS JC 5C 5D 9C TH 8C\r
+5H 3S JH 9H 2S 2C 6S 7S AS KS\r
+8C QD JC QS TC QC 4H AC KH 6C\r
+TC 5H 7D JH 4H 2H 8D JC KS 4D\r
+5S 9C KH KD 9H 5C TS 3D 7D 2D\r
+5H AS TC 4D 8C 2C TS 9D 3H 8D\r
+6H 8D 2D 9H JD 6C 4S 5H 5S 6D\r
+AD 9C JC 7D 6H 9S 6D JS 9H 3C\r
+AD JH TC QS 4C 5D 9S 7C 9C AH\r
+KD 6H 2H TH 8S QD KS 9D 9H AS\r
+4H 8H 8D 5H 6C AH 5S AS AD 8S\r
+QS 5D 4S 2H TD KS 5H AC 3H JC\r
+9C 7D QD KD AC 6D 5H QH 6H 5S\r
+KC AH QH 2H 7D QS 3H KS 7S JD\r
+6C 8S 3H 6D KS QD 5D 5C 8H TC\r
+9H 4D 4S 6S 9D KH QC 4H 6C JD\r
+TD 2D QH 4S 6H JH KD 3C QD 8C\r
+4S 6H 7C QD 9D AS AH 6S AD 3C\r
+2C KC TH 6H 8D AH 5C 6D 8S 5D\r
+TD TS 7C AD JC QD 9H 3C KC 7H\r
+5D 4D 5S 8H 4H 7D 3H JD KD 2D\r
+JH TD 6H QS 4S KD 5C 8S 7D 8H\r
+AC 3D AS 8C TD 7H KH 5D 6C JD\r
+9D KS 7C 6D QH TC JD KD AS KC\r
+JH 8S 5S 7S 7D AS 2D 3D AD 2H\r
+2H 5D AS 3C QD KC 6H 9H 9S 2C\r
+9D 5D TH 4C JH 3H 8D TC 8H 9H\r
+6H KD 2C TD 2H 6C 9D 2D JS 8C\r
+KD 7S 3C 7C AS QH TS AD 8C 2S\r
+QS 8H 6C JS 4C 9S QC AD TD TS\r
+2H 7C TS TC 8C 3C 9H 2D 6D JC\r
+TC 2H 8D JH KS 6D 3H TD TH 8H\r
+9D TD 9H QC 5D 6C 8H 8C KC TS\r
+2H 8C 3D AH 4D TH TC 7D 8H KC\r
+TS 5C 2D 8C 6S KH AH 5H 6H KC\r
+5S 5D AH TC 4C JD 8D 6H 8C 6C\r
+KC QD 3D 8H 2D JC 9H 4H AD 2S\r
+TD 6S 7D JS KD 4H QS 2S 3S 8C\r
+4C 9H JH TS 3S 4H QC 5S 9S 9C\r
+2C KD 9H JS 9S 3H JC TS 5D AC\r
+AS 2H 5D AD 5H JC 7S TD JS 4C\r
+2D 4S 8H 3D 7D 2C AD KD 9C TS\r
+7H QD JH 5H JS AC 3D TH 4C 8H\r
+6D KH KC QD 5C AD 7C 2D 4H AC\r
+3D 9D TC 8S QD 2C JC 4H JD AH\r
+6C TD 5S TC 8S AH 2C 5D AS AC\r
+TH 7S 3D AS 6C 4C 7H 7D 4H AH\r
+5C 2H KS 6H 7S 4H 5H 3D 3C 7H\r
+3C 9S AC 7S QH 2H 3D 6S 3S 3H\r
+2D 3H AS 2C 6H TC JS 6S 9C 6C\r
+QH KD QD 6D AC 6H KH 2C TS 8C\r
+8H 7D 3S 9H 5D 3H 4S QC 9S 5H\r
+2D 9D 7H 6H 3C 8S 5H 4D 3S 4S\r
+KD 9S 4S TC 7S QC 3S 8S 2H 7H\r
+TC 3D 8C 3H 6C 2H 6H KS KD 4D\r
+KC 3D 9S 3H JS 4S 8H 2D 6C 8S\r
+6H QS 6C TC QD 9H 7D 7C 5H 4D\r
+TD 9D 8D 6S 6C TC 5D TS JS 8H\r
+4H KC JD 9H TC 2C 6S 5H 8H AS\r
+JS 9C 5C 6S 9D JD 8H KC 4C 6D\r
+4D 8D 8S 6C 7C 6H 7H 8H 5C KC\r
+TC 3D JC 6D KS 9S 6H 7S 9C 2C\r
+6C 3S KD 5H TS 7D 9H 9S 6H KH\r
+3D QD 4C 6H TS AC 3S 5C 2H KD\r
+4C AS JS 9S 7C TS 7H 9H JC KS\r
+4H 8C JD 3H 6H AD 9S 4S 5S KS\r
+4C 2C 7D 3D AS 9C 2S QS KC 6C\r
+8S 5H 3D 2S AC 9D 6S 3S 4D TD\r
+QD TH 7S TS 3D AC 7H 6C 5D QC\r
+TC QD AD 9C QS 5C 8D KD 3D 3C\r
+9D 8H AS 3S 7C 8S JD 2D 8D KC\r
+4C TH AC QH JS 8D 7D 7S 9C KH\r
+9D 8D 4C JH 2C 2S QD KD TS 4H\r
+4D 6D 5D 2D JH 3S 8S 3H TC KH\r
+AD 4D 2C QS 8C KD JH JD AH 5C\r
+5C 6C 5H 2H JH 4H KS 7C TC 3H\r
+3C 4C QC 5D JH 9C QD KH 8D TC\r
+3H 9C JS 7H QH AS 7C 9H 5H JC\r
+2D 5S QD 4S 3C KC 6S 6C 5C 4C\r
+5D KH 2D TS 8S 9C AS 9S 7C 4C\r
+7C AH 8C 8D 5S KD QH QS JH 2C\r
+8C 9D AH 2H AC QC 5S 8H 7H 2C\r
+QD 9H 5S QS QC 9C 5H JC TH 4H\r
+6C 6S 3H 5H 3S 6H KS 8D AC 7S\r
+AC QH 7H 8C 4S KC 6C 3D 3S TC\r
+9D 3D JS TH AC 5H 3H 8S 3S TC\r
+QD KH JS KS 9S QC 8D AH 3C AC\r
+5H 6C KH 3S 9S JH 2D QD AS 8C\r
+6C 4D 7S 7H 5S JC 6S 9H 4H JH\r
+AH 5S 6H 9S AD 3S TH 2H 9D 8C\r
+4C 8D 9H 7C QC AD 4S 9C KC 5S\r
+9D 6H 4D TC 4C JH 2S 5D 3S AS\r
+2H 6C 7C KH 5C AD QS TH JD 8S\r
+3S 4S 7S AH AS KC JS 2S AD TH\r
+JS KC 2S 7D 8C 5C 9C TS 5H 9D\r
+7S 9S 4D TD JH JS KH 6H 5D 2C\r
+JD JS JC TH 2D 3D QD 8C AC 5H\r
+7S KH 5S 9D 5D TD 4S 6H 3C 2D\r
+4S 5D AC 8D 4D 7C AD AS AH 9C\r
+6S TH TS KS 2C QC AH AS 3C 4S\r
+2H 8C 3S JC 5C 7C 3H 3C KH JH\r
+7S 3H JC 5S 6H 4C 2S 4D KC 7H\r
+4D 7C 4H 9S 8S 6S AD TC 6C JC\r
+KH QS 3S TC 4C 8H 8S AC 3C TS\r
+QD QS TH 3C TS 7H 7D AH TD JC\r
+TD JD QC 4D 9S 7S TS AD 7D AC\r
+AH 7H 4S 6D 7C 2H 9D KS JC TD\r
+7C AH JD 4H 6D QS TS 2H 2C 5C\r
+TC KC 8C 9S 4C JS 3C JC 6S AH\r
+AS 7D QC 3D 5S JC JD 9D TD KH\r
+TH 3C 2S 6H AH AC 5H 5C 7S 8H\r
+QC 2D AC QD 2S 3S JD QS 6S 8H\r
+KC 4H 3C 9D JS 6H 3S 8S AS 8C\r
+7H KC 7D JD 2H JC QH 5S 3H QS\r
+9H TD 3S 8H 7S AC 5C 6C AH 7C\r
+8D 9H AH JD TD QS 7D 3S 9C 8S\r
+AH QH 3C JD KC 4S 5S 5D TD KS\r
+9H 7H 6S JH TH 4C 7C AD 5C 2D\r
+7C KD 5S TC 9D 6S 6C 5D 2S TH\r
+KC 9H 8D 5H 7H 4H QC 3D 7C AS\r
+6S 8S QC TD 4S 5C TH QS QD 2S\r
+8S 5H TH QC 9H 6S KC 7D 7C 5C\r
+7H KD AH 4D KH 5C 4S 2D KC QH\r
+6S 2C TD JC AS 4D 6C 8C 4H 5S\r
+JC TC JD 5S 6S 8D AS 9D AD 3S\r
+6D 6H 5D 5S TC 3D 7D QS 9D QD\r
+4S 6C 8S 3S 7S AD KS 2D 7D 7C\r
+KC QH JC AC QD 5D 8D QS 7H 7D\r
+JS AH 8S 5H 3D TD 3H 4S 6C JH\r
+4S QS 7D AS 9H JS KS 6D TC 5C\r
+2D 5C 6H TC 4D QH 3D 9H 8S 6C\r
+6D 7H TC TH 5S JD 5C 9C KS KD\r
+8D TD QH 6S 4S 6C 8S KC 5C TC\r
+5S 3D KS AC 4S 7D QD 4C TH 2S\r
+TS 8H 9S 6S 7S QH 3C AH 7H 8C\r
+4C 8C TS JS QC 3D 7D 5D 7S JH\r
+8S 7S 9D QC AC 7C 6D 2H JH KC\r
+JS KD 3C 6S 4S 7C AH QC KS 5H\r
+KS 6S 4H JD QS TC 8H KC 6H AS\r
+KH 7C TC 6S TD JC 5C 7D AH 3S\r
+3H 4C 4H TC TH 6S 7H 6D 9C QH\r
+7D 5H 4S 8C JS 4D 3D 8S QH KC\r
+3H 6S AD 7H 3S QC 8S 4S 7S JS\r
+3S JD KH TH 6H QS 9C 6C 2D QD\r
+4S QH 4D 5H KC 7D 6D 8D TH 5S\r
+TD AD 6S 7H KD KH 9H 5S KC JC\r
+3H QC AS TS 4S QD KS 9C 7S KC\r
+TS 6S QC 6C TH TC 9D 5C 5D KD\r
+JS 3S 4H KD 4C QD 6D 9S JC 9D\r
+8S JS 6D 4H JH 6H 6S 6C KS KH\r
+AC 7D 5D TC 9S KH 6S QD 6H AS\r
+AS 7H 6D QH 8D TH 2S KH 5C 5H\r
+4C 7C 3D QC TC 4S KH 8C 2D JS\r
+6H 5D 7S 5H 9C 9H JH 8S TH 7H\r
+AS JS 2S QD KH 8H 4S AC 8D 8S\r
+3H 4C TD KD 8C JC 5C QS 2D JD\r
+TS 7D 5D 6C 2C QS 2H 3C AH KS\r
+4S 7C 9C 7D JH 6C 5C 8H 9D QD\r
+2S TD 7S 6D 9C 9S QS KH QH 5C\r
+JC 6S 9C QH JH 8D 7S JS KH 2H\r
+8D 5H TH KC 4D 4S 3S 6S 3D QS\r
+2D JD 4C TD 7C 6D TH 7S JC AH\r
+QS 7S 4C TH 9D TS AD 4D 3H 6H\r
+2D 3H 7D JD 3D AS 2S 9C QC 8S\r
+4H 9H 9C 2C 7S JH KD 5C 5D 6H\r
+TC 9H 8H JC 3C 9S 8D KS AD KC\r
+TS 5H JD QS QH QC 8D 5D KH AH\r
+5D AS 8S 6S 4C AH QC QD TH 7H\r
+3H 4H 7D 6S 4S 9H AS 8H JS 9D\r
+JD 8C 2C 9D 7D 5H 5S 9S JC KD\r
+KD 9C 4S QD AH 7C AD 9D AC TD\r
+6S 4H 4S 9C 8D KS TC 9D JH 7C\r
+5S JC 5H 4S QH AC 2C JS 2S 9S\r
+8C 5H AS QD AD 5C 7D 8S QC TD\r
+JC 4C 8D 5C KH QS 4D 6H 2H 2C\r
+TH 4S 2D KC 3H QD AC 7H AD 9D\r
+KH QD AS 8H TH KC 8D 7S QH 8C\r
+JC 6C 7D 8C KH AD QS 2H 6S 2D\r
+JC KH 2D 7D JS QC 5H 4C 5D AD\r
+TS 3S AD 4S TD 2D TH 6S 9H JH\r
+9H 2D QS 2C 4S 3D KH AS AC 9D\r
+KH 6S 8H 4S KD 7D 9D TS QD QC\r
+JH 5H AH KS AS AD JC QC 5S KH\r
+5D 7D 6D KS KD 3D 7C 4D JD 3S\r
+AC JS 8D 5H 9C 3H 4H 4D TS 2C\r
+6H KS KH 9D 7C 2S 6S 8S 2H 3D\r
+6H AC JS 7S 3S TD 8H 3H 4H TH\r
+9H TC QC KC 5C KS 6H 4H AC 8S\r
+TC 7D QH 4S JC TS 6D 6C AC KH\r
+QH 7D 7C JH QS QD TH 3H 5D KS\r
+3D 5S 8D JS 4C 2C KS 7H 9C 4H\r
+5H 8S 4H TD 2C 3S QD QC 3H KC\r
+QC JS KD 9C AD 5S 9D 7D 7H TS\r
+8C JC KH 7C 7S 6C TS 2C QD TH\r
+5S 9D TH 3C 7S QH 8S 9C 2H 5H\r
+5D 9H 6H 2S JS KH 3H 7C 2H 5S\r
+JD 5D 5S 2C TC 2S 6S 6C 3C 8S\r
+4D KH 8H 4H 2D KS 3H 5C 2S 9H\r
+3S 2D TD 7H 8S 6H JD KC 9C 8D\r
+6S QD JH 7C 9H 5H 8S 8H TH TD\r
+QS 7S TD 7D TS JC KD 7C 3C 2C\r
+3C JD 8S 4H 2D 2S TD AS 4D AC\r
+AH KS 6C 4C 4S 7D 8C 9H 6H AS\r
+5S 3C 9S 2C QS KD 4D 4S AC 5D\r
+2D TS 2C JS KH QH 5D 8C AS KC\r
+KD 3H 6C TH 8S 7S KH 6H 9S AC\r
+6H 7S 6C QS AH 2S 2H 4H 5D 5H\r
+5H JC QD 2C 2S JD AS QC 6S 7D\r
+6C TC AS KD 8H 9D 2C 7D JH 9S\r
+2H 4C 6C AH 8S TD 3H TH 7C TS\r
+KD 4S TS 6C QH 8D 9D 9C AH 7D\r
+6D JS 5C QD QC 9C 5D 8C 2H KD\r
+3C QH JH AD 6S AH KC 8S 6D 6H\r
+3D 7C 4C 7S 5S 3S 6S 5H JC 3C\r
+QH 7C 5H 3C 3S 8C TS 4C KD 9C\r
+QD 3S 7S 5H 7H QH JC 7C 8C KD\r
+3C KD KH 2S 4C TS AC 6S 2C 7C\r
+2C KH 3C 4C 6H 4D 5H 5S 7S QD\r
+4D 7C 8S QD TS 9D KS 6H KD 3C\r
+QS 4D TS 7S 4C 3H QD 8D 9S TC\r
+TS QH AC 6S 3C 9H 9D QS 8S 6H\r
+3S 7S 5D 4S JS 2D 6C QH 6S TH\r
+4C 4H AS JS 5D 3D TS 9C AC 8S\r
+6S 9C 7C 3S 5C QS AD AS 6H 3C\r
+9S 8C 7H 3H 6S 7C AS 9H JD KH\r
+3D 3H 7S 4D 6C 7C AC 2H 9C TH\r
+4H 5S 3H AC TC TH 9C 9H 9S 8D\r
+8D 9H 5H 4D 6C 2H QD 6S 5D 3S\r
+4C 5C JD QS 4D 3H TH AC QH 8C\r
+QC 5S 3C 7H AD 4C KS 4H JD 6D\r
+QS AH 3H KS 9H 2S JS JH 5H 2H\r
+2H 5S TH 6S TS 3S KS 3C 5H JS\r
+2D 9S 7H 3D KC JH 6D 7D JS TD\r
+AC JS 8H 2C 8C JH JC 2D TH 7S\r
+5D 9S 8H 2H 3D TC AH JC KD 9C\r
+9D QD JC 2H 6D KH TS 9S QH TH\r
+2C 8D 4S JD 5H 3H TH TC 9C KC\r
+AS 3D 9H 7D 4D TH KH 2H 7S 3H\r
+4H 7S KS 2S JS TS 8S 2H QD 8D\r
+5S 6H JH KS 8H 2S QC AC 6S 3S\r
+JC AS AD QS 8H 6C KH 4C 4D QD\r
+2S 3D TS TD 9S KS 6S QS 5C 8D\r
+3C 6D 4S QC KC JH QD TH KH AD\r
+9H AH 4D KS 2S 8D JH JC 7C QS\r
+2D 6C TH 3C 8H QD QH 2S 3S KS\r
+6H 5D 9S 4C TS TD JS QD 9D JD\r
+5H 8H KH 8S KS 7C TD AD 4S KD\r
+2C 7C JC 5S AS 6C 7D 8S 5H 9C\r
+6S QD 9S TS KH QS 5S QH 3C KC\r
+7D 3H 3C KD 5C AS JH 7H 6H JD\r
+9D 5C 9H KC 8H KS 4S AD 4D 2S\r
+3S JD QD 8D 2S 7C 5S 6S 5H TS\r
+6D 9S KC TD 3S 6H QD JD 5C 8D\r
+5H 9D TS KD 8D 6H TD QC 4C 7D\r
+6D 4S JD 9D AH 9S AS TD 9H QD\r
+2D 5S 2H 9C 6H 9S TD QC 7D TC\r
+3S 2H KS TS 2C 9C 8S JS 9D 7D\r
+3C KC 6D 5D 6C 6H 8S AS 7S QS\r
+JH 9S 2H 8D 4C 8H 9H AD TH KH\r
+QC AS 2S JS 5C 6H KD 3H 7H 2C\r
+QD 8H 2S 8D 3S 6D AH 2C TC 5C\r
+JD JS TS 8S 3H 5D TD KC JC 6H\r
+6S QS TC 3H 5D AH JC 7C 7D 4H\r
+7C 5D 8H 9C 2H 9H JH KH 5S 2C\r
+9C 7H 6S TH 3S QC QD 4C AC JD\r
+2H 5D 9S 7D KC 3S QS 2D AS KH\r
+2S 4S 2H 7D 5C TD TH QH 9S 4D\r
+6D 3S TS 6H 4H KS 9D 8H 5S 2D\r
+9H KS 4H 3S 5C 5D KH 6H 6S JS\r
+KC AS 8C 4C JC KH QC TH QD AH\r
+6S KH 9S 2C 5H TC 3C 7H JC 4D\r
+JD 4S 6S 5S 8D 7H 7S 4D 4C 2H\r
+7H 9H 5D KH 9C 7C TS TC 7S 5H\r
+4C 8D QC TS 4S 9H 3D AD JS 7C\r
+8C QS 5C 5D 3H JS AH KC 4S 9D\r
+TS JD 8S QS TH JH KH 2D QD JS\r
+JD QC 5D 6S 9H 3S 2C 8H 9S TS\r
+2S 4C AD 7H JC 5C 2D 6D 4H 3D\r
+7S JS 2C 4H 8C AD QD 9C 3S TD\r
+JD TS 4C 6H 9H 7D QD 6D 3C AS\r
+AS 7C 4C 6S 5D 5S 5C JS QC 4S\r
+KD 6S 9S 7C 3C 5S 7D JH QD JS\r
+4S 7S JH 2C 8S 5D 7H 3D QH AD\r
+TD 6H 2H 8D 4H 2D 7C AD KH 5D\r
+TS 3S 5H 2C QD AH 2S 5C KH TD\r
+KC 4D 8C 5D AS 6C 2H 2S 9H 7C\r
+KD JS QC TS QS KH JH 2C 5D AD\r
+3S 5H KC 6C 9H 3H 2H AD 7D 7S\r
+7S JS JH KD 8S 7D 2S 9H 7C 2H\r
+9H 2D 8D QC 6S AD AS 8H 5H 6C\r
+2S 7H 6C 6D 7D 8C 5D 9D JC 3C\r
+7C 9C 7H JD 2H KD 3S KH AD 4S\r
+QH AS 9H 4D JD KS KD TS KH 5H\r
+4C 8H 5S 3S 3D 7D TD AD 7S KC\r
+JS 8S 5S JC 8H TH 9C 4D 5D KC\r
+7C 5S 9C QD 2C QH JS 5H 8D KH\r
+TD 2S KS 3D AD KC 7S TC 3C 5D\r
+4C 2S AD QS 6C 9S QD TH QH 5C\r
+8C AD QS 2D 2S KC JD KS 6C JC\r
+8D 4D JS 2H 5D QD 7S 7D QH TS\r
+6S 7H 3S 8C 8S 9D QS 8H 6C 9S\r
+4S TC 2S 5C QD 4D QS 6D TH 6S\r
+3S 5C 9D 6H 8D 4C 7D TC 7C TD\r
+AH 6S AS 7H 5S KD 3H 5H AC 4C\r
+8D 8S AH KS QS 2C AD 6H 7D 5D\r
+6H 9H 9S 2H QS 8S 9C 5D 2D KD\r
+TS QC 5S JH 7D 7S TH 9S 9H AC\r
+7H 3H 6S KC 4D 6D 5C 4S QD TS\r
+TD 2S 7C QD 3H JH 9D 4H 7S 7H\r
+KS 3D 4H 5H TC 2S AS 2D 6D 7D\r
+8H 3C 7H TD 3H AD KC TH 9C KH\r
+TC 4C 2C 9S 9D 9C 5C 2H JD 3C\r
+3H AC TS 5D AD 8D 6H QC 6S 8C\r
+2S TS 3S JD 7H 8S QH 4C 5S 8D\r
+AC 4S 6C 3C KH 3D 7C 2D 8S 2H\r
+4H 6C 8S TH 2H 4S 8H 9S 3H 7S\r
+7C 4C 9C 2C 5C AS 5D KD 4D QH\r
+9H 4H TS AS 7D 8D 5D 9S 8C 2H\r
+QC KD AC AD 2H 7S AS 3S 2D 9S\r
+2H QC 8H TC 6D QD QS 5D KH 3C\r
+TH JD QS 4C 2S 5S AD 7H 3S AS\r
+7H JS 3D 6C 3S 6D AS 9S AC QS\r
+9C TS AS 8C TC 8S 6H 9D 8D 6C\r
+4D JD 9C KC 7C 6D KS 3S 8C AS\r
+3H 6S TC 8D TS 3S KC 9S 7C AS\r
+8C QC 4H 4S 8S 6C 3S TC AH AC\r
+4D 7D 5C AS 2H 6S TS QC AD TC\r
+QD QC 8S 4S TH 3D AH TS JH 4H\r
+5C 2D 9S 2C 3H 3C 9D QD QH 7D\r
+KC 9H 6C KD 7S 3C 4D AS TC 2D\r
+3D JS 4D 9D KS 7D TH QC 3H 3C\r
+8D 5S 2H 9D 3H 8C 4C 4H 3C TH\r
+JC TH 4S 6S JD 2D 4D 6C 3D 4C\r
+TS 3S 2D 4H AC 2C 6S 2H JH 6H\r
+TD 8S AD TC AH AC JH 9S 6S 7S\r
+6C KC 4S JD 8D 9H 5S 7H QH AH\r
+KD 8D TS JH 5C 5H 3H AD AS JS\r
+2D 4H 3D 6C 8C 7S AD 5D 5C 8S\r
+TD 5D 7S 9C 4S 5H 6C 8C 4C 8S\r
+JS QH 9C AS 5C QS JC 3D QC 7C\r
+JC 9C KH JH QS QC 2C TS 3D AD\r
+5D JH AC 5C 9S TS 4C JD 8C KS\r
+KC AS 2D KH 9H 2C 5S 4D 3D 6H\r
+TH AH 2D 8S JC 3D 8C QH 7S 3S\r
+8H QD 4H JC AS KH KS 3C 9S 6D\r
+9S QH 7D 9C 4S AC 7H KH 4D KD\r
+AH AD TH 6D 9C 9S KD KS QH 4H\r
+QD 6H 9C 7C QS 6D 6S 9D 5S JH\r
+AH 8D 5H QD 2H JC KS 4H KH 5S\r
+5C 2S JS 8D 9C 8C 3D AS KC AH\r
+JD 9S 2H QS 8H 5S 8C TH 5C 4C\r
+QC QS 8C 2S 2C 3S 9C 4C KS KH\r
+2D 5D 8S AH AD TD 2C JS KS 8C\r
+TC 5S 5H 8H QC 9H 6H JD 4H 9S\r
+3C JH 4H 9H AH 4S 2H 4C 8D AC\r
+8S TH 4D 7D 6D QD QS 7S TC 7C\r
+KH 6D 2D JD 5H JS QD JH 4H 4S\r
+9C 7S JH 4S 3S TS QC 8C TC 4H\r
+QH 9D 4D JH QS 3S 2C 7C 6C 2D\r
+4H 9S JD 5C 5H AH 9D TS 2D 4C\r
+KS JH TS 5D 2D AH JS 7H AS 8D\r
+JS AH 8C AD KS 5S 8H 2C 6C TH\r
+2H 5D AD AC KS 3D 8H TS 6H QC\r
+6D 4H TS 9C 5H JS JH 6S JD 4C\r
+JH QH 4H 2C 6D 3C 5D 4C QS KC\r
+6H 4H 6C 7H 6S 2S 8S KH QC 8C\r
+3H 3D 5D KS 4H TD AD 3S 4D TS\r
+5S 7C 8S 7D 2C KS 7S 6C 8C JS\r
+5D 2H 3S 7C 5C QD 5H 6D 9C 9H\r
+JS 2S KD 9S 8D TD TS AC 8C 9D\r
+5H QD 2S AC 8C 9H KS 7C 4S 3C\r
+KH AS 3H 8S 9C JS QS 4S AD 4D\r
+AS 2S TD AD 4D 9H JC 4C 5H QS\r
+5D 7C 4H TC 2D 6C JS 4S KC 3S\r
+4C 2C 5D AC 9H 3D JD 8S QS QH\r
+2C 8S 6H 3C QH 6D TC KD AC AH\r
+QC 6C 3S QS 4S AC 8D 5C AD KH\r
+5S 4C AC KH AS QC 2C 5C 8D 9C\r
+8H JD 3C KH 8D 5C 9C QD QH 9D\r
+7H TS 2C 8C 4S TD JC 9C 5H QH\r
+JS 4S 2C 7C TH 6C AS KS 7S JD\r
+JH 7C 9H 7H TC 5H 3D 6D 5D 4D\r
+2C QD JH 2H 9D 5S 3D TD AD KS\r
+JD QH 3S 4D TH 7D 6S QS KS 4H\r
+TC KS 5S 8D 8H AD 2S 2D 4C JH\r
+5S JH TC 3S 2D QS 9D 4C KD 9S\r
+AC KH 3H AS 9D KC 9H QD 6C 6S\r
+9H 7S 3D 5C 7D KC TD 8H 4H 6S\r
+3C 7H 8H TC QD 4D 7S 6S QH 6C\r
+6D AD 4C QD 6C 5D 7D 9D KS TS\r
+JH 2H JD 9S 7S TS KH 8D 5D 8H\r
+2D 9S 4C 7D 9D 5H QD 6D AC 6S\r
+7S 6D JC QD JH 4C 6S QS 2H 7D\r
+8C TD JH KD 2H 5C QS 2C JS 7S\r
+TC 5H 4H JH QD 3S 5S 5D 8S KH\r
+KS KH 7C 2C 5D JH 6S 9C 6D JC\r
+5H AH JD 9C JS KC 2H 6H 4D 5S\r
+AS 3C TH QC 6H 9C 8S 8C TD 7C\r
+KC 2C QD 9C KH 4D 7S 3C TS 9H\r
+9C QC 2S TS 8C TD 9S QD 3S 3C\r
+4D 9D TH JH AH 6S 2S JD QH JS\r
+QD 9H 6C KD 7D 7H 5D 6S 8H AH\r
+8H 3C 4S 2H 5H QS QH 7S 4H AC\r
+QS 3C 7S 9S 4H 3S AH KS 9D 7C\r
+AD 5S 6S 2H 2D 5H TC 4S 3C 8C\r
+QH TS 6S 4D JS KS JH AS 8S 6D\r
+2C 8S 2S TD 5H AS TC TS 6C KC\r
+KC TS 8H 2H 3H 7C 4C 5S TH TD\r
+KD AD KH 7H 7S 5D 5H 5S 2D 9C\r
+AD 9S 3D 7S 8C QC 7C 9C KD KS\r
+3C QC 9S 8C 4D 5C AS QD 6C 2C\r
+2H KC 8S JD 7S AC 8D 5C 2S 4D\r
+9D QH 3D 2S TC 3S KS 3C 9H TD\r
+KD 6S AC 2C 7H 5H 3S 6C 6H 8C\r
+QH TC 8S 6S KH TH 4H 5D TS 4D\r
+8C JS 4H 6H 2C 2H 7D AC QD 3D\r
+QS KC 6S 2D 5S 4H TD 3H JH 4C\r
+7S 5H 7H 8H KH 6H QS TH KD 7D\r
+5H AD KD 7C KH 5S TD 6D 3C 6C\r
+8C 9C 5H JD 7C KC KH 7H 2H 3S\r
+7S 4H AD 4D 8S QS TH 3D 7H 5S\r
+8D TC KS KD 9S 6D AD JD 5C 2S\r
+7H 8H 6C QD 2H 6H 9D TC 9S 7C\r
+8D 6D 4C 7C 6C 3C TH KH JS JH\r
+5S 3S 8S JS 9H AS AD 8H 7S KD\r
+JH 7C 2C KC 5H AS AD 9C 9S JS\r
+AD AC 2C 6S QD 7C 3H TH KS KD\r
+9D JD 4H 8H 4C KH 7S TS 8C KC\r
+3S 5S 2H 7S 6H 7D KS 5C 6D AD\r
+5S 8C 9H QS 7H 7S 2H 6C 7D TD\r
+QS 5S TD AC 9D KC 3D TC 2D 4D\r
+TD 2H 7D JD QD 4C 7H 5D KC 3D\r
+4C 3H 8S KD QH 5S QC 9H TC 5H\r
+9C QD TH 5H TS 5C 9H AH QH 2C\r
+4D 6S 3C AC 6C 3D 2C 2H TD TH\r
+AC 9C 5D QC 4D AD 8D 6D 8C KC\r
+AD 3C 4H AC 8D 8H 7S 9S TD JC\r
+4H 9H QH JS 2D TH TD TC KD KS\r
+5S 6S 9S 8D TH AS KH 5H 5C 8S\r
+JD 2S 9S 6S 5S 8S 5D 7S 7H 9D\r
+5D 8C 4C 9D AD TS 2C 7D KD TC\r
+8S QS 4D KC 5C 8D 4S KH JD KD\r
+AS 5C AD QH 7D 2H 9S 7H 7C TC\r
+2S 8S JD KH 7S 6C 6D AD 5D QC\r
+9H 6H 3S 8C 8H AH TC 4H JS TD\r
+2C TS 4D 7H 2D QC 9C 5D TH 7C\r
+6C 8H QC 5D TS JH 5C 5H 9H 4S\r
+2D QC 7H AS JS 8S 2H 4C 4H 8D\r
+JS 6S AC KD 3D 3C 4S 7H TH KC\r
+QH KH 6S QS 5S 4H 3C QD 3S 3H\r
+7H AS KH 8C 4H 9C 5S 3D 6S TS\r
+9C 7C 3H 5S QD 2C 3D AD AC 5H\r
+JH TD 2D 4C TS 3H KH AD 3S 7S\r
+AS 4C 5H 4D 6S KD JC 3C 6H 2D\r
+3H 6S 8C 2D TH 4S AH QH AD 5H\r
+7C 2S 9H 7H KC 5C 6D 5S 3H JC\r
+3C TC 9C 4H QD TD JH 6D 9H 5S\r
+7C 6S 5C 5D 6C 4S 7H 9H 6H AH\r
+AD 2H 7D KC 2C 4C 2S 9S 7H 3S\r
+TH 4C 8S 6S 3S AD KS AS JH TD\r
+5C TD 4S 4D AD 6S 5D TC 9C 7D\r
+8H 3S 4D 4S 5S 6H 5C AC 3H 3D\r
+9H 3C AC 4S QS 8S 9D QH 5H 4D\r
+JC 6C 5H TS AC 9C JD 8C 7C QD\r
+8S 8H 9C JD 2D QC QH 6H 3C 8D\r
+KS JS 2H 6H 5H QH QS 3H 7C 6D\r
+TC 3H 4S 7H QC 2H 3S 8C JS KH\r
+AH 8H 5S 4C 9H JD 3H 7S JC AC\r
+3C 2D 4C 5S 6C 4S QS 3S JD 3D\r
+5H 2D TC AH KS 6D 7H AD 8C 6H\r
+6C 7S 3C JD 7C 8H KS KH AH 6D\r
+AH 7D 3H 8H 8S 7H QS 5H 9D 2D\r
+JD AC 4H 7S 8S 9S KS AS 9D QH\r
+7S 2C 8S 5S JH QS JC AH KD 4C\r
+AH 2S 9H 4H 8D TS TD 6H QH JD\r
+4H JC 3H QS 6D 7S 9C 8S 9D 8D\r
+5H TD 4S 9S 4C 8C 8D 7H 3H 3D\r
+QS KH 3S 2C 2S 3C 7S TD 4S QD\r
+7C TD 4D 5S KH AC AS 7H 4C 6C\r
+2S 5H 6D JD 9H QS 8S 2C 2H TD\r
+2S TS 6H 9H 7S 4H JC 4C 5D 5S\r
+2C 5H 7D 4H 3S QH JC JS 6D 8H\r
+4C QH 7C QD 3S AD TH 8S 5S TS\r
+9H TC 2S TD JC 7D 3S 3D TH QH\r
+7D 4C 8S 5C JH 8H 6S 3S KC 3H\r
+JC 3H KH TC QH TH 6H 2C AC 5H\r
+QS 2H 9D 2C AS 6S 6C 2S 8C 8S\r
+9H 7D QC TH 4H KD QS AC 7S 3C\r
+4D JH 6S 5S 8H KS 9S QC 3S AS\r
+JD 2D 6S 7S TC 9H KC 3H 7D KD\r
+2H KH 7C 4D 4S 3H JS QD 7D KC\r
+4C JC AS 9D 3C JS 6C 8H QD 4D\r
+AH JS 3S 6C 4C 3D JH 6D 9C 9H\r
+9H 2D 8C 7H 5S KS 6H 9C 2S TC\r
+6C 8C AD 7H 6H 3D KH AS 5D TH\r
+KS 8C 3S TS 8S 4D 5S 9S 6C 4H\r
+9H 4S 4H 5C 7D KC 2D 2H 9D JH\r
+5C JS TC 9D 9H 5H 7S KH JC 6S\r
+7C 9H 8H 4D JC KH JD 2H TD TC\r
+8H 6C 2H 2C KH 6H 9D QS QH 5H\r
+AC 7D 2S 3D QD JC 2D 8D JD JH\r
+2H JC 2D 7H 2C 3C 8D KD TD 4H\r
+3S 4H 6D 8D TS 3H TD 3D 6H TH\r
+JH JC 3S AC QH 9H 7H 8S QC 2C\r
+7H TD QS 4S 8S 9C 2S 5D 4D 2H\r
+3D TS 3H 2S QC 8H 6H KC JC KS\r
+5D JD 7D TC 8C 6C 9S 3D 8D AC\r
+8H 6H JH 6C 5D 8D 8S 4H AD 2C\r
+9D 4H 2D 2C 3S TS AS TC 3C 5D\r
+4D TH 5H KS QS 6C 4S 2H 3D AD\r
+5C KC 6H 2C 5S 3C 4D 2D 9H 9S\r
+JD 4C 3H TH QH 9H 5S AH 8S AC\r
+7D 9S 6S 2H TD 9C 4H 8H QS 4C\r
+3C 6H 5D 4H 8C 9C KC 6S QD QS\r
+3S 9H KD TC 2D JS 8C 6S 4H 4S\r
+2S 4C 8S QS 6H KH 3H TH 8C 5D\r
+2C KH 5S 3S 7S 7H 6C 9D QD 8D\r
+8H KS AC 2D KH TS 6C JS KC 7H\r
+9C KS 5C TD QC AH 6C 5H 9S 7C\r
+5D 4D 3H 4H 6S 7C 7S AH QD TD\r
+2H 7D QC 6S TC TS AH 7S 9D 3H\r
+TH 5H QD 9S KS 7S 7C 6H 8C TD\r
+TH 2D 4D QC 5C 7D JD AH 9C 4H\r
+4H 3H AH 8D 6H QC QH 9H 2H 2C\r
+2D AD 4C TS 6H 7S TH 4H QS TD\r
+3C KD 2H 3H QS JD TC QC 5D 8H\r
+KS JC QD TH 9S KD 8D 8C 2D 9C\r
+3C QD KD 6D 4D 8D AH AD QC 8S\r
+8H 3S 9D 2S 3H KS 6H 4C 7C KC\r
+TH 9S 5C 3D 7D 6H AC 7S 4D 2C\r
+5C 3D JD 4D 2D 6D 5H 9H 4C KH\r
+AS 7H TD 6C 2H 3D QD KS 4C 4S\r
+JC 3C AC 7C JD JS 8H 9S QC 5D\r
+JD 6S 5S 2H AS 8C 7D 5H JH 3D\r
+8D TC 5S 9S 8S 3H JC 5H 7S AS\r
+5C TD 3D 7D 4H 8D 7H 4D 5D JS\r
+QS 9C KS TD 2S 8S 5C 2H 4H AS\r
+TH 7S 4H 7D 3H JD KD 5D 2S KC\r
+JD 7H 4S 8H 4C JS 6H QH 5S 4H\r
+2C QS 8C 5S 3H QC 2S 6C QD AD\r
+8C 3D JD TC 4H 2H AD 5S AC 2S\r
+5D 2C JS 2D AD 9D 3D 4C 4S JH\r
+8D 5H 5D 6H 7S 4D KS 9D TD JD\r
+3D 6D 9C 2S AS 7D 5S 5C 8H JD\r
+7C 8S 3S 6S 5H JD TC AD 7H 7S\r
+2S 9D TS 4D AC 8D 6C QD JD 3H\r
+9S KH 2C 3C AC 3D 5H 6H 8D 5D\r
+KS 3D 2D 6S AS 4C 2S 7C 7H KH\r
+AC 2H 3S JC 5C QH 4D 2D 5H 7S\r
+TS AS JD 8C 6H JC 8S 5S 2C 5D\r
+7S QH 7H 6C QC 8H 2D 7C JD 2S\r
+2C QD 2S 2H JC 9C 5D 2D JD JH\r
+7C 5C 9C 8S 7D 6D 8D 6C 9S JH\r
+2C AD 6S 5H 3S KS 7S 9D KH 4C\r
+7H 6C 2C 5C TH 9D 8D 3S QC AH\r
+5S KC 6H TC 5H 8S TH 6D 3C AH\r
+9C KD 4H AD TD 9S 4S 7D 6H 5D\r
+7H 5C 5H 6D AS 4C KD KH 4H 9D\r
+3C 2S 5C 6C JD QS 2H 9D 7D 3H\r
+AC 2S 6S 7S JS QD 5C QS 6H AD\r
+5H TH QC 7H TC 3S 7C 6D KC 3D\r
+4H 3D QC 9S 8H 2C 3S JC KS 5C\r
+4S 6S 2C 6H 8S 3S 3D 9H 3H JS\r
+4S 8C 4D 2D 8H 9H 7D 9D AH TS\r
+9S 2C 9H 4C 8D AS 7D 3D 6D 5S\r
+6S 4C 7H 8C 3H 5H JC AH 9D 9C\r
+2S 7C 5S JD 8C 3S 3D 4D 7D 6S\r
+3C KC 4S 5D 7D 3D JD 7H 3H 4H\r
+9C 9H 4H 4D TH 6D QD 8S 9S 7S\r
+2H AC 8S 4S AD 8C 2C AH 7D TC\r
+TS 9H 3C AD KS TC 3D 8C 8H JD\r
+QC 8D 2C 3C 7D 7C JD 9H 9C 6C\r
+AH 6S JS JH 5D AS QC 2C JD TD\r
+9H KD 2H 5D 2D 3S 7D TC AH TS\r
+TD 8H AS 5D AH QC AC 6S TC 5H\r
+KS 4S 7H 4D 8D 9C TC 2H 6H 3H\r
+3H KD 4S QD QH 3D 8H 8C TD 7S\r
+8S JD TC AH JS QS 2D KH KS 4D\r
+3C AD JC KD JS KH 4S TH 9H 2C\r
+QC 5S JS 9S KS AS 7C QD 2S JD\r
+KC 5S QS 3S 2D AC 5D 9H 8H KS\r
+6H 9C TC AD 2C 6D 5S JD 6C 7C\r
+QS KH TD QD 2C 3H 8S 2S QC AH\r
+9D 9H JH TC QH 3C 2S JS 5C 7H\r
+6C 3S 3D 2S 4S QD 2D TH 5D 2C\r
+2D 6H 6D 2S JC QH AS 7H 4H KH\r
+5H 6S KS AD TC TS 7C AC 4S 4H\r
+AD 3C 4H QS 8C 9D KS 2H 2D 4D\r
+4S 9D 6C 6D 9C AC 8D 3H 7H KD\r
+JC AH 6C TS JD 6D AD 3S 5D QD\r
+JC JH JD 3S 7S 8S JS QC 3H 4S\r
+JD TH 5C 2C AD JS 7H 9S 2H 7S\r
+8D 3S JH 4D QC AS JD 2C KC 6H\r
+2C AC 5H KD 5S 7H QD JH AH 2D\r
+JC QH 8D 8S TC 5H 5C AH 8C 6C\r
+3H JS 8S QD JH 3C 4H 6D 5C 3S\r
+6D 4S 4C AH 5H 5S 3H JD 7C 8D\r
+8H AH 2H 3H JS 3C 7D QC 4H KD\r
+6S 2H KD 5H 8H 2D 3C 8S 7S QD\r
+2S 7S KC QC AH TC QS 6D 4C 8D\r
+5S 9H 2C 3S QD 7S 6C 2H 7C 9D\r
+3C 6C 5C 5S JD JC KS 3S 5D TS\r
+7C KS 6S 5S 2S 2D TC 2H 5H QS\r
+AS 7H 6S TS 5H 9S 9D 3C KD 2H\r
+4S JS QS 3S 4H 7C 2S AC 6S 9D\r
+8C JH 2H 5H 7C 5D QH QS KH QC\r
+3S TD 3H 7C KC 8D 5H 8S KH 8C\r
+4H KH JD TS 3C 7H AS QC JS 5S\r
+AH 9D 2C 8D 4D 2D 6H 6C KC 6S\r
+2S 6H 9D 3S 7H 4D KH 8H KD 3D\r
+9C TC AC JH KH 4D JD 5H TD 3S\r
+7S 4H 9D AS 4C 7D QS 9S 2S KH\r
+3S 8D 8S KS 8C JC 5C KH 2H 5D\r
+8S QH 2C 4D KC JS QC 9D AC 6H\r
+8S 8C 7C JS JD 6S 4C 9C AC 4S\r
+QH 5D 2C 7D JC 8S 2D JS JH 4C\r
+JS 4C 7S TS JH KC KH 5H QD 4S\r
+QD 8C 8D 2D 6S TD 9D AC QH 5S\r
+QH QC JS 3D 3C 5C 4H KH 8S 7H\r
+7C 2C 5S JC 8S 3H QC 5D 2H KC\r
+5S 8D KD 6H 4H QD QH 6D AH 3D\r
+7S KS 6C 2S 4D AC QS 5H TS JD\r
+7C 2D TC 5D QS AC JS QC 6C KC\r
+2C KS 4D 3H TS 8S AD 4H 7S 9S\r
+QD 9H QH 5H 4H 4D KH 3S JC AD\r
+4D AC KC 8D 6D 4C 2D KH 2C JD\r
+2C 9H 2D AH 3H 6D 9C 7D TC KS\r
+8C 3H KD 7C 5C 2S 4S 5H AS AH\r
+TH JD 4H KD 3H TC 5C 3S AC KH\r
+6D 7H AH 7S QC 6H 2D TD JD AS\r
+JH 5D 7H TC 9S 7D JC AS 5S KH\r
+2H 8C AD TH 6H QD KD 9H 6S 6C\r
+QH KC 9D 4D 3S JS JH 4H 2C 9H\r
+TC 7H KH 4H JC 7D 9S 3H QS 7S\r
+AD 7D JH 6C 7H 4H 3S 3H 4D QH\r
+JD 2H 5C AS 6C QC 4D 3C TC JH\r
+AC JD 3H 6H 4C JC AD 7D 7H 9H\r
+4H TC TS 2C 8C 6S KS 2H JD 9S\r
+4C 3H QS QC 9S 9H 6D KC 9D 9C\r
+5C AD 8C 2C QH TH QD JC 8D 8H\r
+QC 2C 2S QD 9C 4D 3S 8D JH QS\r
+9D 3S 2C 7S 7C JC TD 3C TC 9H\r
+3C TS 8H 5C 4C 2C 6S 8D 7C 4H\r
+KS 7H 2H TC 4H 2C 3S AS AH QS\r
+8C 2D 2H 2C 4S 4C 6S 7D 5S 3S\r
+TH QC 5D TD 3C QS KD KC KS AS\r
+4D AH KD 9H KS 5C 4C 6H JC 7S\r
+KC 4H 5C QS TC 2H JC 9S AH QH\r
+4S 9H 3H 5H 3C QD 2H QC JH 8H\r
+5D AS 7H 2C 3D JH 6H 4C 6S 7D\r
+9C JD 9H AH JS 8S QH 3H KS 8H\r
+3S AC QC TS 4D AD 3D AH 8S 9H\r
+7H 3H QS 9C 9S 5H JH JS AH AC\r
+8D 3C JD 2H AC 9C 7H 5S 4D 8H\r
+7C JH 9H 6C JS 9S 7H 8C 9D 4H\r
+2D AS 9S 6H 4D JS JH 9H AD QD\r
+6H 7S JH KH AH 7H TD 5S 6S 2C\r
+8H JH 6S 5H 5S 9D TC 4C QC 9S\r
+7D 2C KD 3H 5H AS QD 7H JS 4D\r
+TS QH 6C 8H TH 5H 3C 3H 9C 9D\r
+AD KH JS 5D 3H AS AC 9S 5C KC\r
+2C KH 8C JC QS 6D AH 2D KC TC\r
+9D 3H 2S 7C 4D 6D KH KS 8D 7D\r
+9H 2S TC JH AC QC 3H 5S 3S 8H\r
+3S AS KD 8H 4C 3H 7C JH QH TS\r
+7S 6D 7H 9D JH 4C 3D 3S 6C AS\r
+4S 2H 2C 4C 8S 5H KC 8C QC QD\r
+3H 3S 6C QS QC 2D 6S 5D 2C 9D\r
+2H 8D JH 2S 3H 2D 6C 5C 7S AD\r
+9H JS 5D QH 8S TS 2H 7S 6S AD\r
+6D QC 9S 7H 5H 5C 7D KC JD 4H\r
+QC 5S 9H 9C 4D 6S KS 2S 4C 7C\r
+9H 7C 4H 8D 3S 6H 5C 8H JS 7S\r
+2D 6H JS TD 4H 4D JC TH 5H KC\r
+AC 7C 8D TH 3H 9S 2D 4C KC 4D\r
+KD QS 9C 7S 3D KS AD TS 4C 4H\r
+QH 9C 8H 2S 7D KS 7H 5D KD 4C\r
+9C 2S 2H JC 6S 6C TC QC JH 5C\r
+7S AC 8H KC 8S 6H QS JC 3D 6S\r
+JS 2D JH 8C 4S 6H 8H 6D 5D AD\r
+6H 7D 2S 4H 9H 7C AS AC 8H 5S\r
+3C JS 4S 6D 5H 2S QH 6S 9C 2C\r
+3D 5S 6S 9S 4C QS 8D QD 8S TC\r
+9C 3D AH 9H 5S 2C 7D AD JC 3S\r
+7H TC AS 3C 6S 6D 7S KH KC 9H\r
+3S TC 8H 6S 5H JH 8C 7D AC 2S\r
+QD 9D 9C 3S JC 8C KS 8H 5D 4D\r
+JS AH JD 6D 9D 8C 9H 9S 8H 3H\r
+2D 6S 4C 4D 8S AD 4S TC AH 9H\r
+TS AC QC TH KC 6D 4H 7S 8C 2H\r
+3C QD JS 9D 5S JC AH 2H TS 9H\r
+3H 4D QH 5D 9C 5H 7D 4S JC 3S\r
+8S TH 3H 7C 2H JD JS TS AC 8D\r
+9C 2H TD KC JD 2S 8C 5S AD 2C\r
+3D KD 7C 5H 4D QH QD TC 6H 7D\r
+7H 2C KC 5S KD 6H AH QC 7S QH\r
+6H 5C AC 5H 2C 9C 2D 7C TD 2S\r
+4D 9D AH 3D 7C JD 4H 8C 4C KS\r
+TH 3C JS QH 8H 4C AS 3D QS QC\r
+4D 7S 5H JH 6D 7D 6H JS KH 3C\r
+QD 8S 7D 2H 2C 7C JC 2S 5H 8C\r
+QH 8S 9D TC 2H AD 7C 8D QD 6S\r
+3S 7C AD 9H 2H 9S JD TS 4C 2D\r
+3S AS 4H QC 2C 8H 8S 7S TD TC\r
+JH TH TD 3S 4D 4H 5S 5D QS 2C\r
+8C QD QH TC 6D 4S 9S 9D 4H QC\r
+8C JS 9D 6H JD 3H AD 6S TD QC\r
+KC 8S 3D 7C TD 7D 8D 9H 4S 3S\r
+6C 4S 3D 9D KD TC KC KS AC 5S\r
+7C 6S QH 3D JS KD 6H 6D 2D 8C\r
+JD 2S 5S 4H 8S AC 2D 6S TS 5C\r
+5H 8C 5S 3C 4S 3D 7C 8D AS 3H\r
+AS TS 7C 3H AD 7D JC QS 6C 6H\r
+3S 9S 4C AC QH 5H 5D 9H TS 4H\r
+6C 5C 7H 7S TD AD JD 5S 2H 2S\r
+7D 6C KC 3S JD 8D 8S TS QS KH\r
+8S QS 8D 6C TH AC AH 2C 8H 9S\r
+7H TD KH QH 8S 3D 4D AH JD AS\r
+TS 3D 2H JC 2S JH KH 6C QC JS\r
+KC TH 2D 6H 7S 2S TC 8C 9D QS\r
+3C 9D 6S KH 8H 6D 5D TH 2C 2H\r
+6H TC 7D AD 4D 8S TS 9H TD 7S\r
+JS 6D JD JC 2H AC 6C 3D KH 8D\r
+KH JD 9S 5D 4H 4C 3H 7S QS 5C\r
+4H JD 5D 3S 3C 4D KH QH QS 7S\r
+JD TS 8S QD AH 4C 6H 3S 5S 2C\r
+QS 3D JD AS 8D TH 7C 6S QC KS\r
+7S 2H 8C QC 7H AC 6D 2D TH KH\r
+5S 6C 7H KH 7D AH 8C 5C 7S 3D\r
+3C KD AD 7D 6C 4D KS 2D 8C 4S\r
+7C 8D 5S 2D 2S AH AD 2C 9D TD\r
+3C AD 4S KS JH 7C 5C 8C 9C TH\r
+AS TD 4D 7C JD 8C QH 3C 5H 9S\r
+3H 9C 8S 9S 6S QD KS AH 5H JH\r
+QC 9C 5S 4H 2H TD 7D AS 8C 9D\r
+8C 2C 9D KD TC 7S 3D KH QC 3C\r
+4D AS 4C QS 5S 9D 6S JD QH KS\r
+6D AH 6C 4C 5H TS 9H 7D 3D 5S\r
+QS JD 7C 8D 9C AC 3S 6S 6C KH\r
+8H JH 5D 9S 6D AS 6S 3S QC 7H\r
+QD AD 5C JH 2H AH 4H AS KC 2C\r
+JH 9C 2C 6H 2D JS 5D 9H KC 6D\r
+7D 9D KD TH 3H AS 6S QC 6H AD\r
+JD 4H 7D KC 3H JS 3C TH 3D QS\r
+4C 3H 8C QD 5H 6H AS 8H AD JD\r
+TH 8S KD 5D QC 7D JS 5S 5H TS\r
+7D KC 9D QS 3H 3C 6D TS 7S AH\r
+7C 4H 7H AH QC AC 4D 5D 6D TH\r
+3C 4H 2S KD 8H 5H JH TC 6C JD\r
+4S 8C 3D 4H JS TD 7S JH QS KD\r
+7C QC KD 4D 7H 6S AD TD TC KH\r
+5H 9H KC 3H 4D 3D AD 6S QD 6H\r
+TH 7C 6H TS QH 5S 2C KC TD 6S\r
+7C 4D 5S JD JH 7D AC KD KH 4H\r
+7D 6C 8D 8H 5C JH 8S QD TH JD\r
+8D 7D 6C 7C 9D KD AS 5C QH JH\r
+9S 2C 8C 3C 4C KS JH 2D 8D 4H\r
+7S 6C JH KH 8H 3H 9D 2D AH 6D\r
+4D TC 9C 8D 7H TD KS TH KD 3C\r
+JD 9H 8D QD AS KD 9D 2C 2S 9C\r
+8D 3H 5C 7H KS 5H QH 2D 8C 9H\r
+2D TH 6D QD 6C KC 3H 3S AD 4C\r
+4H 3H JS 9D 3C TC 5H QH QC JC\r
+3D 5C 6H 3S 3C JC 5S 7S 2S QH\r
+AC 5C 8C 4D 5D 4H 2S QD 3C 3H\r
+2C TD AH 9C KD JS 6S QD 4C QC\r
+QS 8C 3S 4H TC JS 3H 7C JC AD\r
+5H 4D 9C KS JC TD 9S TS 8S 9H\r
+QD TS 7D AS AC 2C TD 6H 8H AH\r
+6S AD 8C 4S 9H 8D 9D KH 8S 3C\r
+QS 4D 2D 7S KH JS JC AD 4C 3C\r
+QS 9S 7H KC TD TH 5H JS AC JH\r
+6D AC 2S QS 7C AS KS 6S KH 5S\r
+6D 8H KH 3C QS 2H 5C 9C 9D 6C\r
+JS 2C 4C 6H 7D JC AC QD TD 3H\r
+4H QC 8H JD 4C KD KS 5C KC 7S\r
+6D 2D 3H 2S QD 5S 7H AS TH 6S\r
+AS 6D 8D 2C 8S TD 8H QD JC AH\r
+9C 9H 2D TD QH 2H 5C TC 3D 8H\r
+KC 8S 3D KH 2S TS TC 6S 4D JH\r
+9H 9D QS AC KC 6H 5D 4D 8D AH\r
+9S 5C QS 4H 7C 7D 2H 8S AD JS\r
+3D AC 9S AS 2C 2D 2H 3H JC KH\r
+7H QH KH JD TC KS 5S 8H 4C 8D\r
+2H 7H 3S 2S 5H QS 3C AS 9H KD\r
+AD 3D JD 6H 5S 9C 6D AC 9S 3S\r
+3D 5D 9C 2D AC 4S 2S AD 6C 6S\r
+QC 4C 2D 3H 6S KC QH QD 2H JH\r
+QC 3C 8S 4D 9S 2H 5C 8H QS QD\r
+6D KD 6S 7H 3S KH 2H 5C JC 6C\r
+3S 9S TC 6S 8H 2D AD 7S 8S TS\r
+3C 6H 9C 3H 5C JC 8H QH TD QD\r
+3C JS QD 5D TD 2C KH 9H TH AS\r
+9S TC JD 3D 5C 5H AD QH 9H KC\r
+TC 7H 4H 8H 3H TD 6S AC 7C 2S\r
+QS 9D 5D 3C JC KS 4D 6C JH 2S\r
+9S 6S 3C 7H TS 4C KD 6D 3D 9C\r
+2D 9H AH AC 7H 2S JH 3S 7C QC\r
+QD 9H 3C 2H AC AS 8S KD 8C KH\r
+2D 7S TD TH 6D JD 8D 4D 2H 5S\r
+8S QH KD JD QS JH 4D KC 5H 3S\r
+3C KH QC 6D 8H 3S AH 7D TD 2D\r
+5S 9H QH 4S 6S 6C 6D TS TH 7S\r
+6C 4C 6D QS JS 9C TS 3H 8D 8S\r
+JS 5C 7S AS 2C AH 2H AD 5S TC\r
+KD 6C 9C 9D TS 2S JC 4H 2C QD\r
+QS 9H TC 3H KC KS 4H 3C AD TH\r
+KH 9C 2H KD 9D TC 7S KC JH 2D\r
+7C 3S KC AS 8C 5D 9C 9S QH 3H\r
+2D 8C TD 4C 2H QC 5D TC 2C 7D\r
+KS 4D 6C QH TD KH 5D 7C AD 8D\r
+2S 9S 8S 4C 8C 3D 6H QD 7C 7H\r
+6C 8S QH 5H TS 5C 3C 4S 2S 2H\r
+8S 6S 2H JC 3S 3H 9D 8C 2S 7H\r
+QC 2C 8H 9C AC JD 4C 4H 6S 3S\r
+3H 3S 7D 4C 9S 5H 8H JC 3D TC\r
+QH 2S 2D 9S KD QD 9H AD 6D 9C\r
+8D 2D KS 9S JC 4C JD KC 4S TH\r
+KH TS 6D 4D 5C KD 5H AS 9H AD\r
+QD JS 7C 6D 5D 5C TH 5H QH QS\r
+9D QH KH 5H JH 4C 4D TC TH 6C\r
+KH AS TS 9D KD 9C 7S 4D 8H 5S\r
+KH AS 2S 7D 9D 4C TS TH AH 7C\r
+KS 4D AC 8S 9S 8D TH QH 9D 5C\r
+5D 5C 8C QS TC 4C 3D 3S 2C 8D\r
+9D KS 2D 3C KC 4S 8C KH 6C JC\r
+8H AH 6H 7D 7S QD 3C 4C 6C KC\r
+3H 2C QH 8H AS 7D 4C 8C 4H KC\r
+QD 5S 4H 2C TD AH JH QH 4C 8S\r
+3H QS 5S JS 8H 2S 9H 9C 3S 2C\r
+6H TS 7S JC QD AC TD KC 5S 3H\r
+QH AS QS 7D JC KC 2C 4C 5C 5S\r
+QH 3D AS JS 4H 8D 7H JC 2S 9C\r
+5D 4D 2S 4S 9D 9C 2D QS 8H 7H\r
+6D 7H 3H JS TS AC 2D JH 7C 8S\r
+JH 5H KC 3C TC 5S 9H 4C 8H 9D\r
+8S KC 5H 9H AD KS 9D KH 8D AH\r
+JC 2H 9H KS 6S 3H QC 5H AH 9C\r
+5C KH 5S AD 6C JC 9H QC 9C TD\r
+5S 5D JC QH 2D KS 8H QS 2H TS\r
+JH 5H 5S AH 7H 3C 8S AS TD KH\r
+6H 3D JD 2C 4C KC 7S AH 6C JH\r
+4C KS 9D AD 7S KC 7D 8H 3S 9C\r
+7H 5C 5H 3C 8H QC 3D KH 6D JC\r
+2D 4H 5D 7D QC AD AH 9H QH 8H\r
+KD 8C JS 9D 3S 3C 2H 5D 6D 2S\r
+8S 6S TS 3C 6H 8D 5S 3H TD 6C\r
+KS 3D JH 9C 7C 9S QS 5S 4H 6H\r
+7S 6S TH 4S KC KD 3S JC JH KS\r
+7C 3C 2S 6D QH 2C 7S 5H 8H AH\r
+KC 8D QD 6D KH 5C 7H 9D 3D 9C\r
+6H 2D 8S JS 9S 2S 6D KC 7C TC\r
+KD 9C JH 7H KC 8S 2S 7S 3D 6H\r
+4H 9H 2D 4C 8H 7H 5S 8S 2H 8D\r
+AD 7C 3C 7S 5S 4D 9H 3D JC KH\r
+5D AS 7D 6D 9C JC 4C QH QS KH\r
+KD JD 7D 3D QS QC 8S 6D JS QD\r
+6S 8C 5S QH TH 9H AS AC 2C JD\r
+QC KS QH 7S 3C 4C 5C KC 5D AH\r
+6C 4H 9D AH 2C 3H KD 3D TS 5C\r
+TD 8S QS AS JS 3H KD AC 4H KS\r
+7D 5D TS 9H 4H 4C 9C 2H 8C QC\r
+2C 7D 9H 4D KS 4C QH AD KD JS\r
+QD AD AH KH 9D JS 9H JC KD JD\r
+8S 3C 4S TS 7S 4D 5C 2S 6H 7C\r
+JS 7S 5C KD 6D QH 8S TD 2H 6S\r
+QH 6C TC 6H TD 4C 9D 2H QC 8H\r
+3D TS 4D 2H 6H 6S 2C 7H 8S 6C\r
+9H 9D JD JH 3S AH 2C 6S 3H 8S\r
+2C QS 8C 5S 3H 2S 7D 3C AD 4S\r
+5C QC QH AS TS 4S 6S 4C 5H JS\r
+JH 5C TD 4C 6H JS KD KH QS 4H\r
+TC KH JC 4D 9H 9D 8D KC 3C 8H\r
+2H TC 8S AD 9S 4H TS 7H 2C 5C\r
+4H 2S 6C 5S KS AH 9C 7C 8H KD\r
+TS QH TD QS 3C JH AH 2C 8D 7D\r
+5D KC 3H 5S AC 4S 7H QS 4C 2H\r
+3D 7D QC KH JH 6D 6C TD TH KD\r
+5S 8D TH 6C 9D 7D KH 8C 9S 6D\r
+JD QS 7S QC 2S QH JC 4S KS 8D\r
+7S 5S 9S JD KD 9C JC AD 2D 7C\r
+4S 5H AH JH 9C 5D TD 7C 2D 6S\r
+KC 6C 7H 6S 9C QD 5S 4H KS TD\r
+6S 8D KS 2D TH TD 9H JD TS 3S\r
+KH JS 4H 5D 9D TC TD QC JD TS\r
+QS QD AC AD 4C 6S 2D AS 3H KC\r
+4C 7C 3C TD QS 9C KC AS 8D AD\r
+KC 7H QC 6D 8H 6S 5S AH 7S 8C\r
+3S AD 9H JC 6D JD AS KH 6S JH\r
+AD 3D TS KS 7H JH 2D JS QD AC\r
+9C JD 7C 6D TC 6H 6C JC 3D 3S\r
+QC KC 3S JC KD 2C 8D AH QS TS\r
+AS KD 3D JD 8H 7C 8C 5C QD 6C\r
index d07d0c8e31dabbcff6cdf2075e4f2b7c7b16aa6a..43f380b3ba820de37a836288f8b00fbd213eceae 100644 (file)
@@ -66,4 +66,4 @@ PRIVATE>
 ! [ euler055 ] 100 ave-time
 ! 478 ms ave run time - 30.63 SD (100 trials)
 
-MAIN: euler055
+SOLUTION: euler055
index e2d95e27c11f6f7dcf56ff1e7419eb220c69c1a6..76c275e4dde21dbabc1d3cb43061f3b9685e8cae 100644 (file)
@@ -29,4 +29,4 @@ IN: project-euler.056
 ! [ euler056 ] 100 ave-time
 ! 22 ms ave run time - 2.13 SD (100 trials)
 
-MAIN: euler056
+SOLUTION: euler056
index 53240b0ec1dbea2176deb63bebdf3910447f466c..681a17dd9ec2fe17434d74e380e77e868be72996 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Samuel Tardieu
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions math.parser sequences ;
+USING: kernel math math.functions math.parser sequences project-euler.common ;
 IN: project-euler.057
 
 ! http://projecteuler.net/index.php?section=problems&id=57
@@ -40,4 +40,4 @@ IN: project-euler.057
 ! [ euler057 ] time
 ! 3.375118 seconds
 
-MAIN: euler057
+SOLUTION: euler057
diff --git a/extra/project-euler/058/058-tests.factor b/extra/project-euler/058/058-tests.factor
new file mode 100644 (file)
index 0000000..13a2aaf
--- /dev/null
@@ -0,0 +1,3 @@
+USING: project-euler.058 tools.test ;
+
+{ 26241 } [ euler058 ] unit-test
diff --git a/extra/project-euler/058/058.factor b/extra/project-euler/058/058.factor
new file mode 100644 (file)
index 0000000..133175f
--- /dev/null
@@ -0,0 +1,68 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: fry kernel math math.primes math.ranges project-euler.common sequences ;
+IN: project-euler.058
+
+! http://projecteuler.net/index.php?section=problems&id=58
+
+! DESCRIPTION
+! -----------
+
+! Starting with 1 and solveling anticlockwise in the following way, a square
+! solve with side length 7 is formed.
+
+!     37 36 35 34 33 32 31
+!     38 17 16 15 14 13 30
+!     39 18  5  4  3 12 29
+!     40 19  6  1  2 11 28
+!     41 20  7  8  9 10 27
+!     42 21 22 23 24 25 26
+!     43 44 45 46 47 48 49
+
+! It is interesting to note that the odd squares lie along the bottom right
+! diagonal, but what is more interesting is that 8 out of the 13 numbers lying
+! along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.
+
+! If one complete new layer is wrapped around the solve above, a square solve
+! with side length 9 will be formed. If this process is continued, what is the
+! side length of the square solve for which the ratio of primes along both
+! diagonals first falls below 10%?
+
+
+! SOLUTION
+! --------
+
+<PRIVATE
+
+CONSTANT: PERCENT_PRIME 0.1
+
+! The corners of a square of side length n are:
+!    (n-2)² + 1(n-1)
+!    (n-2)² + 2(n-1)
+!    (n-2)² + 3(n-1)
+!    (n-2)² + 4(n-1) = odd squares, no need to calculate
+
+: prime-corners ( n -- m )
+    3 [1,b] swap '[ _ [ 1- * ] keep 2 - sq + prime? ] count ;
+
+: total-corners ( n -- m )
+    1- 2 * ; foldable
+
+: ratio-below? ( count length -- ? )
+    total-corners 1+ / PERCENT_PRIME < ;
+
+: next-layer ( count length -- count' length' )
+    2 + [ prime-corners + ] keep ;
+
+: solve ( count length -- length )
+    2dup ratio-below? [ nip ] [ next-layer solve ] if ;
+
+PRIVATE>
+
+: euler058 ( -- answer )
+    8 7 solve ;
+
+! [ euler058 ] 10 ave-time
+! 12974 ms ave run time - 284.46 SD (10 trials)
+
+SOLUTION: euler058
index 0abd753c0989adca62db594e097c945a7c6ac2c3..9a2fb8c868a48f1c53a7ac6de43a6edcecbb85b7 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays ascii assocs hashtables io.encodings.ascii io.files kernel math
     math.parser namespaces make sequences sequences.private sorting
-    splitting grouping strings sets accessors ;
+    splitting grouping strings sets accessors project-euler.common ;
 IN: project-euler.059
 
 ! http://projecteuler.net/index.php?section=problems&id=59
@@ -89,4 +89,4 @@ PRIVATE>
 ! [ euler059 ] 100 ave-time
 ! 8 ms ave run time - 1.4 SD (100 trials)
 
-MAIN: euler059
+SOLUTION: euler059
diff --git a/extra/project-euler/063/063-tests.factor b/extra/project-euler/063/063-tests.factor
new file mode 100644 (file)
index 0000000..0cff44d
--- /dev/null
@@ -0,0 +1,3 @@
+USING: project-euler.063 tools.test ;
+
+{ 49 } [ euler063 ] unit-test
diff --git a/extra/project-euler/063/063.factor b/extra/project-euler/063/063.factor
new file mode 100644 (file)
index 0000000..80e3990
--- /dev/null
@@ -0,0 +1,37 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.functions math.ranges project-euler.common sequences ;
+IN: project-euler.063
+
+! http://projecteuler.net/index.php?section=problems&id=63
+
+! DESCRIPTION
+! -----------
+
+! The 5-digit number, 16807 = 7^5, is also a fifth power. Similarly, the
+! 9-digit number, 134217728 = 8^9, is a ninth power.
+
+! How many n-digit positive integers exist which are also an nth power?
+
+
+! SOLUTION
+! --------
+
+! Only have to check from 1 to 9 because 10^n already has too many digits.
+! In general, x^n has n digits when:
+
+!     10^(n-1) <= x^n < 10^n
+
+! ...take the left side of that equation, solve for n to see where they meet:
+
+!     n = log(10) / [ log(10) - log(x) ]
+
+! Round down since we already know that particular value of n is no good.
+
+: euler063 ( -- answer )
+    9 [1,b] [ log [ 10 log dup ] dip - /i ] sigma ;
+
+! [ euler063 ] 100 ave-time
+! 0 ms ave run time - 0.0 SD (100 trials)
+
+SOLUTION: euler063
index 3f9d67091dad9ceef9066042b5138047ee064f1b..7f3472f306a6ff5c7c299918170fafdf7c042fd3 100644 (file)
@@ -59,4 +59,4 @@ PRIVATE>
 ! [ euler067a ] 100 ave-time
 ! 21 ms ave run time - 2.65 SD (100 trials)
 
-MAIN: euler067a
+SOLUTION: euler067a
diff --git a/extra/project-euler/069/069-tests.factor b/extra/project-euler/069/069-tests.factor
new file mode 100644 (file)
index 0000000..97741c0
--- /dev/null
@@ -0,0 +1,4 @@
+USING: project-euler.069 tools.test ;
+
+{ 510510 } [ euler069 ] unit-test
+{ 510510 } [ euler069a ] unit-test
diff --git a/extra/project-euler/069/069.factor b/extra/project-euler/069/069.factor
new file mode 100644 (file)
index 0000000..eae1d82
--- /dev/null
@@ -0,0 +1,87 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators fry kernel math math.primes math.primes.factors math.ranges
+    project-euler.common sequences ;
+IN: project-euler.069
+
+! http://projecteuler.net/index.php?section=problems&id=69
+
+! DESCRIPTION
+! -----------
+
+! Euler's Totient function, φ(n) [sometimes called the phi function], is used
+! to determine the number of numbers less than n which are relatively prime to
+! n. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and
+! relatively prime to nine, φ(9)=6.
+
+!     +----+------------------+------+-----------+
+!     | n  | Relatively Prime | φ(n) | n / φ(n)  |
+!     +----+------------------+------+-----------+
+!     | 2  | 1                | 1    | 2         |
+!     | 3  | 1,2              | 2    | 1.5       |
+!     | 4  | 1,3              | 2    | 2         |
+!     | 5  | 1,2,3,4          | 4    | 1.25      |
+!     | 6  | 1,5              | 2    | 3         |
+!     | 7  | 1,2,3,4,5,6      | 6    | 1.1666... |
+!     | 8  | 1,3,5,7          | 4    | 2         |
+!     | 9  | 1,2,4,5,7,8      | 6    | 1.5       |
+!     | 10 | 1,3,7,9          | 4    | 2.5       |
+!     +----+------------------+------+-----------+
+
+! It can be seen that n = 6 produces a maximum n / φ(n) for n ≤ 10.
+
+! Find the value of n ≤ 1,000,000 for which n / φ(n) is a maximum.
+
+
+! SOLUTION
+! --------
+
+! Brute force
+
+<PRIVATE
+
+: totient-ratio ( n -- m )
+    dup totient / ;
+
+PRIVATE>
+
+: euler069 ( -- answer )
+    2 1000000 [a,b] [ totient-ratio ] map
+    [ supremum ] keep index 2 + ;
+
+! [ euler069 ] 10 ave-time
+! 25210 ms ave run time - 115.37 SD (10 trials)
+
+
+! ALTERNATE SOLUTIONS
+! -------------------
+
+! In order to obtain maximum n / φ(n), φ(n) needs to be low and n needs to be
+! high. Hence we need a number that has the most factors. A number with the
+! most unique factors would have fewer relatively prime.
+
+<PRIVATE
+
+: primorial ( n -- m )
+    {
+        { [ dup 0 = ] [ drop V{ 1 } ] }
+        { [ dup 1 = ] [ drop V{ 2 } ] }
+        [ nth-prime primes-upto ]
+    } cond product ;
+
+: (primorial-upto) ( count limit -- m )
+    '[ dup primorial _ <= ] [ 1+ dup primorial ] produce
+    nip penultimate ;
+
+: primorial-upto ( limit -- m )
+    1 swap (primorial-upto) ;
+
+PRIVATE>
+
+: euler069a ( -- answer )
+    1000000 primorial-upto ;
+
+! [ euler069a ] 100 ave-time
+! 0 ms ave run time - 0.01 SD (100 trials)
+
+SOLUTION: euler069a
index 69d9eb1a03cb3b11f68de14cf0ec5ad49b42de19..0fd93a8f2d0fb9afa4b226374c0409f3f1d54f4a 100644 (file)
@@ -32,13 +32,6 @@ IN: project-euler.071
 ! repeatedly until the denominator is as close to 1000000 as possible without
 ! going over.
 
-<PRIVATE
-
-: penultimate ( seq -- elt )
-    dup length 2 - swap nth ;
-
-PRIVATE>
-
 : euler071 ( -- answer )
     2/5 [ dup denominator 1000000 <= ] [ 3/7 mediant dup ] produce
     nip penultimate numerator ;
@@ -46,4 +39,4 @@ PRIVATE>
 ! [ euler071 ] 100 ave-time
 ! 155 ms ave run time - 6.95 SD (100 trials)
 
-MAIN: euler071
+SOLUTION: euler071
index 68dcd01e0d3d93ce1abf798e40af4eca06a970ed..c7e88057226c21b4a632361fb78a65be8dc8c93a 100644 (file)
@@ -49,4 +49,4 @@ PRIVATE>
 ! [ euler073 ] 10 ave-time
 ! 20506 ms ave run time - 937.07 SD (10 trials)
 
-MAIN: euler073
+SOLUTION: euler073
index 2b5b9311650b530fa22f274ffaf92c267823d0c3..5f54d8508e89683d64e352b1fdab0b8034877c8f 100755 (executable)
@@ -75,4 +75,4 @@ PRIVATE>
 ! [ euler075 ] 10 ave-time
 ! 3341 ms ave run timen - 157.77 SD (10 trials)
 
-MAIN: euler075
+SOLUTION: euler075
index e332d9ef3e53c40c4ba322fa793e4f800bb4e798..e6ed9035d2b72e1fd702003551d77b247ff7718d 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays assocs kernel locals math math.order math.ranges sequences ;
+USING: arrays assocs kernel locals math math.order math.ranges sequences project-euler.common ;
 IN: project-euler.076
 
 ! http://projecteuler.net/index.php?section=problems&id=76
@@ -56,4 +56,4 @@ PRIVATE>
 ! [ euler076 ] 100 ave-time
 ! 560 ms ave run time - 17.74 SD (100 trials)
 
-MAIN: euler076
+SOLUTION: euler076
index ad75c43c42772c2fe8f37bf9d3a40c84792d1b52..3ad740670312e4462f25d2bc0c3b7fe0cec156ec 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs io.encodings.ascii io.files kernel make math math.parser
-    sequences sets ;
+    sequences sets project-euler.common ;
 IN: project-euler.079
 
 ! http://projecteuler.net/index.php?section=problems&id=79
@@ -63,4 +63,4 @@ PRIVATE>
 ! TODO: prune and diff are relatively slow; topological sort could be
 ! cleaned up and generalized much better, but it works for this problem
 
-MAIN: euler079
+SOLUTION: euler079
index c778fd952556f1406efd6dfb3f0482a5f7a92682..4901eae3428af4eb4f058a563b862d90a2d4a1b5 100644 (file)
@@ -50,4 +50,4 @@ PRIVATE>
 
 ! TODO: this solution is not very efficient, much better optimizations exist
 
-MAIN: euler092
+SOLUTION: euler092
index 6e6547a7e961e563d670ecff987fab769313e5de..a8895c215a0113e8c700825ba0ca7363fc6e5fcb 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: math math.functions ;
+USING: math math.functions project-euler.common ;
 IN: project-euler.097
 
 ! http://projecteuler.net/index.php?section=problems&id=97
@@ -28,4 +28,4 @@ IN: project-euler.097
 ! [ euler097 ] 100 ave-time
 ! 0 ms ave run timen - 0.22 SD (100 trials)
 
-MAIN: euler097
+SOLUTION: euler097
index ebc830cf0026f94d5c2fd687a7a77d824caa4d68..30bf52bebbf56867f719417d4965e4bdbbc99baf 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2008 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.encodings.ascii io.files kernel math math.functions math.parser
-    math.vectors sequences splitting ;
+    math.vectors sequences splitting project-euler.common ;
 IN: project-euler.099
 
 ! http://projecteuler.net/index.php?section=problems&id=99
@@ -49,4 +49,4 @@ PRIVATE>
 ! [ euler099 ] 100 ave-time
 ! 16 ms ave run timen - 1.67 SD (100 trials)
 
-MAIN: euler099
+SOLUTION: euler099
index ec372add3bff00f4ded9e71be8bfc223c47aeb6b..6f05eb7120846adb2a05fdcb1ad2ab95aa018bf5 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions sequences ;
+USING: kernel math math.functions sequences project-euler.common ;
 IN: project-euler.100
 
 ! http://projecteuler.net/index.php?section=problems&id=100
@@ -33,4 +33,4 @@ IN: project-euler.100
 ! [ euler100 ] 100 ave-time
 ! 0 ms ave run time - 0.14 SD (100 trials)
 
-MAIN: euler100
+SOLUTION: euler100
index 742fe9d625b324b3c9f739026041a0ad9f392f0f..174618e1471723c5b76abea869240e7be17d1c59 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.ranges sequences ;
+USING: kernel math math.ranges sequences project-euler.common ;
 IN: project-euler.116
 
 ! http://projecteuler.net/index.php?section=problems&id=116
@@ -57,4 +57,4 @@ PRIVATE>
 ! [ euler116 ] 100 ave-time
 ! 0 ms ave run time - 0.34 SD (100 trials)
 
-MAIN: euler116
+SOLUTION: euler116
index b90a98173ee887f8286e56ac9c586734c19310c9..cb485d3ce237fbef8b8fff6d32c19a73cc2e5b9a 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.order sequences splitting ;
+USING: kernel math math.order sequences splitting project-euler.common ;
 IN: project-euler.117
 
 ! http://projecteuler.net/index.php?section=problems&id=117
@@ -41,4 +41,4 @@ PRIVATE>
 ! [ euler117 ] 100 ave-time
 ! 0 ms ave run time - 0.29 SD (100 trials)
 
-MAIN: euler117
+SOLUTION: euler117
index 0f009919d9ddde0c399627540d54839e4d3c2caf..ef1cf30dc0e22576d0c2fd3d643e6687a61b29d4 100644 (file)
@@ -45,4 +45,4 @@ PRIVATE>
 ! [ euler134 ] 10 ave-time
 ! 933 ms ave run timen - 19.58 SD (10 trials)
 
-MAIN: euler134
+SOLUTION: euler134
index 5aa0299dda1a7b8b904beb355376e6dbfcb0ea79..582e103e56538a67579b1e680b6cef9ea2b0ec28 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions sequences ;
+USING: kernel math math.functions sequences project-euler.common ;
 IN: project-euler.148
 
 ! http://projecteuler.net/index.php?section=problems&id=148
@@ -51,4 +51,4 @@ PRIVATE>
 ! [ euler148 ] 100 ave-time
 ! 0 ms ave run time - 0.17 SD (100 trials)
 
-MAIN: euler148
+SOLUTION: euler148
index 1b84b25d37a1b27dedaec1731dd396102b431a2e..e013e165751fc7128e4ee3b71b2833052bbef935 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: hints kernel locals math math.order sequences sequences.private ;
+USING: hints kernel locals math math.order sequences sequences.private project-euler.common ;
 IN: project-euler.150
 
 ! http://projecteuler.net/index.php?section=problems&id=150
@@ -75,4 +75,4 @@ PRIVATE>
 ! [ euler150 ] 10 ave-time
 ! 30208 ms ave run time - 593.45 SD (10 trials)
 
-MAIN: euler150
+SOLUTION: euler150
index 7913cf954012924ab3976a44c7286b5b9a1cd5bc..66c5a6301edad0832b9f3e56a77db20bbc73d1e1 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs combinators kernel math math.order namespaces sequences ;
+USING: assocs combinators kernel math math.order namespaces sequences project-euler.common ;
 IN: project-euler.151
 
 ! http://projecteuler.net/index.php?section=problems&id=151
@@ -76,4 +76,4 @@ DEFER: (euler151)
 ! [ euler151 ] 100 ave-time
 ! ? ms run time - 100 trials
 
-MAIN: euler151
+SOLUTION: euler151
index 5bc4fdc74e3026162e52c9f45c9fc1fa9dd77475..cea1472c0bf67095ce32fb0b9803367361044df1 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays assocs kernel math math.ranges sequences ;
+USING: arrays assocs kernel math math.ranges sequences project-euler.common ;
 IN: project-euler.164
 
 ! http://projecteuler.net/index.php?section=problems&id=164
@@ -35,4 +35,4 @@ PRIVATE>
 ! [ euler164 ] 100 ave-time
 ! 7 ms ave run time - 1.23 SD (100 trials)
 
-MAIN: euler164
+SOLUTION: euler164
index ef43fc3c340cdc97b5883ac19828f1d4fa61757d..5f0b853f0db998207cbe1d9787bdd85fc4cc7bef 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
 IN: project-euler.169
-USING: combinators kernel math math.functions memoize ;
+USING: combinators kernel math math.functions memoize project-euler.common ;
 
 ! http://projecteuler.net/index.php?section=problems&id=169
 
@@ -39,4 +39,4 @@ MEMO: fn ( n -- x )
 ! [ euler169 ] 100 ave-time
 ! 0 ms ave run time - 0.2 SD (100 trials)
 
-MAIN: euler169
+SOLUTION: euler169
index 757dfb017a223b339586fb3153a19e50f15ca9a8..3fbef562eba2c9652fc656151f1f5d85207dd0f1 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.functions math.ranges sequences ;
+USING: kernel math math.functions math.ranges sequences project-euler.common ;
 IN: project-euler.173
 
 ! http://projecteuler.net/index.php?section=problems&id=173
@@ -35,4 +35,4 @@ PRIVATE>
 ! [ euler173 ] 100 ave-time
 ! 0 ms ave run time - 0.35 SD (100 trials)
 
-MAIN: euler173
+SOLUTION: euler173
index 9aebcf565cc44ab575187cf45726fb69b4bc0129..c99d670808a905f51d6b908a755dd440859b85fd 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2007 Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel math math.parser math.ranges sequences vectors ;
+USING: combinators kernel math math.parser math.ranges sequences vectors project-euler.common ;
 IN: project-euler.175
 
 ! http://projecteuler.net/index.php?section=problems&id=175
@@ -55,4 +55,4 @@ PRIVATE>
 ! [ euler175 ] 100 ave-time
 ! 0 ms ave run time - 0.31 SD (100 trials)
 
-MAIN: euler175
+SOLUTION: euler175
index 679748b3c2fb694e61c38ae9bec8b13680205a42..a9e62ec3a90033659b83aff90487b0b1afc466a0 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: circular disjoint-sets kernel math math.ranges sequences ;
+USING: circular disjoint-sets kernel math math.ranges sequences project-euler.common ;
 IN: project-euler.186
 
 ! http://projecteuler.net/index.php?section=problems&id=186
@@ -73,4 +73,4 @@ IN: project-euler.186
 ! [ euler186 ] 10 ave-time
 ! 18572 ms ave run time - 796.87 SD (10 trials)
 
-MAIN: euler186
+SOLUTION: euler186
index 84ab74bb031177a7c0dddd9c3006518cb40718ec..ec52af041524405c6a4c95eaff8b9a1b021d9185 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences math math.functions math.ranges locals ;
+USING: kernel sequences math math.functions math.ranges locals project-euler.common ;
 IN: project-euler.190
 
 ! http://projecteuler.net/index.php?section=problems&id=190
@@ -51,4 +51,4 @@ PRIVATE>
 ! [ euler150 ] 100 ave-time
 ! 5 ms ave run time - 1.01 SD (100 trials)
 
-MAIN: euler190
+SOLUTION: euler190
index f2b5a2e212e10ba6791686ab74d4a4dda141b98b..2f165f654889b1106d473334feddb20098738a75 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: fry kernel math math.primes.factors sequences sets ;
+USING: fry kernel math math.primes.factors sequences sets project-euler.common ;
 IN: project-euler.203
 
 ! http://projecteuler.net/index.php?section=problems&id=203
@@ -61,4 +61,4 @@ PRIVATE>
 ! [ euler203 ] 100 ave-time
 ! 12 ms ave run time - 1.6 SD (100 trials)
 
-MAIN: euler203
+SOLUTION: euler203
index 297fb69de377aa61b9c7b306cad24778802567a6..30c42cc4be2b5855a56d90556b903f1497db8d58 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (c) 2008 Eric Mertens.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel locals math ;
+USING: accessors kernel locals math project-euler.common ;
 IN: project-euler.215
 
 ! http://projecteuler.net/index.php?section=problems&id=215
@@ -89,4 +89,4 @@ PRIVATE>
 ! [ euler215 ] 100 ave-time
 ! 208 ms ave run time - 9.06 SD (100 trials)
 
-MAIN: euler215
+SOLUTION: euler215
index ac8986b3ffbef338a200a0ba625f2f34dce20184..c2ffe26d949cbdbeefaf594651d0a4966d7f4d61 100644 (file)
@@ -1,8 +1,10 @@
-! Copyright (c) 2007-2008 Aaron Schaefer.
+! Copyright (c) 2007-2009 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel make math math.functions math.matrices math.miller-rabin
-    math.order math.parser math.primes.factors math.ranges math.ratios
-    sequences sorting strings unicode.case ;
+USING: accessors arrays kernel lists make math math.functions math.matrices
+    math.miller-rabin math.order math.parser math.primes.factors
+    math.primes.lists math.ranges math.ratios namespaces parser prettyprint
+    quotations sequences sorting strings unicode.case vocabs vocabs.parser
+    words ;
 IN: project-euler.common
 
 ! A collection of words used by more than one Project Euler solution
@@ -15,11 +17,13 @@ IN: project-euler.common
 ! log10 - #25, #134
 ! max-path - #18, #67
 ! mediant - #71, #73
+! nth-prime - #7, #69
 ! nth-triangle - #12, #42
 ! number>digits - #16, #20, #30, #34, #35, #38, #43, #52, #55, #56, #92
 ! palindrome? - #4, #36, #55
 ! pandigital? - #32, #38
 ! pentagonal? - #44, #45
+! penultimate - #69, #71
 ! propagate-all - #18, #67
 ! sum-proper-divisors - #21
 ! tau* - #12
@@ -43,7 +47,7 @@ IN: project-euler.common
 
 : (sum-divisors) ( n -- sum )
     dup sqrt >integer [1,b] [
-        [ 2dup mod 0 = [ 2dup / + , ] [ drop ] if ] each
+        [ 2dup divisor? [ 2dup / + , ] [ drop ] if ] each
         dup perfect-square? [ sqrt >fixnum neg , ] [ drop ] if
     ] { } make sum ;
 
@@ -56,7 +60,7 @@ PRIVATE>
     >lower [ CHAR: a - 1+ ] sigma ;
 
 : cartesian-product ( seq1 seq2 -- seq1xseq2 )
-    swap [ swap [ 2array ] with map ] with map concat ;
+    [ [ 2array ] with map ] curry map concat ;
 
 : log10 ( m -- n )
     log 10 log / ;
@@ -74,6 +78,12 @@ PRIVATE>
 : number>digits ( n -- seq )
     [ dup 0 = not ] [ 10 /mod ] produce reverse nip ;
 
+: number-length ( n -- m )
+    log10 floor 1+ >integer ;
+
+: nth-prime ( n -- n )
+    1- lprimes lnth ;
+
 : nth-triangle ( n -- n )
     dup 1+ * 2 / ;
 
@@ -86,6 +96,9 @@ PRIVATE>
 : pentagonal? ( n -- ? )
     dup 0 > [ 24 * 1+ sqrt 1+ 6 / 1 mod zero? ] [ drop f ] if ;
 
+: penultimate ( seq -- elt )
+    dup length 2 - swap nth ;
+
 ! Not strictly needed, but it is nice to be able to dump the triangle after the
 ! propagation
 : propagate-all ( triangle -- new-triangle )
@@ -116,7 +129,7 @@ PRIVATE>
     factor-2s dup [ 1+ ]
     [ perfect-square? -1 0 ? ]
     [ dup sqrt >fixnum [1,b] ] tri* [
-        dupd mod 0 = [ [ 2 + ] dip ] when
+        dupd divisor? [ [ 2 + ] dip ] when
     ] each drop * ;
 
 ! These transforms are for generating primitive Pythagorean triples
@@ -127,3 +140,9 @@ PRIVATE>
 : d-transform ( triple -- new-triple )
     { { -1 -2 -2 } { 2 1 2 } { 2 2 3 } } transform ;
 
+SYNTAX: SOLUTION:
+    scan-word
+    [ name>> "-main" append create-in ] keep
+    [ drop in get vocab (>>main) ]
+    [ [ . ] swap prefix (( -- )) define-declared ]
+    2bi ;
index f5bc95a8f713f41e36920a15be1a9503e094d3cd..95d364421500c6c50c315db2c6180d2256040e10 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2007, 2008 Aaron Schaefer, Samuel Tardieu.
+! Copyright (c) 2007-2009 Aaron Schaefer, Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: definitions io io.files io.pathnames kernel math math.parser
     prettyprint project-euler.ave-time sequences vocabs vocabs.loader
@@ -14,14 +14,15 @@ USING: definitions io io.files io.pathnames kernel math math.parser
     project-euler.037 project-euler.038 project-euler.039 project-euler.040
     project-euler.041 project-euler.042 project-euler.043 project-euler.044
     project-euler.045 project-euler.046 project-euler.047 project-euler.048
-    project-euler.052 project-euler.053 project-euler.055 project-euler.056
-    project-euler.057 project-euler.059 project-euler.067 project-euler.071
-    project-euler.073 project-euler.075 project-euler.076 project-euler.079
-    project-euler.092 project-euler.097 project-euler.099 project-euler.100
-    project-euler.116 project-euler.117 project-euler.134 project-euler.148
-    project-euler.150 project-euler.151 project-euler.164 project-euler.169
-    project-euler.173 project-euler.175 project-euler.186 project-euler.190
-    project-euler.203 project-euler.215 ;
+    project-euler.049 project-euler.052 project-euler.053 project-euler.054
+    project-euler.055 project-euler.056 project-euler.057 project-euler.058
+    project-euler.059 project-euler.063 project-euler.067 project-euler.069
+    project-euler.071 project-euler.073 project-euler.075 project-euler.076
+    project-euler.079 project-euler.092 project-euler.097 project-euler.099
+    project-euler.100 project-euler.116 project-euler.117 project-euler.134
+    project-euler.148 project-euler.150 project-euler.151 project-euler.164
+    project-euler.169 project-euler.173 project-euler.175 project-euler.186
+    project-euler.190 project-euler.203 project-euler.215 ;
 IN: project-euler
 
 <PRIVATE
@@ -44,8 +45,8 @@ PRIVATE>
 
 : run-project-euler ( -- )
     problem-prompt dup problem-solved? [
+        "Answer: " write
         dup number>euler "project-euler." prepend run
-        "Answer: " write dup number? [ number>string ] when print
         "Source: " write solution-path .
     ] [
         drop "That problem has not been solved yet..." print
diff --git a/extra/promises/authors.txt b/extra/promises/authors.txt
deleted file mode 100644 (file)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/promises/promises-docs.factor b/extra/promises/promises-docs.factor
deleted file mode 100755 (executable)
index 4e8dc9a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-! Copyright (C) 2006 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-
-USING: help.markup help.syntax ;
-IN: promises
-
-HELP: promise 
-{ $values { "quot" { $quotation "( -- X )" } } { "promise" "a promise object" } }
-{ $description "Creates a promise to return a value. When forced this quotation is called and the value returned. The value is memorised so that calling " { $link force } " again does not call the quotation again, instead the previous value is returned directly." } 
-{ $see-also force promise-with promise-with2 } ;
-
-HELP: promise-with
-{ $values { "value" "an object" } { "quot" { $quotation "( value -- X )" } } { "promise" "a promise object" } }
-{ $description "Creates a promise to return a value. When forced this quotation is called with the given value on the stack and the result returned. The value is memorised so that calling " { $link force } " again does not call the quotation again, instead the previous value is returned directly." } 
-{ $see-also force promise promise-with2 } ;
-
-HELP: promise-with2
-{ $values { "value1" "an object" } { "value2" "an object" } { "quot" { $quotation "( value1 value2 -- X )" } } { "promise" "a promise object" } }
-{ $description "Creates a promise to return a value. When forced this quotation is called with the given values on the stack and the result returned. The value is memorised so that calling " { $link force } " again does not call the quotation again, instead the previous value is returned directly." } 
-{ $see-also force promise promise-with2 } ;
-
-HELP: force
-{ $values { "promise" "a promise object" } { "value" "a factor object" } }
-{ $description "Calls the quotation associated with the promise if it has not been called before, and returns the value. If the promise has been forced previously, returns the value from the previous call." } 
-{ $see-also promise promise-with promise-with2 } ;
-
-HELP: LAZY:
-{ $syntax "LAZY: word definition... ;" } 
-{ $values { "word" "a new word to define" } { "definition" "a word definition" } }
-{ $description "Creates a lazy word in the current vocabulary. When executed the word will return a " { $link promise } " that when forced, executes the word definition. Any values on the stack that are required by the word definition are captured along with the promise." } 
-{ $examples
-  { $example "USING: arrays sequences prettyprint promises ;" "IN: scratchpad" "LAZY: zeroes ( -- pair ) 0 zeroes 2array ;" "zeroes force second force first ." "0" }
-}
-{ $see-also force promise-with promise-with2 } ;
diff --git a/extra/promises/promises.factor b/extra/promises/promises.factor
deleted file mode 100755 (executable)
index bec2761..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-! Copyright (C) 2004, 2006 Chris Double, Matthew Willis.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel sequences math vectors arrays namespaces call
-make quotations parser effects stack-checker words accessors ;
-IN: promises
-
-TUPLE: promise quot forced? value ;
-
-: promise ( quot -- promise )
-  f f \ promise boa ;
-
-: promise-with ( value quot -- promise )
-  curry promise ;
-
-: promise-with2 ( value1 value2 quot -- promise )
-  2curry 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 forced?>> [
-        dup quot>> call( -- value ) >>value
-        t >>forced?
-    ] unless
-    value>> ;
-
-: stack-effect-in ( quot word -- n )
-  stack-effect [ ] [ infer ] ?if in>> length ;
-
-: make-lazy-quot ( word quot -- quot )
-  [
-    dup ,
-    swap stack-effect-in \ curry <repetition> % 
-    \ promise ,
-  ] [ ] make ;
-
-: LAZY:
-  CREATE-WORD
-  dup parse-definition
-  make-lazy-quot define ; parsing
diff --git a/extra/promises/summary.txt b/extra/promises/summary.txt
deleted file mode 100644 (file)
index d64fe20..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Lazy thunks
diff --git a/extra/promises/tags.txt b/extra/promises/tags.txt
deleted file mode 100644 (file)
index f427429..0000000
+++ /dev/null
@@ -1 +0,0 @@
-extensions
index 1a916c74f4aa79ef01c03a29b26982add1842006..6fe361b556c565ae6a39052a925fde8243909f57 100644 (file)
@@ -194,5 +194,5 @@ M: quadtree clear-assoc ( assoc -- )
 : swizzle ( sequence quot -- sequence' )
     [ dup ] dip map
     [ zip ] [ rect-containing <quadtree> ] bi
-    [ '[ first2 _ set-at ] each ] [ values ] bi ;
+    [ '[ first2 _ set-at ] each ] [ values ] bi ; inline
 
diff --git a/extra/robots/authors.txt b/extra/robots/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/robots/robots-tests.factor b/extra/robots/robots-tests.factor
new file mode 100644 (file)
index 0000000..54b4892
--- /dev/null
@@ -0,0 +1,335 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: calendar io.encodings.utf8 io.files robots tools.test
+urls ;
+IN: robots.tests
+
+[
+    { "http://www.chiplist.com/sitemap.txt" }
+    {
+        T{ rules
+            { user-agents V{ "*" } }
+            { allows V{ } }
+            { disallows
+                V{
+                    URL" /cgi-bin/"
+                    URL" /scripts/"
+                    URL" /ChipList2/scripts/"
+                    URL" /ChipList2/styles/"
+                    URL" /ads/"
+                    URL" /ChipList2/ads/"
+                    URL" /advertisements/"
+                    URL" /ChipList2/advertisements/"
+                    URL" /graphics/"
+                    URL" /ChipList2/graphics/"
+                }
+            }
+            { visit-time
+                {
+                    T{ timestamp { hour 2 } }
+                    T{ timestamp { hour 5 } }
+                }
+            }
+            { request-rate 1 }
+            { crawl-delay 1 }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "UbiCrawler" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "DOC" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Zao" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "sitecheck.internetseer.com" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Zealbot" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "MSIECrawler" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "SiteSnagger" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "WebStripper" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "WebCopier" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Fetch" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Offline Explorer" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Teleport" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "TeleportPro" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "WebZIP" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "linko" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "HTTrack" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Microsoft.URL.Control" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Xenu" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "larbin" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "libwww" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "ZyBORG" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "Download Ninja" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "wget" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "grub-client" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "k2spider" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "NPBot" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents V{ "WebReaper" } }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+        T{ rules
+            { user-agents
+                V{
+                    "abot"
+                    "ALeadSoftbot"
+                    "BeijingCrawler"
+                    "BilgiBot"
+                    "bot"
+                    "botlist"
+                    "BOTW Spider"
+                    "bumblebee"
+                    "Bumblebee"
+                    "BuzzRankingBot"
+                    "Charlotte"
+                    "Clushbot"
+                    "Crawler"
+                    "CydralSpider"
+                    "DataFountains"
+                    "DiamondBot"
+                    "Dulance bot"
+                    "DYNAMIC"
+                    "EARTHCOM.info"
+                    "EDI"
+                    "envolk"
+                    "Exabot"
+                    "Exabot-Images"
+                    "Exabot-Test"
+                    "exactseek-pagereaper"
+                    "Exalead NG"
+                    "FANGCrawl"
+                    "Feed::Find"
+                    "flatlandbot"
+                    "Gigabot"
+                    "GigabotSiteSearch"
+                    "GurujiBot"
+                    "Hatena Antenna"
+                    "Hatena Bookmark"
+                    "Hatena RSS"
+                    "HatenaScreenshot"
+                    "Helix"
+                    "HiddenMarket"
+                    "HyperEstraier"
+                    "iaskspider"
+                    "IIITBOT"
+                    "InfociousBot"
+                    "iVia"
+                    "iVia Page Fetcher"
+                    "Jetbot"
+                    "Kolinka Forum Search"
+                    "KRetrieve"
+                    "LetsCrawl.com"
+                    "Lincoln State Web Browser"
+                    "Links4US-Crawler"
+                    "LOOQ"
+                    "Lsearch/sondeur"
+                    "MapoftheInternet.com"
+                    "NationalDirectory"
+                    "NetCarta_WebMapper"
+                    "NewsGator"
+                    "NextGenSearchBot"
+                    "ng"
+                    "nicebot"
+                    "NP"
+                    "NPBot"
+                    "Nudelsalat"
+                    "Nutch"
+                    "OmniExplorer_Bot"
+                    "OpenIntelligenceData"
+                    "Oracle Enterprise Search"
+                    "Pajaczek"
+                    "panscient.com"
+                    "PeerFactor 404 crawler"
+                    "PeerFactor Crawler"
+                    "PlantyNet"
+                    "PlantyNet_WebRobot"
+                    "plinki"
+                    "PMAFind"
+                    "Pogodak!"
+                    "QuickFinder Crawler"
+                    "Radiation Retriever"
+                    "Reaper"
+                    "RedCarpet"
+                    "ScorpionBot"
+                    "Scrubby"
+                    "Scumbot"
+                    "searchbot"
+                    "Seeker.lookseek.com"
+                    "SeznamBot"
+                    "ShowXML"
+                    "snap.com"
+                    "snap.com beta crawler"
+                    "Snapbot"
+                    "SnapPreviewBot"
+                    "sohu"
+                    "SpankBot"
+                    "Speedy Spider"
+                    "Speedy_Spider"
+                    "SpeedySpider"
+                    "spider"
+                    "SquigglebotBot"
+                    "SurveyBot"
+                    "SynapticSearch"
+                    "T-H-U-N-D-E-R-S-T-O-N-E"
+                    "Talkro Web-Shot"
+                    "Tarantula"
+                    "TerrawizBot"
+                    "TheInformant"
+                    "TMCrawler"
+                    "TridentSpider"
+                    "Tutorial Crawler"
+                    "Twiceler"
+                    "unwrapbot"
+                    "URI::Fetch"
+                    "VengaBot"
+                    "Vonna.com b o t"
+                    "Vortex"
+                    "Votay bot"
+                    "WebAlta Crawler"
+                    "Webbot"
+                    "Webclipping.com"
+                    "WebCorp"
+                    "Webinator"
+                    "WIRE"
+                    "WISEbot"
+                    "Xerka WebBot"
+                    "XSpider"
+                    "YodaoBot"
+                    "Yoono"
+                    "yoono"
+                }
+            }
+            { allows V{ } }
+            { disallows V{ URL" /" } }
+            { unknowns H{ } }
+        }
+    }
+] [ "vocab:robots/robots.txt" utf8 file-contents parse-robots.txt ] unit-test
diff --git a/extra/robots/robots.factor b/extra/robots/robots.factor
new file mode 100644 (file)
index 0000000..3c0eb04
--- /dev/null
@@ -0,0 +1,92 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors http.client kernel unicode.categories
+sequences urls splitting combinators splitting.monotonic
+combinators.short-circuit assocs unicode.case arrays
+math.parser calendar.format make fry present globs
+multiline regexp.combinators regexp ;
+IN: robots
+
+! visit-time is GMT, request-rate is pages/second 
+! crawl-rate is seconds
+
+TUPLE: robots site sitemap rules rules-quot ;
+
+: <robots> ( site sitemap rules -- robots )
+    \ robots new
+        swap >>rules
+        swap >>sitemap
+        swap >>site ;
+
+TUPLE: rules user-agents allows disallows
+visit-time request-rate crawl-delay unknowns ;
+
+<PRIVATE
+
+: >robots.txt-url ( url -- url' )
+    >url URL" robots.txt" derive-url ;
+
+: get-robots.txt ( url -- headers robots.txt )
+    >robots.txt-url http-get ;
+
+: normalize-robots.txt ( string -- sitemaps seq )
+    string-lines
+    [ [ blank? ] trim ] map
+    [ "#" head? not ] filter harvest
+    [ ":" split1 [ [ blank? ] trim ] bi@ [ >lower ] dip  ] { } map>assoc
+    [ first "sitemap" = ] partition [ values ] dip
+    [
+        {
+            [ [ first "user-agent" = ] bi@ and ]
+            [ nip first "user-agent" = not ]
+        } 2|| 
+    ] monotonic-split ;
+
+: <rules> ( -- rules )
+    rules new
+        V{ } clone >>user-agents
+        V{ } clone >>allows
+        V{ } clone >>disallows
+        H{ } clone >>unknowns ;
+
+: add-user-agent ( rules agent -- rules ) over user-agents>> push ;
+: add-allow ( rules allow -- rules ) >url over allows>> push ;
+: add-disallow ( rules disallow -- rules ) >url over disallows>> push ;
+
+: parse-robots.txt-line ( rules seq -- rules )
+    first2 swap {
+        { "user-agent" [ add-user-agent ] }
+        { "allow" [ add-allow ] }
+        { "disallow" [ add-disallow ] }
+        { "crawl-delay" [ string>number >>crawl-delay ] }
+        { "request-rate" [ string>number >>request-rate ] }
+        {
+            "visit-time" [ "-" split1 [ hhmm>timestamp ] bi@ 2array
+            >>visit-time
+        ] }
+        [ pick unknowns>> push-at ]
+    } case ;
+
+: derive-urls ( url seq -- seq' )
+    [ derive-url present ] with { } map-as ;
+
+: robot-rules-quot ( robots -- quot )
+    [
+        [ site>> ] [ rules>> allows>> ] bi
+        derive-urls [ <glob> ] map
+        <or>
+    ] [
+        [ site>> ] [ rules>> disallows>> ] bi
+        derive-urls [ <glob> ] map <and> <not>
+    ] bi 2array <or> '[ _ matches? ] ;
+
+PRIVATE>
+
+: parse-robots.txt ( string -- sitemaps rules-seq )
+    normalize-robots.txt [
+        [ <rules> dup ] dip [ parse-robots.txt-line drop ] with each
+    ] map ;
+
+: robots ( url -- robots )
+    >url
+    dup get-robots.txt nip parse-robots.txt <robots> ;
diff --git a/extra/robots/robots.txt b/extra/robots/robots.txt
new file mode 100644 (file)
index 0000000..bbaaee6
--- /dev/null
@@ -0,0 +1,279 @@
+
+
+# robots.txt
+
+Sitemap: http://www.chiplist.com/sitemap.txt
+
+User-Agent: *
+
+Disallow: /cgi-bin/
+Disallow: /scripts/
+Disallow: /ChipList2/scripts/
+#Disallow: /styles/
+Disallow: /ChipList2/styles/
+
+Disallow: /ads/
+Disallow: /ChipList2/ads/
+Disallow: /advertisements/
+Disallow: /ChipList2/advertisements/
+
+Disallow: /graphics/
+Disallow: /ChipList2/graphics/
+
+#Disallow: /ChipList1/
+
+
+# robots.txt for http://www.wikipedia.org/ and friends
+#
+# Please note: There are a lot of pages on this site, and there are
+# some misbehaved spiders out there that go _way_ too fast. If you're
+# irresponsible, your access to the site may be blocked.
+
+# Inktomi's "Slurp" can read a minimum delay between hits; if your
+# bot supports such a thing using the 'Crawl-delay' or another
+# instruction, please let us know.
+
+# *at least* 1 second please. preferably more :D
+#User-agent: *
+Crawl-delay: 1
+Request-rate: 1/1
+Visit-time: 0200-0500
+
+# Crawlers that are kind enough to obey, but which we'd rather not have
+# unless they're feeding search engines.
+User-agent: UbiCrawler
+Disallow: /
+
+User-agent: DOC
+Disallow: /
+
+User-agent: Zao
+Disallow: /
+
+# Some bots are known to be trouble, particularly those designed to copy
+# entire sites. Please obey robots.txt.
+User-agent: sitecheck.internetseer.com
+Disallow: /
+
+User-agent: Zealbot
+Disallow: /
+
+User-agent: MSIECrawler
+Disallow: /
+
+User-agent: SiteSnagger
+Disallow: /
+
+User-agent: WebStripper
+Disallow: /
+
+User-agent: WebCopier
+Disallow: /
+
+User-agent: Fetch
+Disallow: /
+
+User-agent: Offline Explorer
+Disallow: /
+
+User-agent: Teleport
+Disallow: /
+
+User-agent: TeleportPro
+Disallow: /
+
+User-agent: WebZIP
+Disallow: /
+
+User-agent: linko
+Disallow: /
+
+User-agent: HTTrack
+Disallow: /
+
+User-agent: Microsoft.URL.Control
+Disallow: /
+
+User-agent: Xenu
+Disallow: /
+
+User-agent: larbin
+Disallow: /
+
+User-agent: libwww
+Disallow: /
+
+User-agent: ZyBORG
+Disallow: /
+
+User-agent: Download Ninja
+Disallow: /
+
+#
+# Sorry, wget in its recursive mode is a frequent problem.
+# Please read the man page and use it properly; there is a
+# --wait option you can use to set the delay between hits,
+# for instance.
+#
+User-agent: wget
+Disallow: /
+
+#
+# The 'grub' distributed client has been *very* poorly behaved.
+#
+User-agent: grub-client
+Disallow: /
+
+#
+# Doesn't follow robots.txt anyway, but...
+#
+User-agent: k2spider
+Disallow: /
+
+#
+# Hits many times per second, not acceptable
+# http://www.nameprotect.com/botinfo.html
+User-agent: NPBot
+Disallow: /
+
+# A capture bot, downloads gazillions of pages with no public benefit
+# http://www.webreaper.net/
+User-agent: WebReaper
+Disallow: /
+
+
+# Provided courtesy of http://browsers.garykeith.com.
+# Created on February 13, 2008 at 7:39:00 PM GMT.
+#
+# Place this file in the root public folder of your website.
+# It will stop the following bots from indexing your website.
+#
+User-agent: abot
+User-agent: ALeadSoftbot
+User-agent: BeijingCrawler
+User-agent: BilgiBot
+User-agent: bot
+User-agent: botlist
+User-agent: BOTW Spider
+User-agent: bumblebee
+User-agent: Bumblebee
+User-agent: BuzzRankingBot
+User-agent: Charlotte
+User-agent: Clushbot
+User-agent: Crawler
+User-agent: CydralSpider
+User-agent: DataFountains
+User-agent: DiamondBot
+User-agent: Dulance bot
+User-agent: DYNAMIC
+User-agent: EARTHCOM.info
+User-agent: EDI
+User-agent: envolk
+User-agent: Exabot
+User-agent: Exabot-Images
+User-agent: Exabot-Test
+User-agent: exactseek-pagereaper
+User-agent: Exalead NG
+User-agent: FANGCrawl
+User-agent: Feed::Find
+User-agent: flatlandbot
+User-agent: Gigabot
+User-agent: GigabotSiteSearch
+User-agent: GurujiBot
+User-agent: Hatena Antenna
+User-agent: Hatena Bookmark
+User-agent: Hatena RSS
+User-agent: HatenaScreenshot
+User-agent: Helix
+User-agent: HiddenMarket
+User-agent: HyperEstraier
+User-agent: iaskspider
+User-agent: IIITBOT
+User-agent: InfociousBot
+User-agent: iVia
+User-agent: iVia Page Fetcher
+User-agent: Jetbot
+User-agent: Kolinka Forum Search
+User-agent: KRetrieve
+User-agent: LetsCrawl.com
+User-agent: Lincoln State Web Browser
+User-agent: Links4US-Crawler
+User-agent: LOOQ
+User-agent: Lsearch/sondeur
+User-agent: MapoftheInternet.com
+User-agent: NationalDirectory
+User-agent: NetCarta_WebMapper
+User-agent: NewsGator
+User-agent: NextGenSearchBot
+User-agent: ng
+User-agent: nicebot
+User-agent: NP
+User-agent: NPBot
+User-agent: Nudelsalat
+User-agent: Nutch
+User-agent: OmniExplorer_Bot
+User-agent: OpenIntelligenceData
+User-agent: Oracle Enterprise Search
+User-agent: Pajaczek
+User-agent: panscient.com
+User-agent: PeerFactor 404 crawler
+User-agent: PeerFactor Crawler
+User-agent: PlantyNet
+User-agent: PlantyNet_WebRobot
+User-agent: plinki
+User-agent: PMAFind
+User-agent: Pogodak!
+User-agent: QuickFinder Crawler
+User-agent: Radiation Retriever
+User-agent: Reaper
+User-agent: RedCarpet
+User-agent: ScorpionBot
+User-agent: Scrubby
+User-agent: Scumbot
+User-agent: searchbot
+User-agent: Seeker.lookseek.com
+User-agent: SeznamBot
+User-agent: ShowXML
+User-agent: snap.com
+User-agent: snap.com beta crawler
+User-agent: Snapbot
+User-agent: SnapPreviewBot
+User-agent: sohu
+User-agent: SpankBot
+User-agent: Speedy Spider
+User-agent: Speedy_Spider
+User-agent: SpeedySpider
+User-agent: spider
+User-agent: SquigglebotBot
+User-agent: SurveyBot
+User-agent: SynapticSearch
+User-agent: T-H-U-N-D-E-R-S-T-O-N-E
+User-agent: Talkro Web-Shot
+User-agent: Tarantula
+User-agent: TerrawizBot
+User-agent: TheInformant
+User-agent: TMCrawler
+User-agent: TridentSpider
+User-agent: Tutorial Crawler
+User-agent: Twiceler
+User-agent: unwrapbot
+User-agent: URI::Fetch
+User-agent: VengaBot
+User-agent: Vonna.com b o t
+User-agent: Vortex
+User-agent: Votay bot
+User-agent: WebAlta Crawler
+User-agent: Webbot
+User-agent: Webclipping.com
+User-agent: WebCorp
+User-agent: Webinator
+User-agent: WIRE
+User-agent: WISEbot
+User-agent: Xerka WebBot
+User-agent: XSpider
+User-agent: YodaoBot
+User-agent: Yoono
+User-agent: yoono
+Disallow: /
+
+
diff --git a/extra/sequence-parser/sequence-parser-tests.factor b/extra/sequence-parser/sequence-parser-tests.factor
new file mode 100644 (file)
index 0000000..3b2fcad
--- /dev/null
@@ -0,0 +1,191 @@
+USING: tools.test sequence-parser ascii kernel accessors ;
+IN: sequence-parser.tests
+
+[ "hello" ]
+[ "hello" [ take-rest ] parse-sequence ] unit-test
+
+[ "hi" " how are you?" ]
+[
+    "hi how are you?"
+    [ [ [ current blank? ] take-until ] [ take-rest ] bi ] parse-sequence
+] unit-test
+
+[ "foo" ";bar" ]
+[
+    "foo;bar" [
+        [ CHAR: ; take-until-object ] [ take-rest ] bi
+    ] parse-sequence
+] unit-test
+
+[ "foo " "and bar" ]
+[
+    "foo and bar" [
+        [ "and" take-until-sequence ] [ take-rest ] bi 
+    ] parse-sequence
+] unit-test
+
+[ "foo " " bar" ]
+[
+    "foo and bar" [
+        [ "and" take-until-sequence ]
+        [ "and" take-sequence drop ]
+        [ take-rest ] tri
+    ] parse-sequence
+] unit-test
+
+[ "foo " " bar" ]
+[
+    "foo and bar" [
+        [ "and" take-until-sequence* ]
+        [ take-rest ] bi
+    ] parse-sequence
+] unit-test
+
+[ { 1 2 } ]
+[ { 1 2 3 4 } <sequence-parser> { 3 4 } take-until-sequence ] unit-test
+
+[ f "aaaa" ]
+[
+    "aaaa" <sequence-parser>
+    [ "b" take-until-sequence ] [ take-rest ] bi
+] unit-test
+
+[ 6 ]
+[
+    "      foo   " [ skip-whitespace n>> ] parse-sequence
+] unit-test
+
+[ { 1 2 } ]
+[ { 1 2 3 } <sequence-parser> [ current 3 = ] take-until ] unit-test
+
+[ "ab" ]
+[ "abcd" <sequence-parser> "ab" take-sequence ] unit-test
+
+[ f ]
+[ "abcd" <sequence-parser> "lol" take-sequence ] unit-test
+
+[ "ab" ]
+[
+    "abcd" <sequence-parser>
+    [ "lol" take-sequence drop ] [ "ab" take-sequence ] bi
+] unit-test
+
+[ "" ]
+[ "abcd" <sequence-parser> "" take-sequence ] unit-test
+
+[ "cd" ]
+[ "abcd" <sequence-parser> [ "ab" take-sequence drop ] [ "cd" take-sequence ] bi ] unit-test
+
+[ f ]
+[
+    "\"abc\" asdf" <sequence-parser>
+    [ CHAR: \ CHAR: " take-quoted-string drop ] [ "asdf" take-sequence ] bi
+] unit-test
+
+[ "abc\\\"def" ]
+[
+    "\"abc\\\"def\" asdf" <sequence-parser>
+    CHAR: \ CHAR: " take-quoted-string
+] unit-test
+
+[ "asdf" ]
+[
+    "\"abc\" asdf" <sequence-parser>
+    [ CHAR: \ CHAR: " take-quoted-string drop ]
+    [ skip-whitespace "asdf" take-sequence ] bi
+] unit-test
+
+[ f ]
+[
+    "\"abc asdf" <sequence-parser>
+    CHAR: \ CHAR: " take-quoted-string
+] unit-test
+
+[ "\"abc" ]
+[
+    "\"abc asdf" <sequence-parser>
+    [ CHAR: \ CHAR: " take-quoted-string drop ]
+    [ "\"abc" take-sequence ] bi
+] unit-test
+
+[ "c" ]
+[ "c" <sequence-parser> take-token ] unit-test
+
+[ f ]
+[ "" <sequence-parser> take-token ] unit-test
+
+[ "abcd e \\\"f g" ]
+[ "\"abcd e \\\"f g\"" <sequence-parser> CHAR: \ CHAR: " take-token* ] unit-test
+
+[ "" ]
+[ "" <sequence-parser> take-rest ] unit-test
+
+[ "" ]
+[ "abc" <sequence-parser> dup "abc" take-sequence drop take-rest ] unit-test
+
+[ f ]
+[ "abc" <sequence-parser> "abcdefg" take-sequence ] unit-test
+
+[ "1234" ]
+[ "1234f" <sequence-parser> take-integer ] unit-test
+
+[ "yes" ]
+[
+    "yes1234f" <sequence-parser>
+    [ take-integer drop ] [ "yes" take-sequence ] bi 
+] unit-test
+
+[ f ] [ "" <sequence-parser> 4 take-n ] unit-test
+[ "abcd" ] [ "abcd" <sequence-parser> 4 take-n ] unit-test
+[ "abcd" "efg" ] [ "abcdefg" <sequence-parser> [ 4 take-n ] [ take-rest ] bi ] unit-test
+
+[ "asdfasdf" ] [
+    "/*asdfasdf*/" <sequence-parser> take-c-comment 
+] unit-test
+
+[ "k" ] [
+    "/*asdfasdf*/k" <sequence-parser> [ take-c-comment drop ] [ take-rest ] bi
+] unit-test
+
+[ "omg" ] [
+    "//asdfasdf\nomg" <sequence-parser>
+    [ take-c++-comment drop ] [ take-rest ] bi
+] unit-test
+
+[ "omg" ] [
+    "omg" <sequence-parser>
+    [ take-c++-comment drop ] [ take-rest ] bi
+] unit-test
+
+[ "/*asdfasdf" ] [
+    "/*asdfasdf" <sequence-parser> [ take-c-comment drop ] [ take-rest ] bi
+] unit-test
+
+[ "asdf" "eoieoei" ] [
+    "//asdf\neoieoei" <sequence-parser>
+    [ take-c++-comment ] [ take-rest ] bi
+] unit-test
+
+[ f "33asdf" ]
+[ "33asdf" <sequence-parser> [ take-c-identifier ] [ take-rest ] bi ] unit-test
+
+[ "asdf" ]
+[ "asdf" <sequence-parser> take-c-identifier ] unit-test
+
+[ "_asdf" ]
+[ "_asdf" <sequence-parser> take-c-identifier ] unit-test
+
+[ "_asdf400" ]
+[ "_asdf400" <sequence-parser> take-c-identifier ] unit-test
+
+[ "123" ]
+[ "123jjj" <sequence-parser> take-c-integer ] unit-test
+
+[ "123uLL" ]
+[ "123uLL" <sequence-parser> take-c-integer ] unit-test
+
+[ "123ull" ]
+[ "123ull" <sequence-parser> take-c-integer ] unit-test
+
+[ "123u" ]
+[ "123u" <sequence-parser> take-c-integer ] unit-test
diff --git a/extra/sequence-parser/sequence-parser.factor b/extra/sequence-parser/sequence-parser.factor
new file mode 100644 (file)
index 0000000..4f57a7c
--- /dev/null
@@ -0,0 +1,229 @@
+! Copyright (C) 2005, 2009 Daniel Ehrenberg, Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: namespaces math kernel sequences accessors fry circular
+unicode.case unicode.categories locals combinators.short-circuit
+make combinators io splitting math.parser math.ranges
+generalizations sorting.functor math.order sorting.slots ;
+IN: sequence-parser
+
+TUPLE: sequence-parser sequence n ;
+
+: <sequence-parser> ( sequence -- sequence-parser )
+    sequence-parser new
+        swap >>sequence
+        0 >>n ;
+
+:: with-sequence-parser ( sequence-parser quot -- seq/f )
+    sequence-parser n>> :> n
+    sequence-parser quot call [
+        n sequence-parser (>>n) f
+    ] unless* ; inline
+
+: offset  ( sequence-parser offset -- char/f )
+    swap
+    [ n>> + ] [ sequence>> ?nth ] bi ; inline
+
+: current ( sequence-parser -- char/f ) 0 offset ; inline
+
+: previous ( sequence-parser -- char/f ) -1 offset ; inline
+
+: peek-next ( sequence-parser -- char/f ) 1 offset ; inline
+
+: advance ( sequence-parser -- sequence-parser )
+    [ 1 + ] change-n ; inline
+
+: advance* ( sequence-parser -- )
+    advance drop ; inline
+
+: get+increment ( sequence-parser -- char/f )
+    [ current ] [ advance drop ] bi ; inline
+
+:: skip-until ( sequence-parser quot: ( obj -- ? ) -- )
+    sequence-parser current [
+        sequence-parser quot call
+        [ sequence-parser advance quot skip-until ] unless
+    ] when ; inline recursive
+
+: sequence-parse-end? ( sequence-parser -- ? ) current not ;
+
+: take-until ( sequence-parser quot: ( obj -- ? ) -- sequence/f )
+    over sequence-parse-end? [
+        2drop f
+    ] [
+        [ drop n>> ]
+        [ skip-until ]
+        [ drop [ n>> ] [ sequence>> ] bi ] 2tri subseq
+    ] if ; inline
+
+: take-while ( sequence-parser quot: ( obj -- ? ) -- sequence/f )
+    [ not ] compose take-until ; inline
+
+: <safe-slice> ( from to seq -- slice/f )
+    3dup {
+        [ 2drop 0 < ]
+        [ [ drop ] 2dip length > ]
+        [ drop > ]
+    } 3|| [ 3drop f ] [ slice boa ] if ; inline
+
+:: take-sequence ( sequence-parser sequence -- obj/f )
+    sequence-parser [ n>> dup sequence length + ] [ sequence>> ] bi
+    <safe-slice> sequence sequence= [
+        sequence
+        sequence-parser [ sequence length + ] change-n drop
+    ] [
+        f
+    ] if ;
+
+: take-sequence* ( sequence-parser sequence -- )
+    take-sequence drop ;
+
+:: take-until-sequence ( sequence-parser sequence -- sequence'/f )
+    sequence-parser n>> :> saved
+    sequence length <growing-circular> :> growing
+    sequence-parser
+    [
+        current growing push-growing-circular
+        sequence growing sequence=
+    ] take-until :> found
+    growing sequence sequence= [
+        found dup length
+        growing length 1- - head
+        sequence-parser [ growing length - 1 + ] change-n drop
+        ! sequence-parser advance drop
+    ] [
+        saved sequence-parser (>>n)
+        f
+    ] if ;
+
+:: take-until-sequence* ( sequence-parser sequence -- sequence'/f )
+    sequence-parser sequence take-until-sequence :> out
+    out [
+        sequence-parser [ sequence length + ] change-n drop
+    ] when out ;
+
+: skip-whitespace ( sequence-parser -- sequence-parser )
+    [ [ current blank? not ] take-until drop ] keep ;
+
+: take-rest-slice ( sequence-parser -- sequence/f )
+    [ sequence>> ] [ n>> ] bi
+    2dup [ length ] dip < [ 2drop f ] [ tail-slice ] if ; inline
+
+: take-rest ( sequence-parser -- sequence )
+    [ take-rest-slice ] [ sequence>> like ] bi ;
+
+: take-until-object ( sequence-parser obj -- sequence )
+    '[ current _ = ] take-until ;
+
+: parse-sequence ( sequence quot -- )
+    [ <sequence-parser> ] dip call ; inline
+
+:: take-quoted-string ( sequence-parser escape-char quote-char -- string )
+    sequence-parser n>> :> start-n
+    sequence-parser advance
+    [
+        {
+            [ { [ previous escape-char = ] [ current quote-char = ] } 1&& ]
+            [ current quote-char = not ]
+        } 1||
+    ] take-while :> string
+    sequence-parser current quote-char = [
+        sequence-parser advance* string
+    ] [
+        start-n sequence-parser (>>n) f
+    ] if ;
+
+: (take-token) ( sequence-parser -- string )
+    skip-whitespace [ current { [ blank? ] [ f = ] } 1|| ] take-until ;
+
+:: take-token* ( sequence-parser escape-char quote-char -- string/f )
+    sequence-parser skip-whitespace
+    dup current {
+        { quote-char [ escape-char quote-char take-quoted-string ] }
+        { f [ drop f ] }
+        [ drop (take-token) ]
+    } case ;
+
+: take-token ( sequence-parser -- string/f )
+    CHAR: \ CHAR: " take-token* ;
+
+: take-integer ( sequence-parser -- n/f )
+    [ current digit? ] take-while ;
+
+:: take-n ( sequence-parser n -- seq/f )
+    n sequence-parser [ n>> + ] [ sequence>> length ] bi > [
+        f
+    ] [
+        sequence-parser n>> dup n + sequence-parser sequence>> subseq
+        sequence-parser [ n + ] change-n drop
+    ] if ;
+
+: take-c-comment ( sequence-parser -- seq/f )
+    [
+        dup "/*" take-sequence [
+            "*/" take-until-sequence*
+        ] [
+            drop f
+        ] if
+    ] with-sequence-parser ;
+
+: take-c++-comment ( sequence-parser -- seq/f )
+    [
+        dup "//" take-sequence [
+            [
+                [
+                    { [ current CHAR: \n = ] [ sequence-parse-end? ] } 1||
+                ] take-until
+            ] [
+                advance drop
+            ] bi
+        ] [
+            drop f
+        ] if
+    ] with-sequence-parser ;
+
+: c-identifier-begin? ( ch -- ? )
+    CHAR: a CHAR: z [a,b]
+    CHAR: A CHAR: Z [a,b]
+    { CHAR: _ } 3append member? ;
+
+: c-identifier-ch? ( ch -- ? )
+    CHAR: a CHAR: z [a,b]
+    CHAR: A CHAR: Z [a,b]
+    CHAR: 0 CHAR: 9 [a,b]
+    { CHAR: _ } 4 nappend member? ;
+
+: take-c-identifier ( state-parser -- string/f )
+    [
+        dup current c-identifier-begin? [
+            [ current c-identifier-ch? ] take-while
+        ] [
+            drop f
+        ] if
+    ] with-sequence-parser ;
+
+<< "length" [ length ] define-sorting >>
+
+: sort-tokens ( seq -- seq' )
+    { length>=< <=> } sort-by ;
+
+: take-first-matching ( state-parser seq -- seq )
+    swap
+    '[ _ [ swap take-sequence ] with-sequence-parser ] find nip ;
+
+
+: take-longest ( state-parser seq -- seq )
+    sort-tokens take-first-matching ;
+
+: take-c-integer ( state-parser -- string/f )
+    [
+        dup take-integer [
+            swap
+            { "ull" "uLL" "Ull" "ULL" "ll" "LL" "l" "L" "u" "U" }
+            take-longest [ append ] when*
+        ] [
+            drop f
+        ] if*
+    ] with-sequence-parser ;
+
+: write-full ( sequence-parser -- ) sequence>> write ;
+: write-rest ( sequence-parser -- ) take-rest write ;
index 6c56300f6df0fa71accbb07902b96c4e53240c9d..852fe59d8bd5925f2a02a3a1b3bf34580c800e4d 100644 (file)
@@ -10,7 +10,7 @@ HELP: <n-based-assoc>
 USING: assocs prettyprint kernel sequences.n-based ;
 IN: scratchpad
 
-: months
+: months ( -- assoc )
     {
         "January"
         "February"
@@ -36,7 +36,7 @@ HELP: n-based-assoc
 USING: assocs prettyprint kernel sequences.n-based ;
 IN: scratchpad
 
-: months
+: months ( -- assoc )
     {
         "January"
         "February"
index 7ee5bd649f241863b3211b079910d624c54e9c8a..eed5540cb39490151cf9c09ab281408c958a923d 100644 (file)
@@ -3,7 +3,7 @@ USING: kernel accessors assocs
 sequences sequences.n-based tools.test ;
 IN: sequences.n-based.tests
 
-: months
+: months ( -- assoc )
     V{
         "January"
         "February"
diff --git a/extra/site-watcher/authors.txt b/extra/site-watcher/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/site-watcher/db/authors.txt b/extra/site-watcher/db/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/site-watcher/db/db.factor b/extra/site-watcher/db/db.factor
new file mode 100644 (file)
index 0000000..003b6bb
--- /dev/null
@@ -0,0 +1,130 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors continuations db db.sqlite db.tuples db.types
+io.directories io.files.temp kernel io.streams.string calendar
+debugger combinators.smart sequences arrays ;
+IN: site-watcher.db
+
+TUPLE: account account-name email twitter sms ;
+
+: <account> ( account-name email -- account )
+    account new
+        swap >>email
+        swap >>account-name ;
+
+account "ACCOUNT" {
+    { "account-name" "ACCOUNT_NAME" VARCHAR +user-assigned-id+ }
+    { "email" "EMAIL" VARCHAR }
+    { "twitter" "TWITTER" VARCHAR }
+    { "sms" "SMS" VARCHAR }
+} define-persistent
+
+TUPLE: site site-id url up? changed? last-up error last-error ;
+
+: <site> ( url -- site )
+    site new
+        swap >>url ;
+
+: site-with-url ( url -- site )
+    <site> select-tuple ;
+
+: site-with-id ( id -- site )
+    site new swap >>site-id select-tuple ;
+
+site "SITE" {
+    { "site-id" "SITE_ID" INTEGER +db-assigned-id+ }
+    { "url" "URL" VARCHAR }
+    { "up?" "UP" BOOLEAN }
+    { "changed?" "CHANGED" BOOLEAN }
+    { "last-up" "LAST_UP" TIMESTAMP }
+    { "error" "ERROR" VARCHAR }
+    { "last-error" "LAST_ERROR" TIMESTAMP }
+} define-persistent
+
+TUPLE: watching-site account-name site-id ;
+
+: <watching-site> ( account-name site-id -- watching-site )
+    watching-site new
+        swap >>site-id
+        swap >>account-name ;
+
+watching-site "WATCHING_SITE" {
+    { "account-name" "ACCOUNT_NAME" VARCHAR +user-assigned-id+ }
+    { "site-id" "SITE_ID" INTEGER +user-assigned-id+ }
+} define-persistent
+
+TUPLE: spidering-site < watching-site max-depth max-count ;
+
+C: <spidering-site> spidering-site
+
+SLOT: site
+
+M: watching-site site>>
+    site-id>> site-with-id ;
+
+SLOT: account
+
+M: watching-site account>>
+    account-name>> account new swap >>account-name select-tuple ;
+
+spidering-site "SPIDERING_SITE" {
+    { "max-depth" "MAX_DEPTH" INTEGER }
+    { "max-count" "MAX_COUNT" INTEGER }
+} define-persistent
+
+: spidering-sites ( username -- sites )
+    spidering-site new swap >>account-name select-tuples ;
+
+: insert-site ( url -- site )
+    <site> dup select-tuple [ ] [ dup t >>up? insert-tuple ] ?if ;
+
+: select-account/site ( username url -- account site )
+    insert-site site-id>> ;
+
+: add-spidered-site ( username url -- )
+    select-account/site 10 10 <spidering-site> insert-tuple ;
+
+: remove-spidered-site ( username url -- )
+    select-account/site 10 10 <spidering-site> delete-tuples ;
+
+TUPLE: reporting-site site-id email url up? changed? last-up? error last-error ;
+
+: set-notify-site-watchers ( site new-up? -- site )
+    [ over up?>> = [ t >>changed? ] unless ] keep >>up? ;
+
+: site-good ( site -- )
+    t set-notify-site-watchers
+    now >>last-up
+    f >>error
+    f >>last-error
+    update-tuple ;
+
+: site-bad ( site error -- )
+    [ error. ] with-string-writer >>error
+    f set-notify-site-watchers
+    now >>last-error
+    update-tuple ;
+
+: sites-to-report ( -- seq )
+    "select users.email, site.url, site.up, site.changed, site.last_up, site.error, site.last_error from users, site, watching_site where users.username = watching_site.account_name and site.site_id = watching_site.site_id and site.changed = '1'" sql-query 
+    [ [ reporting-site boa ] input<sequence ] map
+    "update site set changed = 0;" sql-command ;
+
+: insert-account ( account-name email -- ) <account> insert-tuple ;
+
+: find-sites ( -- seq ) f <site> select-tuples ;
+
+: watch-site ( username url -- )
+    select-account/site <watching-site> insert-tuple ;
+
+: unwatch-site ( username url -- )
+    select-account/site <watching-site> delete-tuples ;
+
+: watching-sites ( username -- sites )
+    f <watching-site> select-tuples
+    [ site-id>> site new swap >>site-id select-tuple ] map ;
+
+: site-watcher-path ( -- path ) "site-watcher.db" temp-file ; inline
+
+: with-site-watcher-db ( quot -- )
+    site-watcher-path <sqlite-db> swap with-db ; inline
diff --git a/extra/site-watcher/email/authors.txt b/extra/site-watcher/email/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/site-watcher/email/email.factor b/extra/site-watcher/email/email.factor
new file mode 100644 (file)
index 0000000..d028788
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: smtp namespaces accessors kernel arrays ;
+IN: site-watcher.email
+
+SYMBOL: site-watcher-from
+site-watcher-from [ "factor-site-watcher@gmail.com" ] initialize
+
+: send-site-email ( watching-site body subject -- )
+    [ account>> email>> ] 2dip
+    pick [
+        [ <email> site-watcher-from get >>from ] 3dip
+        [ 1array >>to ] [ >>body ] [ >>subject ] tri* send-email 
+    ] [ 3drop ] if ;
\ No newline at end of file
diff --git a/extra/site-watcher/site-watcher-tests.factor b/extra/site-watcher/site-watcher-tests.factor
new file mode 100644 (file)
index 0000000..e58d5a7
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: db.tuples locals site-watcher site-watcher.db
+site-watcher.private kernel db io.directories io.files.temp
+continuations db.sqlite
+sequences tools.test ;
+IN: site-watcher.tests
+
+[ "site-watcher.db" temp-file delete-file ] ignore-errors
+
+:: fake-sites ( -- seq )
+    "site-watcher.db" temp-file <sqlite-db> [
+        account ensure-table
+        site ensure-table
+        watching-site ensure-table
+
+        "erg" "erg@factorcode.org" insert-account
+        "http://asdfasdfasdfasdfqwerqqq.com" insert-site drop
+        "http://fark.com" insert-site drop
+
+        "erg@factorcode.org" "http://asdfasdfasdfasdfqwerqqq.com" watch-site
+        f <site> select-tuples
+    ] with-db ;
+
+[ f ] [ fake-sites empty? ] unit-test
diff --git a/extra/site-watcher/site-watcher.factor b/extra/site-watcher/site-watcher.factor
new file mode 100644 (file)
index 0000000..535c8cd
--- /dev/null
@@ -0,0 +1,51 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alarms arrays calendar combinators
+combinators.smart continuations debugger http.client fry
+init io.streams.string kernel locals math math.parser db
+namespaces sequences site-watcher.db site-watcher.email ;
+IN: site-watcher
+
+SYMBOL: site-watcher-frequency
+5 minutes site-watcher-frequency set-global
+SYMBOL: running-site-watcher
+[ f running-site-watcher set-global ] "site-watcher" add-init-hook
+
+<PRIVATE
+
+: check-sites ( seq -- )
+    [
+        [ dup url>> http-get 2drop site-good ] [ site-bad ] recover
+    ] each ;
+
+: site-up-email ( site -- body )
+    last-up>> now swap time- duration>minutes 60 /mod
+    [ >integer number>string ] bi@
+    [ " hours, " append ] [ " minutes" append ] bi* append
+    "Site was down for (at least): " prepend ;
+
+: site-down-email ( site -- body ) error>> ;
+
+: send-report ( site -- )
+    [ ]
+    [ dup up?>> [ site-up-email ] [ site-down-email ] if ]
+    [ [ url>> ] [ up?>> "up" "down" ? ] bi " is " glue ] tri
+    send-site-email ;
+
+: send-reports ( seq -- )
+    [ ] [ [ send-report ] each ] if-empty ;
+
+PRIVATE>
+
+: watch-sites ( -- )
+    find-sites check-sites sites-to-report send-reports ;
+
+: run-site-watcher ( db -- )
+    [ running-site-watcher get ] dip '[ 
+        [ _ [ watch-sites ] with-db ] site-watcher-frequency get every
+        running-site-watcher set
+    ] unless ;
+
+: stop-site-watcher ( -- )
+    running-site-watcher get [ cancel-alarm ] when* ;
diff --git a/extra/site-watcher/spider/authors.txt b/extra/site-watcher/spider/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/site-watcher/spider/spider.factor b/extra/site-watcher/spider/spider.factor
new file mode 100644 (file)
index 0000000..335f1f1
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: site-watcher.db site-watcher.email site-watcher.spider
+spider spider.report
+accessors kernel sequences
+xml.writer concurrency.combinators ;
+IN: site-watcher.spider
+
+: <site-spider> ( spidering-site -- spider )
+    [ max-depth>> ]
+    [ max-count>> ]
+    [ site>> url>> ]
+    tri
+    <spider>
+        swap >>max-count
+        swap >>max-depth ;
+
+: spider-and-email ( spidering-site -- )
+    [ ]
+    [ <site-spider> run-spider spider-report xml>string ]
+    [ site>> url>> "Spidered " prefix ] tri
+    send-site-email ;
+
+: spider-sites ( -- )
+    f spidering-sites [ spider-and-email ] parallel-each ;
\ No newline at end of file
index 752d0b3ffacd148213e2c1a8bcb2a0f277f48a55..29367a2b2bfd8a9382196da075073c38a8fcb571 100755 (executable)
@@ -1,9 +1,9 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays hashtables help.markup help.stylesheet io
 io.styles kernel math models namespaces sequences ui ui.gadgets
 ui.gadgets.books ui.gadgets.panes ui.gestures ui.pens.gradient
-parser accessors colors ;
+parser accessors colors fry ;
 IN: slides
 
 CONSTANT: stylesheet
@@ -94,8 +94,8 @@ TUPLE: slides < book ;
         2 + (strip-tease)
     ] with map ;
 
-: STRIP-TEASE:
-    parse-definition strip-tease [ parsed ] each ; parsing
+SYNTAX: STRIP-TEASE:
+    parse-definition strip-tease [ parsed ] each ;
 
 \ slides H{
     { T{ button-down } [ request-focus ] }
@@ -104,4 +104,4 @@ TUPLE: slides < book ;
 } set-gestures
 
 : slides-window ( slides -- )
-    [ <slides> "Slides" open-window ] with-ui ;
+    '[ _ <slides> "Slides" open-window ] with-ui ;
diff --git a/extra/smalltalk/ast/ast.factor b/extra/smalltalk/ast/ast.factor
new file mode 100644 (file)
index 0000000..fc415aa
--- /dev/null
@@ -0,0 +1,53 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: strings arrays memoize kernel sequences accessors combinators ;
+IN: smalltalk.ast
+
+SINGLETONS: nil self super ;
+
+TUPLE: ast-comment { string string } ;
+TUPLE: ast-block { arguments array } { temporaries array } { body array } ;
+TUPLE: ast-message-send receiver { selector string } { arguments array } ;
+TUPLE: ast-message { selector string } { arguments array } ;
+TUPLE: ast-cascade receiver { messages array } ;
+TUPLE: ast-name { name string } ;
+TUPLE: ast-return value ;
+TUPLE: ast-assignment { name ast-name } value ;
+TUPLE: ast-local-variables { names array } ;
+TUPLE: ast-method { name string } { body ast-block } ;
+TUPLE: ast-class { name string } { superclass string } { ivars array } { methods array } ;
+TUPLE: ast-foreign { class string } { name string } ;
+TUPLE: ast-sequence { temporaries array } { body array } ;
+
+! We treat a sequence of statements like a block in a few places to
+! simplify handling of top-level forms
+M: ast-sequence arguments>> drop { } ;
+
+: unclip-temporaries ( statements -- temporaries statements' )
+    {
+        { [ dup empty? ] [ { } ] }
+        { [ dup first ast-local-variables? not ] [ { } ] }
+        [ unclip names>> ]
+    } cond swap ;
+
+: <ast-block> ( arguments body -- block )
+    unclip-temporaries ast-block boa ;
+
+: <ast-sequence> ( body -- block )
+    unclip-temporaries ast-sequence boa ;
+
+! The parser parses normal message sends as cascades with one message, but
+! we represent them differently in the AST to simplify generated code in
+! the common case
+: <ast-cascade> ( receiver messages -- ast )
+    dup length 1 =
+    [ first [ selector>> ] [ arguments>> ] bi ast-message-send boa ]
+    [ ast-cascade boa ]
+    if ;
+
+! Methods return self by default
+: <ast-method> ( class arguments body -- method )
+    self suffix <ast-block> ast-method boa ;
+
+TUPLE: symbol { name string } ;
+MEMO: intern ( name -- symbol ) symbol boa ;
\ No newline at end of file
diff --git a/extra/smalltalk/ast/authors.txt b/extra/smalltalk/ast/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/authors.txt b/extra/smalltalk/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/classes/authors.txt b/extra/smalltalk/classes/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/classes/classes.factor b/extra/smalltalk/classes/classes.factor
new file mode 100644 (file)
index 0000000..1798aad
--- /dev/null
@@ -0,0 +1,25 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel namespaces assocs accessors words sequences classes.tuple ;
+IN: smalltalk.classes
+
+SYMBOL: classes
+
+classes [ H{ } clone ] initialize
+
+: create-class ( class -- class )
+    "smalltalk.classes" create ;
+
+ERROR: no-class name ;
+
+: lookup-class ( class -- class )
+    classes get ?at [ ] [ no-class ] if ;
+
+: define-class ( class superclass ivars -- class-word )
+    [ create-class ] [ lookup-class ] [ ] tri*
+    [ define-tuple-class ] [ 2drop dup dup name>> classes get set-at ] 3bi ;
+
+: define-foreign ( class name -- )
+    classes get set-at ;
+
+tuple "Object" define-foreign
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/assignment/assignment.factor b/extra/smalltalk/compiler/assignment/assignment.factor
new file mode 100644 (file)
index 0000000..3a0a769
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays kernel sequences sets smalltalk.ast ;
+IN: smalltalk.compiler.assignment
+
+GENERIC: assigned-locals ( ast -- seq )
+
+M: ast-return assigned-locals value>> assigned-locals ;
+
+M: ast-block assigned-locals
+    [ body>> assigned-locals ] [ arguments>> ] bi diff ;
+
+M: ast-message-send assigned-locals
+    [ receiver>> assigned-locals ]
+    [ arguments>> assigned-locals ]
+    bi append ;
+
+M: ast-cascade assigned-locals
+    [ receiver>> assigned-locals ]
+    [ messages>> assigned-locals ]
+    bi append ;
+
+M: ast-message assigned-locals
+    arguments>> assigned-locals ;
+
+M: ast-assignment assigned-locals
+    [ name>> dup ast-name? [ name>> 1array ] [ drop { } ] if ]
+    [ value>> assigned-locals ] bi append ;
+
+M: ast-sequence assigned-locals
+    body>> assigned-locals ;
+
+M: array assigned-locals
+    [ assigned-locals ] map concat ;
+
+M: object assigned-locals drop f ;
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/assignment/authors.txt b/extra/smalltalk/compiler/assignment/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/authors.txt b/extra/smalltalk/compiler/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/compiler-tests.factor b/extra/smalltalk/compiler/compiler-tests.factor
new file mode 100644 (file)
index 0000000..81b38f2
--- /dev/null
@@ -0,0 +1,87 @@
+USING: smalltalk.compiler tools.test prettyprint smalltalk.ast
+smalltalk.compiler.lexenv stack-checker locals.rewrite.closures
+kernel accessors compiler.units sequences arrays ;
+IN: smalltalk.compiler.tests
+
+: test-compilation ( ast -- quot )
+    [
+        1array ast-sequence new swap >>body
+        compile-smalltalk [ call ] append
+    ] with-compilation-unit ;
+
+: test-inference ( ast -- in# out# )
+    test-compilation infer [ in>> ] [ out>> ] bi ;
+
+[ 2 1 ] [
+    T{ ast-block f
+       { "a" "b" }
+       {
+           T{ ast-message-send f
+              T{ ast-name f "a" }
+              "+"
+              { T{ ast-name f "b" } }
+           }
+       }
+    } test-inference
+] unit-test
+
+[ 3 1 ] [
+    T{ ast-block f
+       { "a" "b" "c" }
+       {
+           T{ ast-assignment f
+              T{ ast-name f "a" }
+              T{ ast-message-send f
+                 T{ ast-name f "c" }
+                 "+"
+                 { T{ ast-name f "b" } }
+              }
+           }
+           T{ ast-message-send f
+              T{ ast-name f "b" }
+              "blah:"
+              { 123.456 }
+           }
+           T{ ast-return f T{ ast-name f "c" } }
+       }
+    } test-inference
+] unit-test
+
+[ 0 1 ] [
+    T{ ast-block f
+       { }
+       { }
+       {
+           T{ ast-message-send
+              { receiver 1 }
+              { selector "to:do:" }
+              { arguments
+                {
+                    10
+                    T{ ast-block
+                       { arguments { "i" } }
+                       { body
+                         {
+                             T{ ast-message-send
+                                { receiver
+                                  T{ ast-name { name "i" } }
+                                }
+                                { selector "print" }
+                             }
+                         }
+                       }
+                    }
+                }
+              }
+           }
+       }
+    } test-inference
+] unit-test
+
+[ "a" ] [
+    T{ ast-block f
+       { }
+       { }
+       { { T{ ast-block { body { "a" } } } } }
+    } test-compilation call first call
+] unit-test
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/compiler.factor b/extra/smalltalk/compiler/compiler.factor
new file mode 100644 (file)
index 0000000..2eeee30
--- /dev/null
@@ -0,0 +1,157 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs combinators.short-circuit
+continuations fry kernel namespaces quotations sequences sets
+generalizations slots locals.types splitting math
+locals.rewrite.closures generic words combinators locals smalltalk.ast
+smalltalk.compiler.lexenv smalltalk.compiler.assignment
+smalltalk.compiler.return smalltalk.selectors smalltalk.classes ;
+IN: smalltalk.compiler
+
+GENERIC: compile-ast ( lexenv ast -- quot )
+
+M: object compile-ast nip 1quotation ;
+
+M: self compile-ast drop self>> 1quotation ;
+
+ERROR: unbound-local name ;
+
+M: ast-name compile-ast name>> swap lookup-reader ;
+
+: compile-arguments ( lexenv ast -- quot )
+    arguments>> [ compile-ast ] with map [ ] join ;
+
+: compile-new ( lexenv ast -- quot )
+    [ receiver>> compile-ast ]
+    [ compile-arguments ] 2bi
+    [ new ] 3append ;
+
+: compile-ifTrue:ifFalse: ( lexenv ast -- quot )
+    [ receiver>> compile-ast ]
+    [ compile-arguments ] 2bi
+    [ if ] 3append ;
+
+M: ast-message-send compile-ast
+    dup selector>> {
+        { "ifTrue:ifFalse:" [ compile-ifTrue:ifFalse: ] }
+        { "new" [ compile-new ] }
+        [
+            drop
+            [ compile-arguments ]
+            [ receiver>> compile-ast ]
+            [ nip selector>> selector>generic ]
+            2tri [ append ] dip suffix
+        ]
+    } case ;
+
+M: ast-cascade compile-ast
+    [ receiver>> compile-ast ]
+    [
+        messages>> [
+            [ compile-arguments \ dip ]
+            [ selector>> selector>generic ] bi
+            [ ] 3sequence
+        ] with map
+        unclip-last [ [ [ drop ] append ] map ] dip suffix
+        cleave>quot
+    ] 2bi append ;
+
+M: ast-return compile-ast
+    [ value>> compile-ast ] [ drop return>> 1quotation ] 2bi
+    [ continue-with ] 3append ;
+
+: (compile-sequence) ( lexenv asts -- quot )
+    [ drop [ nil ] ] [
+        [ compile-ast ] with map [ drop ] join
+    ] if-empty ;
+
+: block-lexenv ( block -- lexenv )
+    [ [ arguments>> ] [ temporaries>> ] bi append ]
+    [ body>> [ assigned-locals ] map concat unique ] bi
+    '[
+        dup dup _ key?
+        [ <local-reader> ]
+        [ <local> ]
+        if
+    ] H{ } map>assoc
+    dup
+    [ nip local-reader? ] assoc-filter
+    [ <local-writer> ] assoc-map
+    <lexenv> swap >>local-writers swap >>local-readers ;
+
+: lookup-block-vars ( vars lexenv -- seq )
+    local-readers>> '[ _ at ] map ;
+
+: make-temporaries ( block lexenv -- quot )
+    [ temporaries>> ] dip lookup-block-vars
+    [ <def> [ f ] swap suffix ] map [ ] join ;
+
+:: compile-sequence ( lexenv block -- vars quot )
+    lexenv block block-lexenv lexenv-union :> lexenv
+    block arguments>> lexenv lookup-block-vars
+    lexenv block body>> (compile-sequence) block lexenv make-temporaries prepend ;
+
+M: ast-sequence compile-ast
+    compile-sequence nip ;
+
+GENERIC: contains-blocks? ( obj -- ? )
+
+M: ast-block contains-blocks? drop t ;
+
+M: object contains-blocks? drop f ;
+
+M: array contains-blocks? [ contains-blocks? ] any? ;
+
+M: array compile-ast
+    dup contains-blocks? [
+        [ [ compile-ast ] with map [ ] join ] [ length ] bi
+        '[ @ _ narray ]
+    ] [ call-next-method ] if ;
+
+GENERIC: compile-assignment ( lexenv name -- quot )
+
+M: ast-name compile-assignment name>> swap lookup-writer ;
+
+M: ast-assignment compile-ast
+    [ value>> compile-ast [ dup ] ] [ name>> compile-assignment ] 2bi 3append ;
+
+M: ast-block compile-ast
+    compile-sequence <lambda> '[ _ ] ;
+
+:: (compile-method-body) ( lexenv block -- lambda )
+    lexenv block compile-sequence
+    [ lexenv self>> suffix ] dip <lambda> ;
+
+: compile-method-body ( lexenv block -- quot )
+    [ [ (compile-method-body) ] [ arguments>> length 1+ ] bi ] 2keep
+    make-return ;
+
+: compile-method ( lexenv ast-method -- )
+    [ [ class>> ] [ name>> selector>generic ] bi* create-method ]
+    [ body>> compile-method-body ]
+    2bi define ;
+
+: <class-lexenv> ( class -- lexenv )
+    <lexenv> swap >>class "self" <local> >>self "^" <local> >>return ;
+
+M: ast-class compile-ast
+    nip
+    [
+        [ name>> ] [ superclass>> ] [ ivars>> ] tri
+        define-class <class-lexenv> 
+    ]
+    [ methods>> ] bi
+    [ compile-method ] with each
+    [ nil ] ;
+
+ERROR: no-word name ;
+
+M: ast-foreign compile-ast
+    nip
+    [ class>> dup ":" split1 lookup [ ] [ no-word ] ?if ]
+    [ name>> ] bi define-foreign
+    [ nil ] ;
+
+: compile-smalltalk ( statement -- quot )
+    [ empty-lexenv ] dip [ compile-sequence nip 0 ]
+    2keep make-return ;
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/lexenv/authors.txt b/extra/smalltalk/compiler/lexenv/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/lexenv/lexenv-tests.factor b/extra/smalltalk/compiler/lexenv/lexenv-tests.factor
new file mode 100644 (file)
index 0000000..8f171f3
--- /dev/null
@@ -0,0 +1,24 @@
+USING: smalltalk.compiler.lexenv tools.test kernel namespaces accessors ;
+IN: smalltalk.compiler.lexenv.tests
+
+TUPLE: some-class x y z ;
+
+SYMBOL: fake-self
+
+SYMBOL: fake-local
+
+<lexenv>
+    some-class >>class
+    fake-self >>self
+    H{ { "mumble" fake-local } } >>local-readers
+    H{ { "jumble" fake-local } } >>local-writers
+lexenv set
+
+[ [ fake-local ] ] [ "mumble" lexenv get lookup-reader ] unit-test
+[ [ fake-self x>> ] ] [ "x" lexenv get lookup-reader ] unit-test
+[ [ \ tuple ] ] [ "Object" lexenv get lookup-reader ] unit-test
+
+[ [ fake-local ] ] [ "jumble" lexenv get lookup-writer ] unit-test
+[ [ fake-self (>>y) ] ] [ "y" lexenv get lookup-writer ] unit-test
+
+[ "blahblah" lexenv get lookup-writer ] must-fail
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/lexenv/lexenv.factor b/extra/smalltalk/compiler/lexenv/lexenv.factor
new file mode 100644 (file)
index 0000000..cd06314
--- /dev/null
@@ -0,0 +1,67 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs kernel accessors quotations slots words
+sequences namespaces combinators combinators.short-circuit
+summary smalltalk.classes ;
+IN: smalltalk.compiler.lexenv
+
+! local-readers: assoc string => word
+! local-writers: assoc string => word
+! self: word or f for top-level forms
+! class: class word or f for top-level forms
+! method: generic word or f for top-level forms
+TUPLE: lexenv local-readers local-writers self return class method ;
+
+: <lexenv> ( -- lexenv ) lexenv new ; inline
+
+CONSTANT: empty-lexenv T{ lexenv }
+
+: lexenv-union ( lexenv1 lexenv2 -- lexenv )
+    [ <lexenv> ] 2dip {
+        [ [ local-readers>> ] bi@ assoc-union >>local-readers ]
+        [ [ local-writers>> ] bi@ assoc-union >>local-writers ]
+        [ [ self>> ] either? >>self ]
+        [ [ return>> ] either? >>return ]
+        [ [ class>> ] either? >>class ]
+        [ [ method>> ] either? >>method ]
+    } 2cleave ;
+
+: local-reader ( name lexenv -- local )
+    local-readers>> at dup [ 1quotation ] when ;
+
+: ivar-reader ( name lexenv -- quot/f )
+    dup class>> [
+        [ class>> "slots" word-prop slot-named ] [ self>> ] bi
+        swap dup [ name>> reader-word [ ] 2sequence ] [ 2drop f ] if
+    ] [ 2drop f ] if ;
+
+: class-name ( name -- quot/f )
+    classes get at dup [ [ ] curry ] when ;
+
+ERROR: bad-identifier name ;
+
+M: bad-identifier summary drop "Unknown identifier" ;
+
+: lookup-reader ( name lexenv -- reader-quot )
+    {
+        [ local-reader ]
+        [ ivar-reader ]
+        [ drop class-name ]
+        [ drop bad-identifier ]
+    } 2|| ;
+
+: local-writer ( name lexenv -- local )
+    local-writers>> at dup [ 1quotation ] when ;
+
+: ivar-writer ( name lexenv -- quot/f )
+    dup class>> [
+        [ class>> "slots" word-prop slot-named ] [ self>> ] bi
+        swap dup [ name>> writer-word [ ] 2sequence ] [ 2drop f ] if
+    ] [ 2drop f ] if ;
+
+: lookup-writer ( name lexenv -- writer-quot )
+    {
+        [ local-writer ]
+        [ ivar-writer ]
+        [ drop bad-identifier ]
+    } 2|| ;
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/return/authors.txt b/extra/smalltalk/compiler/return/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/return/return-tests.factor b/extra/smalltalk/compiler/return/return-tests.factor
new file mode 100644 (file)
index 0000000..15a3406
--- /dev/null
@@ -0,0 +1,3 @@
+USING: smalltalk.parser smalltalk.compiler.return tools.test ;
+
+[ t ] [ "(i <= 1) ifTrue: [^1] ifFalse: [^((Fib new i:(i-1)) compute + (Fib new i:(i-2)) compute)]" parse-smalltalk need-return-continuation? ] unit-test
\ No newline at end of file
diff --git a/extra/smalltalk/compiler/return/return.factor b/extra/smalltalk/compiler/return/return.factor
new file mode 100644 (file)
index 0000000..8c36bda
--- /dev/null
@@ -0,0 +1,45 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays combinators.short-circuit continuations
+fry generalizations kernel locals locals.types locals.rewrite.closures
+namespaces make sequences smalltalk.ast ;
+IN: smalltalk.compiler.return
+
+SYMBOL: return-continuation
+
+GENERIC: need-return-continuation? ( ast -- ? )
+
+M: ast-return need-return-continuation? drop t ;
+
+M: ast-block need-return-continuation? body>> need-return-continuation? ;
+
+M: ast-message-send need-return-continuation?
+    {
+        [ receiver>> need-return-continuation? ]
+        [ arguments>> need-return-continuation? ]
+    } 1|| ;
+
+M: ast-cascade need-return-continuation?
+    {
+        [ receiver>> need-return-continuation? ]
+        [ messages>> need-return-continuation? ]
+    } 1|| ;
+
+M: ast-message need-return-continuation?
+    arguments>> need-return-continuation? ;
+
+M: ast-assignment need-return-continuation?
+    value>> need-return-continuation? ;
+
+M: ast-sequence need-return-continuation?
+    body>> need-return-continuation? ;
+
+M: array need-return-continuation? [ need-return-continuation? ] any? ;
+
+M: object need-return-continuation? drop f ;
+
+:: make-return ( quot n lexenv block -- quot )
+    block need-return-continuation? [
+        quot clone [ lexenv return>> <def> '[ _ ] prepend ] change-body
+        n '[ _ _ ncurry callcc1 ]
+    ] [ quot ] if rewrite-closures first ;
\ No newline at end of file
diff --git a/extra/smalltalk/eval/authors.txt b/extra/smalltalk/eval/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/eval/eval-tests.factor b/extra/smalltalk/eval/eval-tests.factor
new file mode 100644 (file)
index 0000000..95366d6
--- /dev/null
@@ -0,0 +1,11 @@
+IN: smalltalk.eval.tests
+USING: smalltalk.eval tools.test io.streams.string kernel ;
+
+[ 3 ] [ "1+2" eval-smalltalk ] unit-test
+[ "HAI" ] [ "(1<10) ifTrue:['HAI'] ifFalse:['BAI']" eval-smalltalk ] unit-test
+[ 7 ] [ "1+2+3;+4" eval-smalltalk ] unit-test
+[ 6 "5\n6\n" ] [ [ "[:x|x print] value: 5; value: 6" eval-smalltalk ] with-string-writer ] unit-test
+[ 5 ] [ "|x| x:=5. x" eval-smalltalk ] unit-test
+[ 11 ] [ "[:i| |x| x:=5. i+x] value: 6" eval-smalltalk ] unit-test
+[ t ] [ "class Blah [method foo [5]]. Blah new foo" eval-smalltalk tuple? ] unit-test
+[ 196418 ] [ "vocab:smalltalk/eval/fib.st" eval-smalltalk-file ] unit-test
\ No newline at end of file
diff --git a/extra/smalltalk/eval/eval.factor b/extra/smalltalk/eval/eval.factor
new file mode 100644 (file)
index 0000000..56841be
--- /dev/null
@@ -0,0 +1,13 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.files io.encodings.utf8
+compiler.units smalltalk.parser smalltalk.compiler
+smalltalk.library ;
+IN: smalltalk.eval
+
+: eval-smalltalk ( string -- result )
+    [ parse-smalltalk compile-smalltalk ] with-compilation-unit
+    call( -- result ) ;
+
+: eval-smalltalk-file ( path -- result )
+    utf8 file-contents eval-smalltalk ;
diff --git a/extra/smalltalk/eval/fib.st b/extra/smalltalk/eval/fib.st
new file mode 100644 (file)
index 0000000..41ab8f5
--- /dev/null
@@ -0,0 +1,11 @@
+class Fib [
+    |i|
+    method i: newI [i:=newI].
+    method compute [
+        (i <= 1)
+          ifTrue: [^1]
+          ifFalse: [^((Fib new i:(i-1)) compute + (Fib new i:(i-2)) compute)]
+    ].
+].
+
+[(Fib new i: 26) compute] time
\ No newline at end of file
diff --git a/extra/smalltalk/library/authors.txt b/extra/smalltalk/library/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/library/library.factor b/extra/smalltalk/library/library.factor
new file mode 100644 (file)
index 0000000..28acf98
--- /dev/null
@@ -0,0 +1,101 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel present io math sequences assocs math.ranges
+math.order fry tools.time locals smalltalk.selectors
+smalltalk.ast smalltalk.classes ;
+IN: smalltalk.library
+
+SELECTOR: print
+SELECTOR: asString
+
+M: object selector-print dup present print ;
+M: object selector-asString present ;
+
+SELECTOR: print:
+SELECTOR: nextPutAll:
+SELECTOR: tab
+SELECTOR: nl
+
+M: object selector-print: [ present ] dip stream-print nil ;
+M: object selector-nextPutAll: selector-print: ;
+M: object selector-tab "    " swap selector-print: ;
+M: object selector-nl stream-nl nil ;
+
+SELECTOR: +
+SELECTOR: -
+SELECTOR: *
+SELECTOR: /
+SELECTOR: <
+SELECTOR: >
+SELECTOR: <=
+SELECTOR: >=
+SELECTOR: =
+
+M: object selector-+  swap +  ;
+M: object selector--  swap -  ;
+M: object selector-*  swap *  ;
+M: object selector-/  swap /  ;
+M: object selector-<  swap <  ;
+M: object selector->  swap >  ;
+M: object selector-<= swap <= ;
+M: object selector->= swap >= ;
+M: object selector-=  swap =  ;
+
+SELECTOR: min:
+SELECTOR: max:
+
+M: object selector-min: min ;
+M: object selector-max: max ;
+
+SELECTOR: ifTrue:
+SELECTOR: ifFalse:
+SELECTOR: ifTrue:ifFalse:
+
+M: object selector-ifTrue: [ call( -- result ) ] [ drop nil ] if ;
+M: object selector-ifFalse: [ drop nil ] [ call( -- result ) ] if ;
+M: object selector-ifTrue:ifFalse: [ drop call( -- result ) ] [ nip call( -- result ) ] if ;
+
+SELECTOR: isNil
+
+M: object selector-isNil nil eq? ;
+
+SELECTOR: at:
+SELECTOR: at:put:
+
+M: sequence selector-at: nth ;
+M: sequence selector-at:put: ( key value receiver -- receiver ) [ swapd set-nth ] keep ;
+
+M: assoc selector-at: at ;
+M: assoc selector-at:put: ( key value receiver -- receiver ) [ swapd set-at ] keep ;
+
+SELECTOR: do:
+
+M:: object selector-do: ( quot receiver -- nil )
+    receiver [ quot call( elt -- result ) drop ] each nil ;
+
+SELECTOR: to:
+SELECTOR: to:do:
+
+M: object selector-to: swap [a,b] ;
+M:: object selector-to:do: ( to quot from -- nil )
+    from to [a,b] [ quot call( i -- result ) drop ] each nil ;
+
+SELECTOR: value
+SELECTOR: value:
+SELECTOR: value:value:
+SELECTOR: value:value:value:
+SELECTOR: value:value:value:value:
+
+M: object selector-value call( -- result ) ;
+M: object selector-value: call( input -- result ) ;
+M: object selector-value:value: call( input input -- result ) ;
+M: object selector-value:value:value: call( input input input -- result ) ;
+M: object selector-value:value:value:value: call( input input input input -- result ) ;
+
+SELECTOR: new
+
+M: object selector-new new ;
+
+SELECTOR: time
+
+M: object selector-time '[ _ call( -- result ) ] time ;
\ No newline at end of file
diff --git a/extra/smalltalk/listener/authors.txt b/extra/smalltalk/listener/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/listener/listener.factor b/extra/smalltalk/listener/listener.factor
new file mode 100644 (file)
index 0000000..dc84fd9
--- /dev/null
@@ -0,0 +1,18 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel prettyprint io io.styles colors.constants compiler.units
+fry debugger sequences locals.rewrite.closures smalltalk.ast
+smalltalk.eval smalltalk.printer smalltalk.listener ;
+IN: smalltalk.listener
+
+: eval-interactively ( string -- )
+    '[
+        _ eval-smalltalk
+        dup nil? [ drop ] [ "Result: " write smalltalk>string print ] if
+    ] try ;
+
+: smalltalk-listener ( -- )
+    "Smalltalk>" { { background COLOR: light-blue } } format bl flush readln
+    [ eval-interactively smalltalk-listener ] when* ;
+
+MAIN: smalltalk-listener
\ No newline at end of file
diff --git a/extra/smalltalk/parser/authors.txt b/extra/smalltalk/parser/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/parser/parser-tests.factor b/extra/smalltalk/parser/parser-tests.factor
new file mode 100644 (file)
index 0000000..9027290
--- /dev/null
@@ -0,0 +1,300 @@
+IN: smalltalk.parser.tests
+USING: smalltalk.parser smalltalk.ast
+peg.ebnf tools.test accessors
+io.files io.encodings.ascii kernel ;
+
+EBNF: test-Character
+test         = <foreign parse-smalltalk Character>
+;EBNF
+
+[ CHAR: a ] [ "a" test-Character ] unit-test
+
+EBNF: test-Comment
+test         = <foreign parse-smalltalk Comment>
+;EBNF
+
+[ T{ ast-comment f "Hello, this is a comment." } ]
+[ "\"Hello, this is a comment.\"" test-Comment ]
+unit-test
+
+[ T{ ast-comment f "Hello, \"this\" is a comment." } ]
+[ "\"Hello, \"\"this\"\" is a comment.\"" test-Comment ]
+unit-test
+
+EBNF: test-Identifier
+test         = <foreign parse-smalltalk Identifier>
+;EBNF
+
+[ "OrderedCollection" ] [ "OrderedCollection" test-Identifier ] unit-test
+
+EBNF: test-Literal
+test         = <foreign parse-smalltalk Literal>
+;EBNF
+
+[ nil ] [ "nil" test-Literal ] unit-test
+[ 123 ] [ "123" test-Literal ] unit-test
+[ HEX: deadbeef ] [ "16rdeadbeef" test-Literal ] unit-test
+[ -123 ] [ "-123" test-Literal ] unit-test
+[ 1.2 ] [ "1.2" test-Literal ] unit-test
+[ -1.24 ] [ "-1.24" test-Literal ] unit-test
+[ 12.4e7 ] [ "12.4e7" test-Literal ] unit-test
+[ 12.4e-7 ] [ "12.4e-7" test-Literal ] unit-test
+[ -12.4e7 ] [ "-12.4e7" test-Literal ] unit-test
+[ CHAR: x ] [ "$x" test-Literal ] unit-test
+[ "Hello, world" ] [ "'Hello, world'" test-Literal ] unit-test
+[ "Hello, 'funny' world" ] [ "'Hello, ''funny'' world'" test-Literal ] unit-test
+[ T{ symbol f "foo" } ] [ "#foo" test-Literal ] unit-test
+[ T{ symbol f "+" } ] [ "#+" test-Literal ] unit-test
+[ T{ symbol f "at:put:" } ] [ "#at:put:" test-Literal ] unit-test
+[ T{ symbol f "Hello world" } ] [ "#'Hello world'" test-Literal ] unit-test
+[ B{ 1 2 3 4 } ] [ "#[1 2 3 4]" test-Literal ] unit-test
+[ { nil t f } ] [ "#(nil true false)" test-Literal ] unit-test
+[ { nil { t f } } ] [ "#(nil (true false))" test-Literal ] unit-test
+[ T{ ast-block f { } { } { } } ] [ "[]" test-Literal ] unit-test
+[ T{ ast-block f { "x" } { } { T{ ast-return f T{ ast-name f "x" } } } } ] [ "[ :x|^x]" test-Literal ] unit-test
+[ T{ ast-block f { } { } { T{ ast-return f self } } } ] [ "[^self]" test-Literal ] unit-test
+
+[
+    T{ ast-block
+       { arguments { "i" } }
+       { body
+         {
+             T{ ast-message-send
+                { receiver T{ ast-name { name "i" } } }
+                { selector "print" }
+             }
+         }
+       }
+    }
+]
+[ "[ :i | i print ]" test-Literal ] unit-test
+
+[
+    T{ ast-block
+       { body { 5 self } }
+    }
+]
+[ "[5. self]" test-Literal ] unit-test
+
+EBNF: test-FormalBlockArgumentDeclarationList
+test         = <foreign parse-smalltalk FormalBlockArgumentDeclarationList>
+;EBNF
+
+[ V{ "x" "y" "elt" } ] [ ":x :y :elt" test-FormalBlockArgumentDeclarationList ] unit-test
+
+EBNF: test-Operand
+test         = <foreign parse-smalltalk Operand>
+;EBNF
+
+[ { 123 15.6 { t f } } ] [ "#(123 15.6 (true false))" test-Operand ] unit-test
+[ T{ ast-name f "x" } ] [ "x" test-Operand ] unit-test
+
+EBNF: test-Expression
+test         = <foreign parse-smalltalk Expression>
+;EBNF
+
+[ self ] [ "self" test-Expression ] unit-test
+[ { 123 15.6 { t f } } ] [ "#(123 15.6 (true false))" test-Expression ] unit-test
+[ T{ ast-name f "x" } ] [ "x" test-Expression ] unit-test
+[ T{ ast-message-send f 5 "print" { } } ] [ "5 print" test-Expression ] unit-test
+[ T{ ast-message-send f T{ ast-message-send f 5 "squared" { } } "print" { } } ] [ "5 squared print" test-Expression ] unit-test
+[ T{ ast-message-send f 2 "+" { 2 } } ] [ "2+2" test-Expression ] unit-test
+
+[
+    T{ ast-message-send f
+        T{ ast-message-send f 3 "factorial" { } }
+        "+"
+        { T{ ast-message-send f 4 "factorial" { } } }
+    }
+]
+[ "3 factorial + 4 factorial" test-Expression ] unit-test
+
+[
+    T{ ast-message-send f
+        T{ ast-message-send f 3 "factorial" { } }
+        "+"
+        { T{ ast-message-send f 4 "factorial" { } } }
+    }
+]
+[ "   3 factorial + 4 factorial" test-Expression ] unit-test
+
+[
+    T{ ast-message-send f
+        T{ ast-message-send f 3 "factorial" { } }
+        "+"
+        { T{ ast-message-send f 4 "factorial" { } } }
+    }
+]
+[ "   3 factorial + 4 factorial     " test-Expression ] unit-test
+
+[
+    T{ ast-message-send f
+        T{ ast-message-send f
+            T{ ast-message-send f 3 "factorial" { } }
+            "+"
+            { 4 }
+        }
+        "factorial"
+        { }
+    }
+]
+[ "(3 factorial + 4) factorial" test-Expression ] unit-test
+
+[
+    T{ ast-message-send
+       { receiver
+         T{ ast-message-send
+            { receiver
+              T{ ast-message-send
+                 { receiver 1 }
+                 { selector "<" }
+                 { arguments { 10 } }
+              }
+            }
+            { selector "ifTrue:ifFalse:" }
+            { arguments
+              {
+                  T{ ast-block { body { "HI" } } }
+                  T{ ast-block { body { "BYE" } } }
+              }
+            }
+         }
+       }
+       { selector "print" }
+    }
+]
+[ "((1 < 10) ifTrue: [ 'HI' ] ifFalse: [ 'BYE' ]) print" test-Expression ] unit-test
+
+[
+    T{ ast-cascade
+       { receiver 12 }
+       { messages
+         {
+           T{ ast-message f "sqrt" }
+           T{ ast-message f "+" { 2 } }
+         }
+       }
+    }
+]
+[ "12 sqrt; + 2" test-Expression ] unit-test
+
+[
+    T{ ast-cascade
+       { receiver T{ ast-message-send f 12 "sqrt" } }
+       { messages
+         {
+           T{ ast-message f "+" { 1 } }
+           T{ ast-message f "+" { 2 } }
+         }
+       }
+    }
+]
+[ "12 sqrt + 1; + 2" test-Expression ] unit-test
+
+[
+    T{ ast-cascade
+       { receiver T{ ast-message-send f 12 "squared" } }
+       { messages
+         {
+           T{ ast-message f "to:" { 100 } }
+           T{ ast-message f "sqrt" }
+         }
+       }
+    }
+]
+[ "12 squared to: 100; sqrt" test-Expression ] unit-test
+
+[
+    T{ ast-message-send f
+        T{ ast-message-send f 1 "+" { 2 } }
+        "*"
+        { 3 }
+    }
+]
+[ "1+2*3" test-Expression ] unit-test
+
+[
+    T{ ast-message-send
+       { receiver
+         T{ ast-message-send
+            { receiver { T{ ast-block { body { "a" } } } } }
+            { selector "at:" }
+            { arguments { 0 } }
+         }
+       }
+       { selector "value" }
+    }
+]
+[ "(#(['a']) at: 0) value" test-Expression ] unit-test
+
+EBNF: test-FinalStatement
+test         = <foreign parse-smalltalk FinalStatement>
+;EBNF
+
+[ T{ ast-name f "value" } ] [ "value" test-FinalStatement ] unit-test
+[ T{ ast-return f T{ ast-name f "value" } } ] [ "^value" test-FinalStatement ] unit-test
+[ T{ ast-assignment f T{ ast-name f "value" } 5 } ] [ "value:=5" test-FinalStatement ] unit-test
+
+EBNF: test-LocalVariableDeclarationList
+test         = <foreign parse-smalltalk LocalVariableDeclarationList>
+;EBNF
+
+[ T{ ast-local-variables f { "i" "j" } } ] [ " |  i j   |" test-LocalVariableDeclarationList ] unit-test
+
+
+[ T{ ast-message-send f T{ ast-name f "x" } "foo:bar:" { 1 2 } } ]
+[ "x foo:1 bar:2" test-Expression ] unit-test
+
+[
+    T{ ast-message-send
+        f
+        T{ ast-message-send f
+            T{ ast-message-send f 3 "factorial" { } }
+            "+"
+            { T{ ast-message-send f 4 "factorial" { } } }
+        }
+        "between:and:"
+        { 10 100 }
+    }
+]
+[ "3 factorial + 4 factorial between: 10 and: 100" test-Expression ] unit-test
+
+[ T{ ast-sequence f { } { 1 2 } } ] [ "1. 2" parse-smalltalk ] unit-test
+
+[ T{ ast-sequence f { } { 1 2 } } ] [ "1. 2." parse-smalltalk ] unit-test
+
+[
+    T{ ast-sequence f { }
+        {
+            T{ ast-class
+               { name "Test" }
+               { superclass "Object" }
+               { ivars { "a" } }
+            }
+        }
+    }
+]
+[ "class Test [|a|]" parse-smalltalk ] unit-test
+
+[
+    T{ ast-sequence f { }
+        {
+            T{ ast-class
+               { name "Test1" }
+               { superclass "Object" }
+               { ivars { "a" } }
+            }
+
+            T{ ast-class
+               { name "Test2" }
+               { superclass "Test1" }
+               { ivars { "b" } }
+            }
+        }
+    }
+]
+[ "class Test1 [|a|]. class Test2 extends Test1 [|b|]" parse-smalltalk ] unit-test
+
+[ ] [ "class Foo []. Tests blah " parse-smalltalk drop ] unit-test
+
+[ ] [ "vocab:smalltalk/parser/test.st" ascii file-contents parse-smalltalk drop ] unit-test
\ No newline at end of file
diff --git a/extra/smalltalk/parser/parser.factor b/extra/smalltalk/parser/parser.factor
new file mode 100644 (file)
index 0000000..c7cafe9
--- /dev/null
@@ -0,0 +1,228 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: peg peg.ebnf smalltalk.ast sequences sequences.deep strings
+math.parser kernel arrays byte-arrays math assocs accessors ;
+IN: smalltalk.parser
+
+! :mode=text:noTabs=true:
+
+! Based on http://chronos-st.blogspot.com/2007/12/smalltalk-in-one-page.html
+
+ERROR: bad-number str ;
+
+: check-number ( str -- n )
+    >string dup string>number [ ] [ bad-number ] ?if ;
+
+EBNF: parse-smalltalk
+
+Character = .
+WhitespaceCharacter = (" " | "\t" | "\n" | "\r" )
+DecimalDigit = [0-9]
+Letter = [A-Za-z]
+
+CommentCharacter = [^"] | '""' => [[ CHAR: " ]]
+Comment = '"' (CommentCharacter)*:s '"' => [[ s >string ast-comment boa ]]
+
+OptionalWhiteSpace = (WhitespaceCharacter | Comment)*
+Whitespace = (WhitespaceCharacter | Comment)+
+
+LetterOrDigit = DecimalDigit | Letter
+Identifier = (Letter | "_"):h (LetterOrDigit | "_")*:t => [[ { h t } flatten >string ]]
+Reference = Identifier => [[ ast-name boa ]]
+
+ConstantReference =   "nil" => [[ nil ]]
+                    | "false" => [[ f ]]
+                    | "true" => [[ t ]]
+PseudoVariableReference =   "self" => [[ self ]]
+                          | "super" => [[ super ]]
+ReservedIdentifier = PseudoVariableReference | ConstantReference
+
+BindableIdentifier = Identifier
+
+UnaryMessageSelector = Identifier
+
+Keyword = Identifier:i ":" => [[ i ":" append ]]
+
+KeywordMessageSelector = Keyword+ => [[ concat ]]
+BinarySelectorChar =   "~" | "!" | "@" | "%" | "&" | "*" | "-" | "+"
+                     | "=" | "|" | "\" | "<" | ">" | "," | "?" | "/"
+BinaryMessageSelector = BinarySelectorChar+ => [[ concat ]]
+
+OptionalMinus = ("-" => [[ CHAR: - ]])?
+IntegerLiteral = (OptionalMinus:m UnsignedIntegerLiteral:i) => [[ i m [ neg ] when ]]
+UnsignedIntegerLiteral =   Radix:r "r" BaseNIntegerLiteral:b => [[ b >string r base> ]]
+                         | DecimalIntegerLiteral => [[ check-number ]]
+DecimalIntegerLiteral = DecimalDigit+
+Radix = DecimalIntegerLiteral => [[ check-number ]]
+BaseNIntegerLiteral = LetterOrDigit+
+FloatingPointLiteral = (OptionalMinus
+                        DecimalIntegerLiteral
+                        ("." => [[ CHAR: . ]] DecimalIntegerLiteral Exponent? | Exponent))
+                        => [[ flatten check-number ]]
+Exponent = "e" => [[ CHAR: e ]] (OptionalMinus DecimalIntegerLiteral)?
+
+CharacterLiteral = "$" Character:c => [[ c ]]
+
+StringLiteral = "'" (StringLiteralCharacter | "''" => [[ CHAR: ' ]])*:s "'"
+                => [[ s >string ]]
+StringLiteralCharacter = [^']
+
+SymbolInArrayLiteral =   KeywordMessageSelector
+                       | UnaryMessageSelector
+                       | BinaryMessageSelector
+SymbolLiteral = "#" (SymbolInArrayLiteral | StringLiteral):s => [[ s intern ]]
+
+ArrayLiteral = (ObjectArrayLiteral | ByteArrayLiteral)
+ObjectArrayLiteral = "#" NestedObjectArrayLiteral:elts => [[ elts ]]
+NestedObjectArrayLiteral = "(" OptionalWhiteSpace
+                           (LiteralArrayElement:h
+                            (Whitespace LiteralArrayElement:e => [[ e ]])*:t
+                            => [[ t h prefix ]]
+                           )?:elts OptionalWhiteSpace ")" => [[ elts >array ]]
+
+LiteralArrayElement =   Literal
+                      | NestedObjectArrayLiteral
+                      | SymbolInArrayLiteral
+                      | ConstantReference
+
+ByteArrayLiteral = "#[" OptionalWhiteSpace
+                        (UnsignedIntegerLiteral:h
+                         (Whitespace UnsignedIntegerLiteral:i => [[ i ]])*:t
+                         => [[ t h prefix ]]
+                        )?:elts OptionalWhiteSpace "]" => [[ elts >byte-array ]]
+
+FormalBlockArgumentDeclaration = ":" BindableIdentifier:i => [[ i ]]
+FormalBlockArgumentDeclarationList =
+                FormalBlockArgumentDeclaration:h
+                (Whitespace FormalBlockArgumentDeclaration:v => [[ v ]])*:t
+                => [[ t h prefix ]]
+
+BlockLiteral = "["
+                (OptionalWhiteSpace
+                 FormalBlockArgumentDeclarationList:args
+                 OptionalWhiteSpace
+                 "|"
+                 => [[ args ]]
+                )?:args
+                ExecutableCode:body
+                "]" => [[ args >array body <ast-block> ]]
+
+Literal = (ConstantReference
+                | FloatingPointLiteral
+                | IntegerLiteral
+                | CharacterLiteral
+                | StringLiteral
+                | ArrayLiteral
+                | SymbolLiteral
+                | BlockLiteral)
+
+NestedExpression = "(" Statement:s OptionalWhiteSpace ")" => [[ s ]]
+Operand =       Literal
+                | PseudoVariableReference
+                | Reference
+                | NestedExpression
+
+UnaryMessage = OptionalWhiteSpace
+               UnaryMessageSelector:s !(":")
+               => [[ s { } ast-message boa ]]
+
+BinaryMessage = OptionalWhiteSpace
+                BinaryMessageSelector:selector
+                OptionalWhiteSpace
+                (UnaryMessageSend | Operand):rhs
+                => [[ selector { rhs } ast-message boa ]]
+                                   
+KeywordMessageSegment = Keyword:k OptionalWhiteSpace (BinaryMessageSend | UnaryMessageSend | Operand):arg => [[ { k arg } ]]
+KeywordMessage = OptionalWhiteSpace
+                 KeywordMessageSegment:h
+                 (OptionalWhiteSpace KeywordMessageSegment:s => [[ s ]])*:t
+                 => [[ t h prefix unzip [ concat ] dip ast-message boa ]]
+
+Message = BinaryMessage | UnaryMessage | KeywordMessage
+
+UnaryMessageSend = (UnaryMessageSend | Operand):lhs
+              UnaryMessage:h
+              (OptionalWhiteSpace ";" Message:m => [[ m ]])*:t
+              => [[ lhs t h prefix >array <ast-cascade> ]]
+
+BinaryMessageSend = (BinaryMessageSend | UnaryMessageSend | Operand):lhs
+              BinaryMessage:h
+              (OptionalWhiteSpace ";" Message:m => [[ m ]])*:t
+              => [[ lhs t h prefix >array <ast-cascade> ]]
+
+KeywordMessageSend = (BinaryMessageSend | UnaryMessageSend | Operand):lhs
+              KeywordMessage:h
+              (OptionalWhiteSpace ";" Message:m => [[ m ]])*:t
+              => [[ lhs t h prefix >array <ast-cascade> ]]
+
+Expression = OptionalWhiteSpace
+             (KeywordMessageSend | BinaryMessageSend | UnaryMessageSend | Operand):e
+             => [[ e ]]
+
+AssignmentOperation = OptionalWhiteSpace BindableIdentifier:i
+                      OptionalWhiteSpace ":=" OptionalWhiteSpace => [[ i ast-name boa ]]
+AssignmentStatement = AssignmentOperation:a Statement:s => [[ a s ast-assignment boa ]]
+Statement = ClassDeclaration | ForeignClassDeclaration | AssignmentStatement | Expression
+
+MethodReturnOperator = OptionalWhiteSpace "^"
+FinalStatement = (MethodReturnOperator Statement:s => [[ s ast-return boa ]])
+                 | Statement
+
+LocalVariableDeclarationList = OptionalWhiteSpace "|" OptionalWhiteSpace
+                (BindableIdentifier:h
+                 (Whitespace BindableIdentifier:b => [[ b ]])*:t
+                 => [[ t h prefix ]]
+                )?:b OptionalWhiteSpace "|" => [[ b >array ast-local-variables boa ]]
+
+EndStatement = "."
+
+ExecutableCode = (LocalVariableDeclarationList)?:locals
+                 (Statement:s OptionalWhiteSpace EndStatement => [[ s ]])*:h
+                 (FinalStatement:t (EndStatement)? => [[ t ]])?:t
+                 OptionalWhiteSpace
+                 => [[ h t [ suffix ] when* locals [ prefix ] when* >array ]]
+
+TopLevelForm = ExecutableCode => [[ <ast-sequence> ]]
+
+UnaryMethodHeader = UnaryMessageSelector:selector
+                  => [[ { selector { } } ]]
+BinaryMethodHeader = BinaryMessageSelector:selector OptionalWhiteSpace BindableIdentifier:identifier
+                   => [[ { selector { identifier } } ]]
+KeywordMethodHeaderSegment = Keyword:keyword
+                             OptionalWhiteSpace
+                             BindableIdentifier:identifier => [[ { keyword identifier } ]]
+KeywordMethodHeader = KeywordMethodHeaderSegment:h (Whitespace KeywordMethodHeaderSegment:s => [[ s ]])*:t
+                    => [[ t h prefix unzip [ concat ] dip 2array ]]
+MethodHeader =   KeywordMethodHeader
+               | BinaryMethodHeader
+               | UnaryMethodHeader
+MethodDeclaration = OptionalWhiteSpace "method" OptionalWhiteSpace MethodHeader:header
+        OptionalWhiteSpace "["
+        ExecutableCode:code
+        "]"
+        => [[ header first2 code <ast-method> ]]
+
+ClassDeclaration = OptionalWhiteSpace "class" OptionalWhiteSpace Identifier:name
+        OptionalWhiteSpace
+        ("extends" OptionalWhiteSpace Identifier:superclass OptionalWhiteSpace => [[ superclass ]])?:superclass
+        OptionalWhiteSpace "["
+        (OptionalWhiteSpace LocalVariableDeclarationList:l => [[ l names>> ]])?:ivars
+        (MethodDeclaration:h
+         (OptionalWhiteSpace
+          EndStatement
+          OptionalWhiteSpace
+          MethodDeclaration:m => [[ m ]])*:t (EndStatement)?
+          => [[ t h prefix ]]
+         )?:methods
+        OptionalWhiteSpace "]"
+        => [[ name superclass "Object" or ivars >array methods >array ast-class boa ]]
+
+ForeignClassDeclaration = OptionalWhiteSpace "foreign"
+                          OptionalWhiteSpace Identifier:name
+                          OptionalWhiteSpace Literal:class
+                          => [[ class name ast-foreign boa ]]
+End = !(.)
+
+Program = TopLevelForm End
+
+;EBNF
\ No newline at end of file
diff --git a/extra/smalltalk/parser/test.st b/extra/smalltalk/parser/test.st
new file mode 100644 (file)
index 0000000..063f208
--- /dev/null
@@ -0,0 +1,65 @@
+class TreeNode extends Object [
+    |left right item|
+
+    method binarytrees: n to: output [
+        | minDepth maxDepth stretchDepth check longLivedTree iterations |
+        minDepth := 4.
+        maxDepth := minDepth + 2 max: n.
+        stretchDepth := maxDepth + 1.
+
+        check := (TreeNode bottomUpTree: 0 depth: stretchDepth) itemCheck.
+        output
+            nextPutAll: 'stretch tree of depth '; print: stretchDepth; tab;
+            nextPutAll: ' check: '; print: check; nl.
+
+        longLivedTree := TreeNode bottomUpTree: 0 depth: maxDepth.
+        minDepth to: maxDepth by: 2 do: [:depth|
+            iterations := 1 bitShift: maxDepth - depth + minDepth.
+
+            check := 0.
+            1 to: iterations do: [:i|
+                check := check + (TreeNode bottomUpTree: i depth: depth) itemCheck.
+                check := check + (TreeNode bottomUpTree: -1*i depth: depth) itemCheck
+            ].
+            output
+                print:  (2*iterations); tab;
+                nextPutAll: ' trees of depth '; print: depth; tab;
+                nextPutAll: ' check: '; print: check; nl
+            ].
+
+        output
+            nextPutAll: 'long lived tree of depth '; print: maxDepth; tab;
+            nextPutAll: ' check: '; print: longLivedTree itemCheck; nl
+    ].
+    
+    method binarytrees: arg [
+        self binarytrees: arg to: self stdout.
+        ^''
+    ].
+
+    method left: leftChild right: rightChild item: anItem [
+        left := leftChild.
+        right := rightChild.
+        item := anItem
+    ].
+
+    method itemCheck [
+        ^left isNil
+            ifTrue: [item] ifFalse: [item + (left itemCheck - right itemCheck)]
+    ].
+
+    method bottomUpTree: anItem depth: anInteger [
+        ^(anInteger > 0)
+            ifTrue: [
+                self
+                    left: (self bottomUpTree: 2*anItem - 1 depth: anInteger - 1)
+                    right: (self bottomUpTree: 2*anItem depth: anInteger - 1)
+                    item: anItem
+            ] ifFalse: [self left: nil right: nil item: anItem]
+    ].
+
+    method left: leftChild right: rightChild item: anItem [
+        ^(super new) left: leftChild right: rightChild item: anItem
+    ]
+].
+
diff --git a/extra/smalltalk/printer/authors.txt b/extra/smalltalk/printer/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/printer/printer-tests.factor b/extra/smalltalk/printer/printer-tests.factor
new file mode 100644 (file)
index 0000000..e9f4bd9
--- /dev/null
@@ -0,0 +1,4 @@
+IN: smalltalk.printer.tests
+USING: smalltalk.printer tools.test ;
+
+[ "#((1 2) 'hi')" ] [ { { 1 2 } "hi" } smalltalk>string ] unit-test
\ No newline at end of file
diff --git a/extra/smalltalk/printer/printer.factor b/extra/smalltalk/printer/printer.factor
new file mode 100644 (file)
index 0000000..9b6aa11
--- /dev/null
@@ -0,0 +1,34 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays byte-arrays kernel make math
+math.parser prettyprint sequences smalltalk.ast strings ;
+IN: smalltalk.printer
+
+GENERIC: smalltalk>string ( object -- string )
+
+M: real smalltalk>string number>string ;
+
+M: string smalltalk>string
+    [
+        "'" %
+        [ dup CHAR: ' = [ dup , , ] [ , ] if ] each
+        "'" %
+    ] "" make ;
+
+GENERIC: array-element>string ( object -- string )
+
+M: object array-element>string smalltalk>string ;
+
+M: array array-element>string
+    [ array-element>string ] map " " join "(" ")" surround ;
+
+M: array smalltalk>string
+    array-element>string "#" prepend ;
+
+M: byte-array smalltalk>string
+    [ number>string ] { } map-as " " join "#[" "]" surround ;
+
+M: symbol smalltalk>string
+    name>> smalltalk>string "#" prepend ;
+
+M: object smalltalk>string unparse-short ;
\ No newline at end of file
diff --git a/extra/smalltalk/selectors/authors.txt b/extra/smalltalk/selectors/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/smalltalk/selectors/selectors.factor b/extra/smalltalk/selectors/selectors.factor
new file mode 100644 (file)
index 0000000..2ea1e99
--- /dev/null
@@ -0,0 +1,28 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators effects generic generic.standard
+kernel sequences words lexer ;
+IN: smalltalk.selectors
+
+SYMBOLS: unary binary keyword ;
+
+: selector-type ( selector -- type )
+    {
+        { [ dup [ "~!@%&*-+=|\\<>,?/" member? ] all? ] [ binary ] }
+        { [ CHAR: : over member? ] [ keyword ] }
+        [ unary ]
+    } cond nip ;
+
+: selector>effect ( selector -- effect )
+    dup selector-type {
+        { unary [ drop 0 ] }
+        { binary [ drop 1 ] }
+        { keyword [ [ CHAR: : = ] count ] }
+    } case "receiver" suffix { "result" } <effect> ;
+
+: selector>generic ( selector -- generic )
+    [ "selector-" prepend "smalltalk.selectors" create dup ]
+    [ selector>effect ]
+    bi define-simple-generic ;
+
+SYNTAX: SELECTOR: scan selector>generic drop ;
\ No newline at end of file
diff --git a/extra/spider/report/authors.txt b/extra/spider/report/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/spider/report/report.factor b/extra/spider/report/report.factor
new file mode 100644 (file)
index 0000000..7779b23
--- /dev/null
@@ -0,0 +1,124 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs combinators kernel math
+math.statistics namespaces sequences sorting xml.syntax
+spider urls html ;
+IN: spider.report
+
+SYMBOL: network-failures
+SYMBOL: broken-pages
+SYMBOL: timings
+
+: record-broken-page ( url spider-result -- )
+    headers>> [ code>> ] [ message>> ] bi 2array 2array
+    broken-pages push ;
+
+: record-page-timings ( url spider-result -- )
+    fetched-in>> 2array timings get push ;
+
+: record-network-failure ( url -- )
+    network-failures get push ;
+
+: process-result ( url spider-result -- )
+    {
+        { f [ record-network-failure ] }
+        [
+            dup headers>> code>> 200 =
+            [ record-page-timings ] [ record-broken-page ] if
+        ]
+    } case ;
+
+CONSTANT: slowest 5
+
+SYMBOL: slowest-pages
+SYMBOL: mean-time
+SYMBOL: median-time
+SYMBOL: time-std
+
+: process-timings ( -- )
+    timings get sort-values
+    [ slowest short tail* reverse slowest-pages set ]
+    [
+        values [
+            [ mean 1000000 /f mean-time set ]
+            [ median 1000000 /f median-time set ]
+            [ std 1000000 /f time-std set ] tri
+        ] unless-empty
+    ] bi ;
+
+: process-results ( results -- )
+    V{ } clone network-failures set
+    V{ } clone broken-pages set
+    V{ } clone timings set
+    [ process-result ] assoc-each
+    process-timings ;
+
+: info-table ( alist -- html )
+    [
+        first2 dupd 1000000 /f
+        [XML
+        <tr><td><a href=<->><-></a></td><td><-> seconds</td></tr>
+        XML]
+    ] map [XML <table border="1"><-></table> XML] ;
+
+: report-broken-pages ( -- html )
+    broken-pages get info-table ;
+
+: report-network-failures ( -- html )
+    network-failures get [
+        dup [XML <li><a href=<->><-></a></li> XML]
+    ] map [XML <ul><-></ul> XML] ;
+
+: slowest-pages-table ( -- html )
+    slowest-pages get info-table ;
+
+: timing-summary-table ( -- html )
+    mean-time get
+    median-time get
+    time-std get
+    [XML
+    <table border="1">
+    <tr><th>Mean</th><td><-> seconds</td></tr>
+    <tr><th>Median</th><td><-> seconds</td></tr>
+    <tr><th>Standard deviation</th><td><-> seconds</td></tr>
+    </table>
+    XML] ;
+
+: report-timings ( -- html )
+    slowest-pages-table
+    timing-summary-table
+    [XML
+    <h3>Slowest pages</h3>
+    <->
+
+    <h3>Summary</h3>
+    <->
+    XML] ;
+
+: generate-report ( -- html )
+    url get dup
+    report-broken-pages
+    report-network-failures
+    report-timings
+    [XML
+    <h1>Spider report</h1>
+    URL: <a href=<->><-></a>
+
+    <h2>Broken pages</h2>
+    <->
+
+    <h2>Network failures</h2>
+    <->
+
+    <h2>Load times</h2>
+    <->
+    XML] ;
+
+: spider-report ( spider -- html )
+    [ "Spider report" f ] dip
+    [
+        [ base>> url set ]
+        [ spidered>> process-results ] bi
+        generate-report
+    ] with-scope
+    simple-page ;
index 41dd13e918dabe64634c898db006ebfd1c37f7e7..4ed00d39f60c9f50fd7ce203c90054d862bbf230 100644 (file)
@@ -16,14 +16,9 @@ HELP: run-spider
      { "spider" spider } }
 { $description "Runs a spider until completion. See the " { $subsection "spider-tutorial" } " for a complete description of the tuple slots that affect how thet spider works." } ;
 
-HELP: slurp-heap-while
-{ $values
-     { "heap" "a heap" } { "quot1" quotation } { "quot2" quotation } }
-{ $description "Removes values from a heap that match the predicate quotation " { $snippet "quot1" } " and processes them with " { $snippet "quot2" } " until the predicate quotation no longer matches." } ;
-
 ARTICLE: "spider-tutorial" "Spider tutorial"
 "To create a new spider, call the " { $link <spider> } " word with a link to the site you wish to spider."
-{ $code <" "http://concatentative.org" <spider> "> }
+{ $code <" "http://concatenative.org" <spider> "> }
 "The max-depth is initialized to 0, which retrieves just the initial page. Let's initialize it to something more fun:"
 { $code <" 1 >>max-depth "> }
 "Now the spider will retrieve the first page and all the pages it links to in the same domain." $nl
index bd5b2668bead07fab6ef5e747e5dd196c84d53a9..17e91473c3795df9be7dfd2f75f0705b1a1873b4 100644 (file)
@@ -3,34 +3,43 @@
 USING: accessors fry html.parser html.parser.analyzer
 http.client kernel tools.time sets assocs sequences
 concurrency.combinators io threads namespaces math multiline
-heaps math.parser inspector urls assoc-heaps logging
-combinators.short-circuit continuations calendar prettyprint ;
+math.parser inspector urls logging combinators.short-circuit
+continuations calendar prettyprint dlists deques locals
+spider.unique-deque combinators concurrency.semaphores ;
 IN: spider
 
 TUPLE: spider base count max-count sleep max-depth initial-links
-filters spidered todo nonmatching quiet ;
+filters spidered todo nonmatching quiet currently-spidering
+#threads semaphore follow-robots? robots ;
 
-TUPLE: spider-result url depth headers fetch-time parsed-html
-links processing-time timestamp ;
+TUPLE: spider-result url depth headers
+fetched-in parsed-html links processed-in fetched-at ;
 
 : <spider> ( base -- spider )
     >url
     spider new
         over >>base
-        swap 0 <unique-min-heap> [ heap-push ] keep >>todo
-        <unique-min-heap> >>nonmatching
+        over >>currently-spidering
+        swap 0 <unique-deque> [ push-url ] keep >>todo
+        <unique-deque> >>nonmatching
         0 >>max-depth
         0 >>count
         1/0. >>max-count
-        H{ } clone >>spidered ;
+        H{ } clone >>spidered
+        1 [ >>#threads ] [ <semaphore> >>semaphore ] bi ;
+
+: <spider-result> ( url depth -- spider-result )
+    spider-result new
+        swap >>depth
+        swap >>url ;
 
 <PRIVATE
 
 : apply-filters ( links spider -- links' )
-    filters>> [ '[ _ 1&& ] filter ] when* ;
+    filters>> [ '[ [ _ 1&& ] filter ] call( seq -- seq' ) ] when* ;
 
-: push-links ( links level assoc-heap -- )
-    '[ _ _ heap-push ] each ;
+: push-links ( links level unique-deque -- )
+    '[ _ _ push-url ] each ;
 
 : add-todo ( links level spider -- )
     todo>> push-links ;
@@ -38,64 +47,81 @@ links processing-time timestamp ;
 : add-nonmatching ( links level spider -- )
     nonmatching>> push-links ;
 
-: filter-base ( spider spider-result -- base-links nonmatching-links )
+: filter-base-links ( spider spider-result -- base-links nonmatching-links )
     [ base>> host>> ] [ links>> prune ] bi*
     [ host>> = ] with partition ;
 
 : add-spidered ( spider spider-result -- )
     [ [ 1+ ] change-count ] dip
     2dup [ spidered>> ] [ dup url>> ] bi* rot set-at
-    [ filter-base ] 2keep
+    [ filter-base-links ] 2keep
     depth>> 1+ swap
     [ add-nonmatching ]
     [ tuck [ apply-filters ] 2dip add-todo ] 2bi ;
 
-: normalize-hrefs ( links -- links' )
-    [ >url ] map
-    spider get base>> swap [ derive-url ] with map ;
+: normalize-hrefs ( base links -- links' )
+    [ derive-url ] with map ;
 
-: print-spidering ( url depth -- )
+: print-spidering ( spider-result -- )
+    [ url>> ] [ depth>> ] bi
     "depth: " write number>string write
     ", spidering: " write . yield ;
 
-: (spider-page) ( url depth -- spider-result )
-    f pick spider get spidered>> set-at
-    over '[ _ http-get ] benchmark swap
-    [ parse-html dup find-hrefs normalize-hrefs ] benchmark
-    now spider-result boa ;
-
-: spider-page ( url depth -- )
-    spider get quiet>> [ 2dup print-spidering ] unless
-    (spider-page)
-    spider get [ quiet>> [ dup describe ] unless ]
-    [ swap add-spidered ] bi ;
+:: fill-spidered-result ( spider spider-result -- )
+    f spider-result url>> spider spidered>> set-at
+    [ spider-result url>> http-get ] benchmark :> fetched-in :> html :> headers
+    [
+        html parse-html
+        spider currently-spidering>>
+        over find-all-links normalize-hrefs
+    ] benchmark :> processed-in :> links :> parsed-html
+    spider-result
+        headers >>headers
+        fetched-in >>fetched-in
+        parsed-html >>parsed-html
+        links >>links
+        processed-in >>processed-in
+        now >>fetched-at drop ;
+
+:: spider-page ( spider spider-result -- )
+    spider quiet>> [ spider-result print-spidering ] unless
+    spider spider-result fill-spidered-result
+    spider quiet>> [ spider-result describe ] unless
+    spider spider-result add-spidered ;
 
 \ spider-page ERROR add-error-logging
 
-: spider-sleep ( -- )
-    spider get sleep>> [ sleep ] when* ;
+: spider-sleep ( spider -- ) sleep>> [ sleep ] when* ;
+
+: queue-initial-links ( spider -- )
+    [
+        [ currently-spidering>> ] [ initial-links>> ] bi normalize-hrefs 0
+    ] keep add-todo ;
 
-: queue-initial-links ( spider -- spider )
-    [ initial-links>> normalize-hrefs 0 ] keep
-    [ add-todo ] keep ;
+: spider-page? ( spider -- ? )
+    {
+        [ todo>> deque>> deque-empty? not ]
+        [ [ todo>> peek-url depth>> ] [ max-depth>> ] bi < ]
+        [ [ count>> ] [ max-count>> ] bi < ]
+    } 1&& ;
 
-: slurp-heap-while ( heap quot1 quot2: ( value key -- ) -- )
-    pick heap-empty? [ 3drop ] [
-        [ [ heap-pop dup ] 2dip slip [ t ] compose [ 2drop f ] if ]
-        [ roll [ slurp-heap-while ] [ 3drop ] if ] 3bi
-    ] if ; inline recursive
+: setup-next-url ( spider -- spider spider-result )
+    dup todo>> peek-url url>> >>currently-spidering
+    dup todo>> pop-url [ url>> ] [ depth>> ] bi <spider-result> ;
+
+: spider-next-page ( spider -- )
+    setup-next-url spider-page ;
 
 PRIVATE>
 
+: run-spider-loop ( spider -- )
+    dup spider-page? [
+        [ spider-next-page ] [ spider-sleep ] [ run-spider-loop ] tri
+    ] [
+        drop
+    ] if ;
+
 : run-spider ( spider -- spider )
     "spider" [
-        dup spider [
-            queue-initial-links
-            [ todo>> ] [ max-depth>> ] bi
-            '[
-                _ <= spider get
-                [ count>> ] [ max-count>> ] bi < and
-            ] [ spider-page spider-sleep ] slurp-heap-while
-            spider get
-        ] with-variable
+        dup queue-initial-links [ run-spider-loop ] keep
     ] with-logging ;
diff --git a/extra/spider/unique-deque/authors.txt b/extra/spider/unique-deque/authors.txt
new file mode 100644 (file)
index 0000000..b4bd0e7
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
\ No newline at end of file
diff --git a/extra/spider/unique-deque/unique-deque.factor b/extra/spider/unique-deque/unique-deque.factor
new file mode 100644 (file)
index 0000000..b26797f
--- /dev/null
@@ -0,0 +1,37 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs deques dlists kernel spider ;
+IN: spider.unique-deque
+
+TUPLE: todo-url url depth ;
+
+: <todo-url> ( url depth -- todo-url )
+    todo-url new
+        swap >>depth
+        swap >>url ;
+
+TUPLE: unique-deque assoc deque ;
+
+: <unique-deque> ( -- unique-deque )
+    H{ } clone <dlist> unique-deque boa ;
+
+: url-exists? ( url unique-deque -- ? )
+    [ url>> ] [ assoc>> ] bi* key? ;
+
+: push-url ( url depth unique-deque -- )
+    [ <todo-url> ] dip 2dup url-exists? [
+        2drop
+    ] [
+        [ [ [ t ] dip url>> ] [ assoc>> ] bi* set-at ]
+        [ deque>> push-back ] 2bi
+    ] if ;
+
+: pop-url ( unique-deque -- todo-url ) deque>> pop-front ;
+
+: peek-url ( unique-deque -- todo-url ) deque>> peek-front ;
+
+: slurp-deque-when ( deque quot1 quot2: ( value -- ) -- )
+    pick deque-empty? [ 3drop ] [
+        [ [ pop-front dup ] 2dip slip [ t ] compose [ drop f ] if ]
+        [ roll [ slurp-deque-when ] [ 3drop ] if ] 3bi
+    ] if ; inline recursive
diff --git a/extra/state-machine/authors.txt b/extra/state-machine/authors.txt
deleted file mode 100755 (executable)
index f990dd0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Daniel Ehrenberg
diff --git a/extra/state-machine/state-machine.factor b/extra/state-machine/state-machine.factor
deleted file mode 100755 (executable)
index 18c3720..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-USING: kernel parser lexer strings math namespaces make
-sequences words io arrays quotations debugger accessors
-sequences.private ;
-IN: state-machine
-
-: STATES:
-    ! STATES: set-name state1 state2 ... ;
-    ";" parse-tokens
-    [ length ] keep
-    unclip suffix
-    [ create-in swap 1quotation define ] 2each ; parsing
-
-TUPLE: state place data ;
-
-ERROR: missing-state ;
-
-M: missing-state error.
-    drop "Missing state" print ;
-
-: make-machine ( states -- table quot )
-    ! quot is ( state string -- output-string )
-    [ missing-state ] <array> dup
-    [
-        [ [ dup [ data>> ] [ place>> ] bi ] dip ] %
-        [ swapd bounds-check dispatch ] curry ,
-        [ each pick (>>place) swap (>>date) ] %
-    ] [ ] make [ over make ] curry ;
-
-: define-machine ( word state-class -- )
-    execute make-machine
-    [ over ] dip define
-    "state-table" set-word-prop ;
-
-: MACHINE:
-    ! MACHINE: utf8 unicode-states
-    CREATE scan-word define-machine ; parsing
-
-: S:
-    ! S: state state-machine definition... ;
-    ! definition MUST be ( data char -- newdata state )
-    scan-word execute scan-word "state-table" word-prop
-    parse-definition -rot set-nth ; parsing
index 0f0c349b8ea761c6b91b393e61172bfb23180f41..71b30cd175fd1be468e29d15ecd5f579aae1bec7 100644 (file)
@@ -3,8 +3,8 @@ USING: accessors arrays literals math math.affine-transforms
 math.functions multiline sequences svg tools.test xml xml.traversal ;
 IN: svg.tests
 
-{ 1.0 2.25 } { -3.0 4.0 } { 5.5 0.000001 } <affine-transform> 1array [
-    "matrix ( 1 +2.25 -3  , 0.4e+1  ,5.5, 1e-6 )" svg-transform>affine-transform
+{ 1.0 2.25 } { -3.0 4.0 } { 5.5 0.5 } <affine-transform> 1array [
+    "matrix ( 1 +2.25 -3  , 0.4e+1  ,5.5, 5e-1 )" svg-transform>affine-transform
 ] unit-test
 
 { 1.0 0.0 } { 0.0 1.0 } { 5.0 10.0 } <affine-transform> 1array [
@@ -27,17 +27,22 @@ IN: svg.tests
     "scale(2.0 4.0)" svg-transform>affine-transform
 ] unit-test
 
-{ 1.0 0.0 } { $[ 45 degrees tan ] 1.0 } { 0.0 0.0 } <affine-transform> 1array [
+[ t ] [
     "skewX(45)" svg-transform>affine-transform
+    { 1.0 0.0 } { 1.0 1.0 } { 0.0 0.0 } <affine-transform> 0.001 a~
 ] unit-test
 
-{ 1.0 $[ -45 degrees tan ] } { 0.0 1.0 } { 0.0 0.0 } <affine-transform> 1array [
+[ t ] [
     "skewY(-4.5e1)" svg-transform>affine-transform
+    { 1.0 -1.0 } { 0.0 1.0 } { 0.0 0.0 } <affine-transform> 0.001 a~
 ] unit-test
 
-{ $[  30 degrees cos ] $[ 30 degrees sin ] }
-{ $[ -30 degrees sin ] $[ 30 degrees cos ] } { 0.0 0.0 } <affine-transform> 1array [
+[ t ] [
     "rotate(30)" svg-transform>affine-transform
+    { $[ 0.75 sqrt ] 0.5            }
+    { -0.5           $[ 0.75 sqrt ] }
+    {  0.0           0.0            } <affine-transform> 
+    0.001 a~
 ] unit-test
 
 [ t ] [
@@ -101,7 +106,7 @@ STRING: test-svg-string
 </svg>
 ;
 
-: test-svg-path
+: test-svg-path ( -- obj )
     test-svg-string string>xml body>> children-tags first ;
 
 [ { T{ moveto f { -1.0 -1.0 } f } T{ lineto f { 2.0 2.0 } t } } ]
index f8c901ff562a4bd34f60de5d6cb437d5c19dcd79..0169249e81952ffe15cf1f86394d798c8721a5b4 100644 (file)
@@ -8,7 +8,7 @@ IN: tetris.gl
 #! OpenGL rendering for tetris
 
 : draw-block ( block -- )
-    [ { 1 1 } gl-fill-rect ] with-translation ;
+    { 1 1 } gl-fill-rect ;
 
 : draw-piece-blocks ( piece -- )
     piece-blocks [ draw-block ] each ;
@@ -37,7 +37,7 @@ IN: tetris.gl
 
 : draw-tetris ( width height tetris -- )
     #! width and height are in pixels
-    GL_MODELVIEW [
+    [
         {
             [ board>> scale-board ]
             [ board>> draw-board ]
diff --git a/extra/trees/authors.txt b/extra/trees/authors.txt
new file mode 100644 (file)
index 0000000..39c1f37
--- /dev/null
@@ -0,0 +1,2 @@
+Alex Chapman
+Daniel Ehrenberg
diff --git a/extra/trees/avl/authors.txt b/extra/trees/avl/authors.txt
new file mode 100644 (file)
index 0000000..39c1f37
--- /dev/null
@@ -0,0 +1,2 @@
+Alex Chapman
+Daniel Ehrenberg
diff --git a/extra/trees/avl/avl-docs.factor b/extra/trees/avl/avl-docs.factor
new file mode 100644 (file)
index 0000000..3b18f91
--- /dev/null
@@ -0,0 +1,27 @@
+USING: help.syntax help.markup assocs ;
+IN: trees.avl 
+
+HELP: AVL{
+{ $syntax "AVL{ { key value }... }" }
+{ $values { "key" "a key" } { "value" "a value" } }
+{ $description "Literal syntax for an AVL tree." } ;
+
+HELP: <avl>
+{ $values { "tree" avl } }
+{ $description "Creates an empty AVL tree" } ;
+
+HELP: >avl
+{ $values { "assoc" assoc } { "avl" avl } }
+{ $description "Converts any " { $link assoc } " into an AVL tree." } ;
+
+HELP: avl
+{ $class-description "This is the class for AVL trees. These conform to the assoc protocol and have efficient (logarithmic time) storage and retrieval operations." } ;
+
+ARTICLE: "trees.avl" "AVL trees"
+"This is a library for AVL trees, with logarithmic time storage and retrieval operations. These trees conform to the assoc protocol."
+{ $subsection avl }
+{ $subsection <avl> }
+{ $subsection >avl }
+{ $subsection POSTPONE: AVL{ } ;
+
+ABOUT: "trees.avl"
diff --git a/extra/trees/avl/avl-tests.factor b/extra/trees/avl/avl-tests.factor
new file mode 100755 (executable)
index 0000000..f9edc9c
--- /dev/null
@@ -0,0 +1,117 @@
+USING: kernel tools.test trees trees.avl math random sequences
+assocs accessors ;
+IN: trees.avl.tests
+
+[ "key1" 0 "key2" 0 ] [
+    T{ avl-node f "key1" f f T{ avl-node f "key2" f f 1 } 2 }
+    [ single-rotate ] go-left
+    [ left>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>>
+] unit-test
+
+[ "key1" 0 "key2" 0 ] [
+    T{ avl-node f "key1" f f T{ avl-node f "key2" f f f 1 } 2 }
+    [ select-rotate ] go-left
+    [ left>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>>
+] unit-test
+
+[ "key1" 0 "key2" 0 ] [
+    T{ avl-node f "key1" f T{ avl-node f "key2" f f f -1 } f -2 }
+    [ single-rotate ] go-right
+    [ right>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>>
+] unit-test
+
+[ "key1" 0 "key2" 0 ] [
+    T{ avl-node f "key1" f T{ avl-node f "key2" f f f -1 } f -2 }
+    [ select-rotate ] go-right
+    [ right>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>>
+] unit-test
+
+[ "key1" -1 "key2" 0 "key3" 0 ]
+[ T{ avl-node f "key1" f f
+        T{ avl-node f "key2" f 
+            T{ avl-node f "key3" f f f 1 } f -1 } 2 }
+    [ double-rotate ] go-left
+    [ left>> dup key>> swap balance>> ] keep
+    [ right>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>> ] unit-test
+[ "key1" 0 "key2" 0 "key3" 0 ]
+[ T{ avl-node f "key1" f f
+        T{ avl-node f "key2" f
+            T{ avl-node f "key3" f f f 0 } f -1 } 2 } 
+    [ double-rotate ] go-left
+    [ left>> dup key>> swap balance>> ] keep
+    [ right>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>> ] unit-test
+[ "key1" 0 "key2" 1 "key3" 0 ]
+[ T{ avl-node f "key1" f f
+        T{ avl-node f "key2" f
+            T{ avl-node f "key3" f f f -1 } f -1 } 2 } 
+    [ double-rotate ] go-left
+    [ left>> dup key>> swap balance>> ] keep
+    [ right>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>> ] unit-test
+
+[ "key1" 1 "key2" 0 "key3" 0 ]
+[ T{ avl-node f "key1" f
+        T{ avl-node f "key2" f f
+            T{ avl-node f "key3" f f f -1 } 1 } f -2 }
+    [ double-rotate ] go-right
+    [ right>> dup key>> swap balance>> ] keep
+    [ left>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>> ] unit-test
+[ "key1" 0 "key2" 0 "key3" 0 ]
+[ T{ avl-node f "key1" f
+        T{ avl-node f "key2" f f
+            T{ avl-node f "key3" f f f 0 } 1 } f -2 }
+    [ double-rotate ] go-right
+    [ right>> dup key>> swap balance>> ] keep
+    [ left>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>> ] unit-test
+[ "key1" 0 "key2" -1 "key3" 0 ]
+[ T{ avl-node f "key1" f
+        T{ avl-node f "key2" f f
+            T{ avl-node f "key3" f f f 1 } 1 } f -2 }
+    [ double-rotate ] go-right
+    [ right>> dup key>> swap balance>> ] keep
+    [ left>> dup key>> swap balance>> ] keep
+    dup key>> swap balance>> ] unit-test
+
+[ "eight" ] [
+    <avl> "seven" 7 pick set-at
+    "eight" 8 pick set-at "nine" 9 pick set-at
+    root>> value>>
+] unit-test
+
+[ "another eight" ] [ ! ERROR!
+    <avl> "seven" 7 pick set-at
+    "another eight" 8 pick set-at 8 swap at
+] unit-test
+
+: test-tree ( -- tree )
+    AVL{
+        { 7 "seven" }
+        { 9 "nine" }
+        { 4 "four" } 
+        { 4 "replaced four" } 
+        { 7 "replaced seven" }
+    } clone ;
+
+! test set-at, at, at*
+[ t ] [ test-tree avl? ] unit-test
+[ "seven" ] [ <avl> "seven" 7 pick set-at 7 swap at ] unit-test
+[ "seven" t ] [ <avl> "seven" 7 pick set-at 7 swap at* ] unit-test
+[ f f ] [ <avl> "seven" 7 pick set-at 8 swap at* ] unit-test
+[ "seven" ] [ <avl> "seven" 7 pick set-at 7 swap at ] unit-test
+[ "replacement" ] [ <avl> "seven" 7 pick set-at "replacement" 7 pick set-at 7 swap at ] unit-test
+[ "nine" ] [ test-tree 9 swap at ] unit-test
+[ "replaced four" ] [ test-tree 4 swap at ] unit-test
+[ "replaced seven" ] [ test-tree 7 swap at ] unit-test
+
+! test delete-at--all errors!
+[ f ] [ test-tree 9 over delete-at 9 swap at ] unit-test
+[ "replaced seven" ] [ test-tree 9 over delete-at 7 swap at ] unit-test
+[ "nine" ] [ test-tree 7 over delete-at 4 over delete-at 9 swap at ] unit-test
diff --git a/extra/trees/avl/avl.factor b/extra/trees/avl/avl.factor
new file mode 100755 (executable)
index 0000000..04c7022
--- /dev/null
@@ -0,0 +1,158 @@
+! Copyright (C) 2007 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators kernel generic math math.functions
+math.parser namespaces io sequences trees
+assocs parser accessors math.order prettyprint.custom ;
+IN: trees.avl
+
+TUPLE: avl < tree ;
+
+: <avl> ( -- tree )
+    avl new-tree ;
+
+TUPLE: avl-node < node balance ;
+
+: <avl-node> ( key value -- node )
+    avl-node new-node
+        0 >>balance ;
+
+: increase-balance ( node amount -- )
+    swap [ + ] change-balance drop ;
+
+: rotate ( node -- node )
+    dup node+link dup node-link pick set-node+link
+    tuck set-node-link ;    
+
+: single-rotate ( node -- node )
+    0 over (>>balance) 0 over node+link 
+    (>>balance) rotate ;
+
+: pick-balances ( a node -- balance balance )
+    balance>> {
+        { [ dup zero? ] [ 2drop 0 0 ] }
+        { [ over = ] [ neg 0 ] }
+        [ 0 swap ]
+    } cond ;
+
+: double-rotate ( node -- node )
+    [
+        node+link [
+            node-link current-side get neg
+            over pick-balances rot 0 swap (>>balance)
+        ] keep (>>balance)
+    ] keep swap >>balance
+    dup node+link [ rotate ] with-other-side
+    over set-node+link rotate ;
+
+: select-rotate ( node -- node )
+    dup node+link balance>> current-side get =
+    [ double-rotate ] [ single-rotate ] if ;
+
+: balance-insert ( node -- node taller? )
+    dup balance>> {
+        { [ dup zero? ] [ drop f ] }
+        { [ dup abs 2 = ]
+          [ sgn neg [ select-rotate ] with-side f ] }
+        { [ drop t ] [ t ] } ! balance is -1 or 1, tree is taller
+    } cond ;
+
+DEFER: avl-set
+
+: avl-insert ( value key node -- node taller? )
+    2dup key>> before? left right ? [
+        [ node-link avl-set ] keep swap
+        [ tuck set-node-link ] dip
+        [ dup current-side get increase-balance balance-insert ]
+        [ f ] if
+    ] with-side ;
+
+: (avl-set) ( value key node -- node taller? )
+    2dup key>> = [
+        -rot pick (>>key) over (>>value) f
+    ] [ avl-insert ] if ;
+
+: avl-set ( value key node -- node taller? )
+    [ (avl-set) ] [ swap <avl-node> t ] if* ;
+
+M: avl set-at ( value key node -- node )
+    [ avl-set drop ] change-root drop ;
+
+: delete-select-rotate ( node -- node shorter? )
+    dup node+link balance>> zero? [
+        current-side get neg over (>>balance)
+        current-side get over node+link (>>balance) rotate f
+    ] [
+        select-rotate t
+    ] if ;
+
+: rebalance-delete ( node -- node shorter? )
+    dup balance>> {
+        { [ dup zero? ] [ drop t ] }
+        { [ dup abs 2 = ] [ sgn neg [ delete-select-rotate ] with-side ] }
+        { [ drop t ] [ f ] } ! balance is -1 or 1, tree is not shorter
+    } cond ;
+
+: balance-delete ( node -- node shorter? )
+    current-side get over balance>> {
+        { [ dup zero? ] [ drop neg over (>>balance) f ] }
+        { [ dupd = ] [ drop 0 >>balance t ] }
+        [ dupd neg increase-balance rebalance-delete ]
+    } cond ;
+
+: avl-replace-with-extremity ( to-replace node -- node shorter? )
+    dup node-link [
+        swapd avl-replace-with-extremity [ over set-node-link ] dip
+        [ balance-delete ] [ f ] if
+    ] [
+        [ copy-node-contents drop ] keep node+link t
+    ] if* ;
+
+: replace-with-a-child ( node -- node shorter? )
+    #! assumes that node is not a leaf, otherwise will recurse forever
+    dup node-link [
+        dupd [ avl-replace-with-extremity ] with-other-side
+        [ over set-node-link ] dip [ balance-delete ] [ f ] if
+    ] [
+        [ replace-with-a-child ] with-other-side
+    ] if* ;
+
+: avl-delete-node ( node -- node shorter? )
+    #! delete this node, returning its replacement, and whether this subtree is
+    #! shorter as a result
+    dup leaf? [
+        drop f t
+    ] [
+        left [ replace-with-a-child ] with-side
+    ] if ;
+
+GENERIC: avl-delete ( key node -- node shorter? deleted? )
+
+M: f avl-delete ( key f -- f f f ) nip f f ;
+
+: (avl-delete) ( key node -- node shorter? deleted? )
+    tuck node-link avl-delete [
+        [ over set-node-link ] dip [ balance-delete ] [ f ] if
+    ] dip ;
+
+M: avl-node avl-delete ( key node -- node shorter? deleted? )
+    2dup key>> key-side dup zero? [
+        drop nip avl-delete-node t
+    ] [
+        [ (avl-delete) ] with-side
+    ] if ;
+
+M: avl delete-at ( key node -- )
+    [ avl-delete 2drop ] change-root drop ;
+
+M: avl new-assoc 2drop <avl> ;
+
+: >avl ( assoc -- avl )
+    T{ avl f f 0 } assoc-clone-like ;
+
+M: avl assoc-like
+    drop dup avl? [ >avl ] unless ;
+
+SYNTAX: AVL{
+    \ } [ >avl ] parse-literal ;
+
+M: avl pprint-delims drop \ AVL{ \ } ;
diff --git a/extra/trees/avl/summary.txt b/extra/trees/avl/summary.txt
new file mode 100644 (file)
index 0000000..c2360c2
--- /dev/null
@@ -0,0 +1 @@
+Balanced AVL trees
diff --git a/extra/trees/avl/tags.txt b/extra/trees/avl/tags.txt
new file mode 100644 (file)
index 0000000..42d711b
--- /dev/null
@@ -0,0 +1 @@
+collections
diff --git a/extra/trees/splay/authors.txt b/extra/trees/splay/authors.txt
new file mode 100644 (file)
index 0000000..06a7cfb
--- /dev/null
@@ -0,0 +1,2 @@
+Mackenzie Straight
+Daniel Ehrenberg
diff --git a/extra/trees/splay/splay-docs.factor b/extra/trees/splay/splay-docs.factor
new file mode 100644 (file)
index 0000000..e1b447c
--- /dev/null
@@ -0,0 +1,27 @@
+USING: help.syntax help.markup assocs ;
+IN: trees.splay 
+
+HELP: SPLAY{
+{ $syntax "SPLAY{ { key value }... }" }
+{ $values { "key" "a key" } { "value" "a value" } }
+{ $description "Literal syntax for an splay tree." } ;
+
+HELP: <splay>
+{ $values { "tree" splay } }
+{ $description "Creates an empty splay tree" } ;
+
+HELP: >splay
+{ $values { "assoc" assoc } { "tree" splay } }
+{ $description "Converts any " { $link assoc } " into an splay tree." } ;
+
+HELP: splay
+{ $class-description "This is the class for splay trees. Splay trees have amortized average-case logarithmic time storage and retrieval operations, and better complexity on more skewed lookup distributions, though in bad situations they can degrade to linear time, resembling a linked list. These conform to the assoc protocol." } ;
+
+ARTICLE: "trees.splay" "Splay trees"
+"This is a library for splay trees. Splay trees have amortized average-case logarithmic time storage and retrieval operations, and better complexity on more skewed lookup distributions, though in bad situations they can degrade to linear time, resembling a linked list. These trees conform to the assoc protocol."
+{ $subsection splay }
+{ $subsection <splay> }
+{ $subsection >splay }
+{ $subsection POSTPONE: SPLAY{ } ;
+
+ABOUT: "trees.splay"
diff --git a/extra/trees/splay/splay-tests.factor b/extra/trees/splay/splay-tests.factor
new file mode 100644 (file)
index 0000000..c07357f
--- /dev/null
@@ -0,0 +1,33 @@
+! Copyright (c) 2005 Mackenzie Straight.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel tools.test trees.splay math namespaces assocs
+sequences random sets make grouping ;
+IN: trees.splay.tests
+
+: randomize-numeric-splay-tree ( splay-tree -- )
+    100 [ drop 100 random swap at drop ] with each ;
+
+: make-numeric-splay-tree ( n -- splay-tree )
+    <splay> [ [ conjoin ] curry each ] keep ;
+
+[ t ] [
+    100 make-numeric-splay-tree dup randomize-numeric-splay-tree
+    [ [ drop , ] assoc-each ] { } make [ < ] monotonic?
+] unit-test
+
+[ 10 ] [ 10 make-numeric-splay-tree keys length ] unit-test
+[ 10 ] [ 10 make-numeric-splay-tree values length ] unit-test
+
+[ f ] [ <splay> f 4 pick set-at 4 swap at ] unit-test
+
+! Ensure that f can be a value
+[ t ] [ <splay> f 4 pick set-at 4 swap key? ] unit-test
+
+[
+{ { 1 "a" } { 2 "b" } { 3 "c" } { 4 "d" } { 5 "e" } { 6 "f" } }
+] [
+{
+    { 4 "d" } { 5 "e" } { 6 "f" }
+    { 1 "a" } { 2 "b" } { 3 "c" }
+} >splay >alist
+] unit-test
diff --git a/extra/trees/splay/splay.factor b/extra/trees/splay/splay.factor
new file mode 100755 (executable)
index 0000000..66ef154
--- /dev/null
@@ -0,0 +1,140 @@
+! Copyright (c) 2005 Mackenzie Straight.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays kernel math namespaces sequences assocs parser
+trees generic math.order accessors prettyprint.custom ;
+IN: trees.splay
+
+TUPLE: splay < tree ;
+
+: <splay> ( -- tree )
+    \ splay new-tree ;
+
+: rotate-right ( node -- node )
+    dup left>>
+    [ right>> swap (>>left) ] 2keep
+    [ (>>right) ] keep ;
+                                                        
+: rotate-left ( node -- node )
+    dup right>>
+    [ left>> swap (>>right) ] 2keep
+    [ (>>left) ] keep ;
+
+: link-right ( left right key node -- left right key node )
+    swap [ [ swap (>>left) ] 2keep
+    nip dup left>> ] dip swap ;
+
+: link-left ( left right key node -- left right key node )
+    swap [ rot [ (>>right) ] 2keep
+    drop dup right>> swapd ] dip swap ;
+
+: cmp ( key node -- obj node -1/0/1 )
+    2dup key>> key-side ;
+
+: lcmp ( key node -- obj node -1/0/1 ) 
+    2dup left>> key>> key-side ;
+
+: rcmp ( key node -- obj node -1/0/1 ) 
+    2dup right>> key>> key-side ;
+
+DEFER: (splay)
+
+: splay-left ( left right key node -- left right key node )
+    dup left>> [
+        lcmp 0 < [ rotate-right ] when
+        dup left>> [ link-right (splay) ] when
+    ] when ;
+
+: splay-right ( left right key node -- left right key node )
+    dup right>> [
+        rcmp 0 > [ rotate-left ] when
+        dup right>> [ link-left (splay) ] when
+    ] when ;
+
+: (splay) ( left right key node -- left right key node )
+    cmp dup 0 <
+    [ drop splay-left ] [ 0 > [ splay-right ] when ] if ;
+
+: assemble ( head left right node -- root )
+    [ right>> swap (>>left) ] keep
+    [ left>> swap (>>right) ] keep
+    [ swap left>> swap (>>right) ] 2keep
+    [ swap right>> swap (>>left) ] keep ;
+
+: splay-at ( key node -- node )
+    [ T{ node } clone dup dup ] 2dip
+    (splay) nip assemble ;
+
+: splay ( key tree -- )
+    [ root>> splay-at ] keep (>>root) ;
+
+: splay-split ( key tree -- node node )
+    2dup splay root>> cmp 0 < [
+        nip dup left>> swap f over (>>left)
+    ] [
+        nip dup right>> swap f over (>>right) swap
+    ] if ;
+
+: get-splay ( key tree -- node ? )
+    2dup splay root>> cmp 0 = [
+        nip t
+    ] [
+        2drop f f
+    ] if ;
+
+: get-largest ( node -- node )
+    dup [ dup right>> [ nip get-largest ] when* ] when ;
+
+: splay-largest ( node -- node )
+    dup [ dup get-largest key>> swap splay-at ] when ;
+
+: splay-join ( n2 n1 -- node )
+    splay-largest [
+        [ (>>right) ] keep
+    ] [
+        drop f
+    ] if* ;
+
+: remove-splay ( key tree -- )
+    tuck get-splay nip [
+        dup dec-count
+        dup right>> swap left>> splay-join
+        swap (>>root)
+    ] [ drop ] if* ;
+
+: set-splay ( value key tree -- )
+    2dup get-splay [ 2nip (>>value) ] [
+       drop dup inc-count
+       2dup splay-split rot
+       [ [ swapd ] dip node boa ] dip (>>root)
+    ] if ;
+
+: new-root ( value key tree -- )
+    1 >>count
+    [ swap <node> ] dip (>>root) ;
+
+M: splay set-at ( value key tree -- )
+    dup root>> [ set-splay ] [ new-root ] if ;
+
+M: splay at* ( key tree -- value ? )
+    dup root>> [
+        get-splay [ dup [ value>> ] when ] dip
+    ] [
+        2drop f f
+    ] if ;
+
+M: splay delete-at ( key tree -- )
+    dup root>> [ remove-splay ] [ 2drop ] if ;
+
+M: splay new-assoc
+    2drop <splay> ;
+
+: >splay ( assoc -- tree )
+    T{ splay f f 0 } assoc-clone-like ;
+
+SYNTAX: SPLAY{
+    \ } [ >splay ] parse-literal ;
+
+M: splay assoc-like
+    drop dup splay? [ >splay ] unless ;
+
+M: splay pprint-delims drop \ SPLAY{ \ } ;
diff --git a/extra/trees/splay/summary.txt b/extra/trees/splay/summary.txt
new file mode 100644 (file)
index 0000000..46391bb
--- /dev/null
@@ -0,0 +1 @@
+Splay trees
diff --git a/extra/trees/splay/tags.txt b/extra/trees/splay/tags.txt
new file mode 100644 (file)
index 0000000..fb6cea7
--- /dev/null
@@ -0,0 +1,2 @@
+collections
+trees
diff --git a/extra/trees/summary.txt b/extra/trees/summary.txt
new file mode 100644 (file)
index 0000000..18ad35d
--- /dev/null
@@ -0,0 +1 @@
+Binary search trees
diff --git a/extra/trees/tags.txt b/extra/trees/tags.txt
new file mode 100644 (file)
index 0000000..fb6cea7
--- /dev/null
@@ -0,0 +1,2 @@
+collections
+trees
diff --git a/extra/trees/trees-docs.factor b/extra/trees/trees-docs.factor
new file mode 100644 (file)
index 0000000..24af961
--- /dev/null
@@ -0,0 +1,27 @@
+USING: help.syntax help.markup assocs ;
+IN: trees
+
+HELP: TREE{
+{ $syntax "TREE{ { key value }... }" }
+{ $values { "key" "a key" } { "value" "a value" } }
+{ $description "Literal syntax for an unbalanced tree." } ;
+
+HELP: <tree>
+{ $values { "tree" tree } }
+{ $description "Creates an empty unbalanced binary tree" } ;
+
+HELP: >tree
+{ $values { "assoc" assoc } { "tree" tree } }
+{ $description "Converts any " { $link assoc } " into an unbalanced binary tree." } ;
+
+HELP: tree
+{ $class-description "This is the class for unbalanced binary search trees. It is not usually intended to be used directly but rather as a basis for other trees." } ;
+
+ARTICLE: "trees" "Binary search trees"
+"This is a library for unbalanced binary search trees. It is not intended to be used directly in most situations but rather as a base class for new trees, because performance can degrade to linear time storage/retrieval by the number of keys. These binary search trees conform to the assoc protocol."
+{ $subsection tree }
+{ $subsection <tree> }
+{ $subsection >tree }
+{ $subsection POSTPONE: TREE{ } ;
+
+ABOUT: "trees"
diff --git a/extra/trees/trees-tests.factor b/extra/trees/trees-tests.factor
new file mode 100644 (file)
index 0000000..99d3734
--- /dev/null
@@ -0,0 +1,27 @@
+USING: trees assocs tools.test kernel sequences ;
+IN: trees.tests
+
+: test-tree ( -- tree )
+    TREE{
+        { 7 "seven" }
+        { 9 "nine" }
+        { 4 "four" } 
+        { 4 "replaced four" } 
+        { 7 "replaced seven" }
+    } clone ;
+
+! test set-at, at, at*
+[ "seven" ] [ <tree> "seven" 7 pick set-at 7 swap at ] unit-test
+[ "seven" t ] [ <tree> "seven" 7 pick set-at 7 swap at* ] unit-test
+[ f f ] [ <tree> "seven" 7 pick set-at 8 swap at* ] unit-test
+[ "seven" ] [ <tree> "seven" 7 pick set-at 7 swap at ] unit-test
+[ "replacement" ] [ <tree> "seven" 7 pick set-at "replacement" 7 pick set-at 7 swap at ] unit-test
+[ "replaced four" ] [ test-tree 4 swap at ] unit-test
+[ "nine" ] [ test-tree 9 swap at ] unit-test
+
+! test delete-at
+[ f ] [ test-tree 9 over delete-at 9 swap at ] unit-test
+[ "replaced seven" ] [ test-tree 9 over delete-at 7 swap at ] unit-test
+[ "replaced four" ] [ test-tree 9 over delete-at 4 swap at ] unit-test
+[ "nine" "replaced four" ] [ test-tree 7 over delete-at 9 over at 4 rot at ] unit-test
+[ "nine" ] [ test-tree 7 over delete-at 4 over delete-at 9 swap at ] unit-test
diff --git a/extra/trees/trees.factor b/extra/trees/trees.factor
new file mode 100755 (executable)
index 0000000..4efea6a
--- /dev/null
@@ -0,0 +1,207 @@
+! Copyright (C) 2007 Alex Chapman
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel generic math sequences arrays io namespaces
+prettyprint.private kernel.private assocs random combinators
+parser math.order accessors deques make prettyprint.custom ;
+IN: trees
+
+TUPLE: tree root count ;
+
+: new-tree ( class -- tree )
+    new
+        f >>root
+        0 >>count ; inline
+
+: <tree> ( -- tree )
+    tree new-tree ;
+
+INSTANCE: tree assoc
+
+TUPLE: node key value left right ;
+
+: new-node ( key value class -- node )
+    new
+        swap >>value
+        swap >>key ;
+
+: <node> ( key value -- node )
+    node new-node ;
+
+SYMBOL: current-side
+
+CONSTANT: left -1
+CONSTANT: right 1
+
+: key-side ( k1 k2 -- n )
+    <=> {
+        { +lt+ [ -1 ] }
+        { +eq+ [ 0 ] }
+        { +gt+ [ 1 ] }
+    } case ;
+
+: go-left? ( -- ? ) current-side get left eq? ;
+
+: inc-count ( tree -- ) [ 1+ ] change-count drop ;
+
+: dec-count ( tree -- ) [ 1- ] change-count drop ;
+
+: node-link@ ( node ? -- node )
+    go-left? xor [ left>> ] [ right>> ] if ;
+
+: set-node-link@ ( left parent ? -- ) 
+    go-left? xor [ (>>left) ] [ (>>right) ] if ;
+
+: node-link ( node -- child ) f node-link@  ;
+
+: set-node-link ( child node -- ) f set-node-link@ ;
+
+: node+link ( node -- child ) t node-link@ ;
+
+: set-node+link ( child node -- ) t set-node-link@ ;
+
+: with-side ( side quot -- )
+    [ swap current-side set call ] with-scope ; inline
+
+: with-other-side ( quot -- )
+    current-side get neg swap with-side ; inline
+
+: go-left ( quot -- ) left swap with-side ; inline
+
+: go-right ( quot -- ) right swap with-side ; inline
+
+: leaf? ( node -- ? )
+    [ left>> ] [ right>> ] bi or not ;
+
+: random-side ( -- side )
+    left right 2array random ;
+
+: choose-branch ( key node -- key node-left/right )
+    2dup key>> key-side [ node-link ] with-side ;
+
+: node-at* ( key node -- value ? )
+    [
+        2dup key>> = [
+            nip value>> t
+        ] [
+            choose-branch node-at*
+        ] if
+    ] [ drop f f ] if* ;
+
+M: tree at* ( key tree -- value ? )
+    root>> node-at* ;
+
+: node-set ( value key node -- node )
+    2dup key>> key-side dup 0 eq? [
+        drop nip swap >>value
+    ] [
+        [
+            [ node-link [ node-set ] [ swap <node> ] if* ] keep
+            [ set-node-link ] keep
+        ] with-side
+    ] if ;
+
+M: tree set-at ( value key tree -- )
+    [ [ node-set ] [ swap <node> ] if* ] change-root drop ;
+
+: valid-node? ( node -- ? )
+    [
+        dup dup left>> [ key>> swap key>> before? ] when*
+        [
+        dup dup right>> [ key>> swap key>> after? ] when* ] dip and swap
+        dup left>> valid-node? swap right>> valid-node? and and
+    ] [ t ] if* ;
+
+: valid-tree? ( tree -- ? ) root>> valid-node? ;
+
+: (node>alist) ( node -- )
+    [
+        [ left>> (node>alist) ]
+        [ [ key>> ] [ value>> ] bi 2array , ]
+        [ right>> (node>alist) ]
+        tri
+    ] when* ;
+
+M: tree >alist [ root>> (node>alist) ] { } make ;
+
+M: tree clear-assoc
+    0 >>count
+    f >>root drop ;
+
+: copy-node-contents ( new old -- new )
+    [ key>> >>key ]
+    [ value>> >>value ] bi ;
+
+! Deletion
+DEFER: delete-node
+
+: (prune-extremity) ( parent node -- new-extremity )
+    dup node-link [
+        rot drop (prune-extremity)
+    ] [
+        tuck delete-node swap set-node-link
+    ] if* ;
+
+: prune-extremity ( node -- new-extremity )
+    #! remove and return the leftmost or rightmost child of this node.
+    #! assumes at least one child
+    dup node-link (prune-extremity) ;
+
+: replace-with-child ( node -- node )
+    dup node-link copy-node-contents dup node-link delete-node over set-node-link ;
+
+: replace-with-extremity ( node -- node )
+    dup node-link dup node+link [
+        ! predecessor/successor is not the immediate child
+        [ prune-extremity ] with-other-side copy-node-contents
+    ] [
+        ! node-link is the predecessor/successor
+        drop replace-with-child
+    ] if ;
+
+: delete-node-with-two-children ( node -- node )
+    #! randomised to minimise tree unbalancing
+    random-side [ replace-with-extremity ] with-side ;
+
+: delete-node ( node -- node )
+    #! delete this node, returning its replacement
+    dup left>> [
+        dup right>> [
+            delete-node-with-two-children
+        ] [
+            left>> ! left but no right
+        ] if
+    ] [
+        dup right>> [
+            right>> ! right but not left
+        ] [
+            drop f ! no children
+        ] if
+    ] if ;
+
+: delete-bst-node ( key node -- node )
+    2dup key>> key-side dup 0 eq? [
+        drop nip delete-node
+    ] [
+        [ tuck node-link delete-bst-node over set-node-link ] with-side
+    ] if ;
+
+M: tree delete-at
+    [ delete-bst-node ] change-root drop ;
+
+M: tree new-assoc
+    2drop <tree> ;
+
+M: tree clone dup assoc-clone-like ;
+
+: >tree ( assoc -- tree )
+    T{ tree f f 0 } assoc-clone-like ;
+
+M: tree assoc-like drop dup tree? [ >tree ] unless ;
+
+SYNTAX: TREE{
+    \ } [ >tree ] parse-literal ;
+                                                        
+M: tree assoc-size count>> ;
+M: tree pprint-delims drop \ TREE{ \ } ;
+M: tree >pprint-sequence >alist ;
+M: tree pprint-narrow? drop t ;
diff --git a/extra/ui/gadgets/alerts/alerts.factor b/extra/ui/gadgets/alerts/alerts.factor
new file mode 100644 (file)
index 0000000..04c6b01
--- /dev/null
@@ -0,0 +1,4 @@
+USING: accessors ui ui.gadgets ui.gadgets.labels ui.gadgets.buttons ui.gadgets.packs locals sequences io.styles ;
+IN: ui.gadgets.alerts
+:: alert ( quot string -- ) <pile> { 10 10 } >>gap 1 >>align string <label> { "sans-serif" plain 18 } >>font { 200 100 } >>pref-dim add-gadget 
+   "okay" [ close-window ] quot append <border-button> add-gadget "" open-window ;
\ No newline at end of file
diff --git a/extra/ui/gadgets/book-extras/book-extras.factor b/extra/ui/gadgets/book-extras/book-extras.factor
new file mode 100644 (file)
index 0000000..b9d8599
--- /dev/null
@@ -0,0 +1,11 @@
+USING: accessors kernel fry math models ui.gadgets ui.gadgets.books ui.gadgets.buttons ;
+IN: ui.gadgets.book-extras
+: <book*> ( pages -- book ) 0 <model> <book> ;
+: |<< ( book -- ) 0 swap set-control-value ;
+: next ( book -- ) model>> [ 1 + ] change-model ;
+: prev ( book -- ) model>> [ 1 - ] change-model ;
+: (book-t) ( quot -- quot ) '[ : owner ( gadget -- book ) parent>> dup book? [ owner ] unless ; owner @ ] ;
+: <book-btn> ( label quot -- button ) (book-t) <button> ;
+: <book-bevel-btn> ( label quot -- button ) (book-t) <border-button> ;
+: >>> ( label -- button ) [ next ] <book-btn> ;
+: <<< ( label -- button ) [ prev ] <book-btn> ;
\ No newline at end of file
index 982aabe2e8c6f9217d7dfc4fe7603d66de01bfdd..aa98793c70ef6a2642e2288df9c6ae5b2877a409 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors math.vectors classes.tuple math.rectangles colors
-kernel sequences models opengl math math.order namespaces call
+kernel sequences models opengl math math.order namespaces
 ui.commands ui.gestures ui.render ui.gadgets ui.gadgets.labels
 ui.gadgets.scrollers ui.gadgets.presentations ui.gadgets.viewports
 ui.gadgets.packs ;
@@ -57,9 +57,7 @@ M: list draw-gadget*
     origin get [
         dup color>> gl-color
         selected-rect [
-            dup loc>> [
-                dim>> gl-fill-rect
-            ] with-translation
+            rect-bounds gl-fill-rect
         ] when*
     ] with-translation ;
 
index 4123a836750a8a32d1a8daa49c05c937299296b8..b9d68ffaeb48eaa9336c92003c6678de00e259f7 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: help.markup help.syntax kernel quotations ui.gadgets
-images.bitmap strings ui.gadgets.worlds ;
+images strings ui.gadgets.worlds ;
 IN: ui.offscreen
 
 HELP: <offscreen-world>
@@ -26,9 +26,9 @@ HELP: do-offscreen
 HELP: gadget>bitmap
 { $values
      { "gadget" gadget }
-     { "bitmap" bitmap }
+     { "image" image }
 }
-{ $description "Renders " { $snippet "gadget" } " to an " { $link offscreen-world } " and creates a " { $link bitmap } " from its contents." } ;
+{ $description "Renders " { $snippet "gadget" } " to an " { $link offscreen-world } " and creates an " { $link image } " from its contents." } ;
 
 HELP: offscreen-world
 { $class-description "The class of " { $link world } " objects that render to an offscreen buffer." } ;
@@ -36,9 +36,9 @@ HELP: offscreen-world
 HELP: offscreen-world>bitmap
 { $values
      { "world" offscreen-world }
-     { "bitmap" bitmap }
+     { "image" image }
 }
-{ $description "Saves a copy of the contents of " { $snippet "world" } " to a " { $link bitmap } " object." } ;
+{ $description "Saves a copy of the contents of " { $snippet "world" } " to a " { $link image } " object." } ;
 
 HELP: open-offscreen
 { $values
index cf9370ed7fa6b050fe9e373bf33124743f165445..8d197eb844e7eba490fdfbb93a862ffc4fb4c4ec 100755 (executable)
@@ -1,7 +1,7 @@
 ! (c) 2008 Joe Groff, see license for details
-USING: accessors continuations images.bitmap kernel math
-sequences ui.gadgets ui.gadgets.worlds ui ui.backend
-destructors ;
+USING: accessors alien.c-types continuations images kernel math
+sequences ui.gadgets ui.gadgets.private ui.gadgets.worlds
+ui.private ui ui.backend destructors locals ;
 IN: ui.offscreen
 
 TUPLE: offscreen-world < world ;
@@ -19,18 +19,24 @@ M: offscreen-world ungraft*
 
 : open-offscreen ( gadget -- world )
     "" f <offscreen-world>
-    [ open-world-window dup relayout-1 ] keep
+    [ open-world-window ] [ relayout-1 ] [ ] tri
     notify-queued ;
 
 : close-offscreen ( world -- )
     ungraft notify-queued ;
 
-: offscreen-world>bitmap ( world -- bitmap )
-    offscreen-pixels bgra>bitmap ;
+:: bgrx>bitmap ( alien w h -- image )
+    <image>
+        { w h } >>dim
+        alien w h * 4 * memory>byte-array >>bitmap
+        BGRX >>component-order ;
+
+: offscreen-world>bitmap ( world -- image )
+    offscreen-pixels bgrx>bitmap ;
 
 : do-offscreen ( gadget quot: ( offscreen-world -- ) -- )
     [ open-offscreen ] dip
     over [ slip ] [ close-offscreen ] [ ] cleanup ; inline
 
-: gadget>bitmap ( gadget -- bitmap )
+: gadget>bitmap ( gadget -- image )
     [ offscreen-world>bitmap ] do-offscreen ;
index b796ebde9124cd1beac6a69bd42032703dbafcb2..46f6dcd8de25f6a27fec35e7dee247082d16f364 100644 (file)
@@ -1,3 +1,2 @@
-unportable
 ui
 graphics
index 3ba20c404340ea581d6be7d0dd0c81ef97940cec..807d8760c72473c5c298b9498902290c02dede9e 100644 (file)
Binary files a/extra/ui/render/test/reference.bmp and b/extra/ui/render/test/reference.bmp differ
index 1aa892557f92cad6227c8c7a7f1465a01cc3fb0e..ca7c60e4d68f548b95f387aeed613e4412f4a9d9 100755 (executable)
@@ -26,21 +26,14 @@ SYMBOL: render-output
     #! On Windows, white is { 253 253 253 } ?
     [ 10 /i ] map ;
 
-: stride ( bitmap -- n ) width>> 3 * ;
-
 : bitmap= ( bitmap1 bitmap2 -- ? )
-    [
-        dup [ [ height>> ] [ stride ] bi * ] [ array>> length ] bi = [
-            [ [ array>> ] [ stride 4 align ] bi group ] [ stride ] bi
-            '[ _ head twiddle ] map
-        ] unless
-    ] bi@ = ;
+    [ bitmap>> twiddle ] bi@ = ;
 
 : check-rendering ( gadget -- )
     screenshot
     [ render-output set-global ]
     [
-        "resource:extra/ui/render/test/reference.bmp" load-image
+        "vocab:ui/render/test/reference.bmp" load-image
         bitmap= "is perfect" "needs work" ?
         "Your UI rendering " prepend
         message-window
@@ -74,12 +67,6 @@ M: take-screenshot draw-boundary
         3array <grid>
             { 5 5 } >>gap
             COLOR: blue <grid-lines> >>boundary
-        add-gadget
-        <gadget>
-            { 14 14 } >>dim
-            COLOR: black <checkmark-paint> >>interior
-            COLOR: black <solid> >>boundary
-        { 4 4 } <border>
         add-gadget ;
     
 : ui-render-test ( -- )
diff --git a/extra/ui/utils/utils.factor b/extra/ui/utils/utils.factor
new file mode 100644 (file)
index 0000000..0880139
--- /dev/null
@@ -0,0 +1,6 @@
+USING: accessors sequences namespaces ui.render opengl fry kernel ;
+IN: ui.utils
+SYMBOLS: width height ;
+: store-dim ( gadget -- ) dim>> [ first width set ] [ second height set ] bi ;
+: with-dim ( gadget quot -- ) '[ _ store-dim @ ] with-scope ; inline
+: with-w/h ( gadget quot -- ) '[ origin get _ with-translation ] with-dim ; inline
\ No newline at end of file
index 9b450ed18bd7f1d4750f4b0feb36beda9f4f0838..96497b8bbc5c0cc8c2a992f3bc7af8a5c78ff2f7 100755 (executable)
@@ -15,7 +15,7 @@ IN: units.tests
 [ t ] [ 1 m 2 m 3 m 3array d-product 6 m^3 = ] unit-test
 [ t ] [ 3 m d-recip 1/3 { } { m } <dimensioned> = ] unit-test
 
-: km/L km 1 L d/ ;
-: mpg miles 1 gallons d/ ;
+: km/L ( n -- d ) km 1 L d/ ;
+: mpg ( n -- d ) miles 1 gallons d/ ;
 
 [ t ] [ 100 10 / km/L [ mpg ] undo 23 1 ~ ] unit-test
index c12367ba5ea35a82952aea6e68f9e3173d5c25b7..21c9b303f304946512cc5c85b8f6e342631667b1 100644 (file)
@@ -21,11 +21,11 @@ IN: vars
     [ define-var-getter ]
     [ define-var-setter ] tri ;
 
-: VAR: ! var
-    scan define-var ; parsing
+SYNTAX: VAR: ! var
+    scan define-var ;
 
 : define-vars ( seq -- )
     [ define-var ] each ;
 
-: VARS: ! vars ...
-    ";" parse-tokens define-vars ; parsing
+SYNTAX: VARS: ! vars ...
+    ";" parse-tokens define-vars ;
index 5d7620101fea1b0eda49af5178c5f07d2066160b..1e5c9602b98b500757213f519dafff050910b108 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: slides help.markup math arrays hashtables namespaces
 sequences kernel sequences parser memoize io.encodings.binary
-locals kernel.private tools.vocabs.browser assocs quotations
+locals kernel.private help.vocabs assocs quotations
 urls peg.ebnf tools.vocabs tools.annotations tools.crossref
 help.topics math.functions compiler.tree.optimizer
 compiler.cfg.optimizer fry ;
index bd9843bdc94aa766f191f92a045ccb59f2abd0b6..4012f2ae1c88d49cbc5512819beb17c1dad8585f 100644 (file)
@@ -7,15 +7,15 @@ IN: webapps.irc-log
 
 TUPLE: irclog-app < dispatcher ;
 
-: irc-link ( -- string )   
+: irc-link ( channel -- string )   
     gmt -7 hours convert-timezone >date<
     [ unparse 2 tail ] 2dip
-    "http://bespin.org/~nef/logs/concatenative/%02s.%02d.%02d"
+    "http://bespin.org/~nef/logs/%s/%02s.%02d.%02d"
     sprintf ;
     
 : <display-irclog-action> ( -- action )
     <action>
-        [ irc-link <redirect> ] >>display ;
+        [ "concatenative" irc-link <redirect> ] >>display ;
 
 : <irclog-app> ( -- dispatcher )
     irclog-app new-dispatcher
index 38a30979993818d006bc92b0c61509a19eb818f0..6a52d02009df3b1b562b44d3dccfda232370f63e 100644 (file)
@@ -83,8 +83,7 @@ annotation "ANNOTATIONS"
 ! LINKS, ETC
 ! ! !
 
-: pastebin-url ( -- url )
-    URL" $pastebin/list" ;
+CONSTANT: pastebin-url URL" $pastebin/"
 
 : paste-url ( id -- url )
     "$pastebin/paste" >url swap "id" set-query-param ;
@@ -187,7 +186,7 @@ M: annotation entity-url
                 "id" value <paste> delete-tuples
                 "id" value f <annotation> delete-tuples
             ] with-transaction
-            URL" $pastebin/list" <redirect>
+            pastebin-url <redirect>
         ] >>submit
 
         <protected>
diff --git a/extra/webapps/site-watcher/authors.txt b/extra/webapps/site-watcher/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/webapps/site-watcher/common/authors.txt b/extra/webapps/site-watcher/common/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/webapps/site-watcher/common/common.factor b/extra/webapps/site-watcher/common/common.factor
new file mode 100644 (file)
index 0000000..b27cbf3
--- /dev/null
@@ -0,0 +1,6 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: http.server.dispatchers ;
+IN: webapps.site-watcher.common
+
+TUPLE: site-watcher-app < dispatcher ;
diff --git a/extra/webapps/site-watcher/common/main.xml b/extra/webapps/site-watcher/common/main.xml
new file mode 100644 (file)
index 0000000..35a0ccb
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+<p>SiteWatcher is a free service for web masters. It periodically tries fetching your web site via HTTP, and sends you an e-mail, SMS or Tweet if this fails. <t:a t:href="$site-watcher-app/login">Sign up now!</t:a></p>
+
+<ul>
+  <li><t:a t:href="$site-watcher-app/update-notify">Your contact info</t:a></li>
+  <li><t:a t:href="$site-watcher-app/watch-list">Watched sites</t:a></li>
+  <li><t:a t:href="$site-watcher-app/spider-list">Spidered sites</t:a></li>
+</ul>
+
+</t:chloe>
diff --git a/extra/webapps/site-watcher/common/site-list.xml b/extra/webapps/site-watcher/common/site-list.xml
new file mode 100644 (file)
index 0000000..765381a
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+<h1>Add some sites to watch</h1>
+
+<t:form t:action="$site-watcher-app/add-watch">
+<table>
+  <tr><th>URL:</th><td> <t:field t:name="url" t:size="80" /> <button type="submit">Done</button> </td></tr>
+</table>
+</t:form>
+
+<h1>Keep track of your sites</h1>
+
+<table border="2">
+  <tr> <th>URL</th><th></th> </tr>
+  <t:bind-each t:name="sites">
+    <tr>
+      <td> <t:label t:name="url" /> </td>
+      <td> <t:button t:action="$site-watcher-app/remove-watch" t:for="url">Remove</t:button> </td>
+    </tr>
+  </t:bind-each>
+</table>
+<p>
+  <t:button t:action="$site-watcher-app/check">Check now</t:button>
+</p>
+
+</t:chloe>
diff --git a/extra/webapps/site-watcher/common/site-watcher.xml b/extra/webapps/site-watcher/common/site-watcher.xml
new file mode 100644 (file)
index 0000000..5b2b129
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+<html>
+  <head>
+    <title>SiteWatcher</title>
+  </head>
+  <body>
+    <h1>SiteWatcher</h1>
+    <h2>It tells you if your web site goes down.</h2>
+    <t:call-next-template />
+  </body>
+</html>
+
+</t:chloe>
diff --git a/extra/webapps/site-watcher/common/spider-list.xml b/extra/webapps/site-watcher/common/spider-list.xml
new file mode 100644 (file)
index 0000000..89d191a
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+<h1>Add a site to spider</h1>
+
+<t:form t:action="$site-watcher-app/add-spider">
+<table>
+  <tr><th>URL:</th><td> <t:field t:name="url" t:size="80" /> <button type="submit">Done</button> </td></tr>
+</table>
+</t:form>
+
+<h1>Spidered sites</h1>
+
+<table border="2">
+  <tr> <th>URL</th><th></th> </tr>
+  <t:bind-each t:name="sites">
+    <tr>
+      <td> <t:label t:name="url" /> </td>
+      <td> <t:button t:action="$site-watcher-app/remove-spider" t:for="url">Remove</t:button> </td>
+    </tr>
+  </t:bind-each>
+</table>
+<p>
+  <t:button t:action="$site-watcher-app/spider">Spider now</t:button>
+</p>
+
+</t:chloe>
diff --git a/extra/webapps/site-watcher/common/update-notify.xml b/extra/webapps/site-watcher/common/update-notify.xml
new file mode 100644 (file)
index 0000000..02075de
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+<h3>Enter your contact details</h3>
+
+<t:form t:action="$site-watcher-app/update-notify">
+<table>
+  <tr><th>E-mail:</th><td><t:field t:name="email" t:size="80" /></td></tr>
+  <tr><th>Twitter:</th><td><t:field t:name="twitter" t:size="80" /></td></tr>
+  <tr><th>SMS:</th><td><t:field t:name="sms" t:size="80" /></td></tr>
+</table>
+<p> <button type="submit">Done</button> </p>
+</t:form>
+
+</t:chloe>
diff --git a/extra/webapps/site-watcher/site-watcher.factor b/extra/webapps/site-watcher/site-watcher.factor
new file mode 100644 (file)
index 0000000..edd8104
--- /dev/null
@@ -0,0 +1,93 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors assocs db.sqlite furnace furnace.actions furnace.alloy
+furnace.auth furnace.auth.features.deactivate-user
+furnace.auth.features.edit-profile
+furnace.auth.features.recover-password
+furnace.auth.features.registration furnace.auth.login
+furnace.boilerplate furnace.redirection html.forms http.server
+http.server.dispatchers kernel namespaces site-watcher site-watcher.db
+site-watcher.private urls validators io.sockets.secure.unix.debug
+io.servers.connection db db.tuples sequences webapps.site-watcher.common
+webapps.site-watcher.watching webapps.site-watcher.spidering ;
+QUALIFIED: assocs
+IN: webapps.site-watcher
+
+: <main-action> ( -- action )
+    <page-action>
+        { site-watcher-app "main" } >>template ;
+
+: <update-notify-action> ( -- action )
+    <page-action>
+        [
+            username f <account> select-tuple from-object
+        ] >>init
+        { site-watcher-app "update-notify" } >>template
+        [
+            {
+                { "email" [ [ v-email ] v-optional ] }
+                { "twitter" [ [ v-one-word ] v-optional ] }
+                { "sms" [ [ v-one-line ] v-optional ] }
+            } validate-params
+        ] >>validate
+        [
+            username f <account> select-tuple
+            "email" value >>email
+            "twitter" value >>twitter
+            "sms" value >>sms
+            update-tuple
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "update notification details" >>description ;
+
+: <site-watcher-app> ( -- dispatcher )
+    site-watcher-app new-dispatcher
+        <main-action> "" add-responder
+        <watch-list-action> "watch-list" add-responder
+        <add-watched-site-action> "add-watch" add-responder
+        <remove-watched-site-action> "remove-watch" add-responder
+        <check-sites-action> "check" add-responder
+        <spider-list-action> "spider-list" add-responder
+        <add-spidered-site-action> "add-spider" add-responder
+        <remove-spidered-site-action> "remove-spider" add-responder
+        <spider-sites-action> "spider" add-responder
+        <update-notify-action> "update-notify" add-responder ;
+
+: <login-config> ( responder -- responder' )
+    "SiteWatcher" <login-realm>
+        "SiteWatcher" >>name
+        allow-registration
+        allow-password-recovery
+        allow-edit-profile
+        allow-deactivation ;
+
+: <site-watcher-server> ( -- threaded-server )
+    <http-server>
+        <test-secure-config> >>secure-config
+        8081 >>insecure
+        8431 >>secure ;
+
+: site-watcher-db ( -- db )
+    "test.db" temp-file <sqlite-db> ;
+
+<site-watcher-app>
+<login-config>
+<boilerplate> { site-watcher-app "site-watcher" } >>template
+site-watcher-db <alloy>
+main-responder set-global
+
+M: site-watcher-app init-user-profile
+    drop B
+    "username" value "email" value <account> insert-tuple ;
+
+: init-db ( -- )
+    site-watcher-db [
+        { site account watching-site spidering-site }
+        [ ensure-table ] each
+    ] with-db ;
+
+: start-site-watcher ( -- )
+    init-db
+    site-watcher-db run-site-watcher
+    <site-watcher-server> start-server ;
diff --git a/extra/webapps/site-watcher/spidering/authors.txt b/extra/webapps/site-watcher/spidering/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/webapps/site-watcher/spidering/spidering.factor b/extra/webapps/site-watcher/spidering/spidering.factor
new file mode 100644 (file)
index 0000000..d0116a7
--- /dev/null
@@ -0,0 +1,52 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors furnace.actions furnace.auth
+furnace.redirection html.forms validators webapps.site-watcher.common
+site-watcher.db site-watcher.spider kernel urls sequences ;
+IN: webapps.site-watcher.spidering
+
+CONSTANT: site-list-url URL" $site-watcher-app/spider-list"
+
+: <spider-list-action> ( -- action )
+    <page-action>
+        { site-watcher-app "spider-list" } >>template
+        [
+            ! Silly query
+            username B spidering-sites [ site>> ] map
+            "sites" set-value
+        ] >>init
+    <protected>
+        "list spidered sites" >>description ;
+
+: <add-spidered-site-action> ( -- action )
+    <action>
+        [
+            { { "url" [ v-url ] } } validate-params
+        ] >>validate
+        [
+            username "url" value add-spidered-site
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "add a spidered site" >>description ;
+
+: <remove-spidered-site-action> ( -- action )
+    <action>
+        [
+            { { "url" [ v-url ] } } validate-params
+        ] >>validate
+        [
+            username "url" value remove-spidered-site
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "remove a spidered site" >>description ;
+
+: <spider-sites-action> ( -- action )
+    <action>
+        [
+            spider-sites
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "spider sites" >>description ;
\ No newline at end of file
diff --git a/extra/webapps/site-watcher/watching/authors.txt b/extra/webapps/site-watcher/watching/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/extra/webapps/site-watcher/watching/watching.factor b/extra/webapps/site-watcher/watching/watching.factor
new file mode 100644 (file)
index 0000000..414595a
--- /dev/null
@@ -0,0 +1,52 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors furnace.actions furnace.auth
+furnace.redirection html.forms site-watcher site-watcher.db
+validators webapps.site-watcher.common urls ;
+IN: webapps.site-watcher.watching
+
+CONSTANT: site-list-url URL" $site-watcher-app/watch-list"
+
+: <watch-list-action> ( -- action )
+    <page-action>
+        { site-watcher-app "site-list" } >>template
+        [
+            ! Silly query
+            username watching-sites
+            "sites" set-value
+        ] >>init
+    <protected>
+        "list watched sites" >>description ;
+
+: <add-watched-site-action> ( -- action )
+    <action>
+        [
+            { { "url" [ v-url ] } } validate-params
+        ] >>validate
+        [
+            username "url" value watch-site
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "add a watched site" >>description ;
+
+: <remove-watched-site-action> ( -- action )
+    <action>
+        [
+            { { "url" [ v-url ] } } validate-params
+        ] >>validate
+        [
+            username "url" value unwatch-site
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "remove a watched site" >>description ;
+
+: <check-sites-action> ( -- action )
+    <action>
+        [
+            watch-sites
+            site-list-url <redirect>
+        ] >>submit
+    <protected>
+        "check watched sites" >>description ;
\ No newline at end of file
index e3774bbe0b063c6250e041a10fa6f262f6a5f56e..38d9d39d558777b8f1e7e7a23222feca7121f7a4 100644 (file)
@@ -5,7 +5,7 @@
        <t:title><t:label t:name="title" /></t:title>
 
        <div class="description">
-               <t:farkup t:name="parsed" t:parsed="true" />
+               <t:farkup t:name="content" />
        </div>
 
        <p>
index bca48ce26037e8204dfe4a7e8cd49212cb823e0f..6bdc449dc8f459758585cb2bf0ce786725a1fb4d 100644 (file)
@@ -20,7 +20,7 @@
                                                                </t:a>
                                                        </h2>
 
-                                                       <t:farkup t:name="parsed" t:parsed="true" />
+                                                       <t:farkup t:name="content" />
                                                </t:bind>
                                        </div>
                                </td>
@@ -58,7 +58,7 @@
                        <tr>
                                <td colspan="2" class="footer">
                                        <t:bind t:name="footer">
-                                               <t:farkup t:name="parsed" t:parsed="true" />
+                                               <t:farkup t:name="content" />
                                        </t:bind>
                                </td>
                        </tr>
index 07fbbe059601e05cfabaa93b75c21781f6ff7262..2341b020a84fdb0e495a0c584b0f0bcb48bc262f 100644 (file)
@@ -47,7 +47,7 @@ article "ARTICLES" {
 
 : <article> ( title -- article ) article new swap >>title ;
 
-TUPLE: revision id title author date content parsed description ;
+TUPLE: revision id title author date content description ;
 
 revision "REVISIONS" {
     { "id" "ID" INTEGER +db-assigned-id+ }
@@ -55,7 +55,6 @@ revision "REVISIONS" {
     { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } ! uid
     { "date" "DATE" TIMESTAMP +not-null+ }
     { "content" "CONTENT" TEXT +not-null+ }
-    { "parsed" "PARSED" FACTOR-BLOB +not-null+ } ! Farkup AST
     { "description" "DESCRIPTION" TEXT }
 } define-persistent
 
@@ -72,9 +71,6 @@ M: revision feed-entry-url id>> revision-url ;
 : <revision> ( id -- revision )
     revision new swap >>id ;
 
-: compute-html ( revision -- )
-    dup content>> parse-farkup >>parsed drop ;
-
 : validate-title ( -- )
     { { "title" [ v-one-line ] } } validate-params ;
 
@@ -141,13 +137,12 @@ M: revision feed-entry-url id>> revision-url ;
     [ title>> ] [ id>> ] bi article boa insert-tuple ;
 
 : add-revision ( revision -- )
-    [ compute-html ]
     [ insert-tuple ]
     [
         dup title>> <article> select-tuple
         [ amend-article ] [ add-article ] if*
     ]
-    tri ;
+    bi ;
 
 : <edit-article-action> ( -- action )
     <page-action>
index 83f06ec1370445843f3f894ddf79b6f4db9a7fae..728764226eb7954b30ee683416c1e378af67a10f 100644 (file)
@@ -1,17 +1,18 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel
 cocoa
 cocoa.application
 cocoa.types
 cocoa.classes
-cocoa.windows ;
+cocoa.windows
+core-graphics.types ;
 IN: webkit-demo
 
 FRAMEWORK: /System/Library/Frameworks/WebKit.framework
 IMPORT: WebView
 
-: rect ( -- rect ) 0 0 700 500 <NSRect> ;
+: rect ( -- rect ) 0 0 700 500 <CGRect> ;
 
 : <WebView> ( -- id )
     WebView -> alloc
index 7abdc149dd8ed71bf5077c4927739e7f457cb830..34cd19c34fc99344f8b86536dfd7a51f4cf2d703 100644 (file)
@@ -1,6 +1,6 @@
 USING: kernel sequences namespaces make math assocs words arrays
 tools.annotations vocabs sorting prettyprint io system
-math.statistics accessors tools.time ;
+math.statistics accessors tools.time fry ;
 IN: wordtimer
 
 SYMBOL: *wordtimes*
@@ -40,7 +40,7 @@ SYMBOL: *calling*
   [ swap time-unless-recursing ] 2curry ; 
 
 : add-timer ( word -- )
-  dup [ (add-timer) ] annotate ;
+  dup '[ [ _ ] dip (add-timer) ] annotate ;
 
 : add-timers ( vocab -- )
   words [ add-timer ] each ;
index f3b510fdd97003f313ae63b983758dbc80836b97..bc1bb900ce450804cc71e273940eceacff2c7cec 100644 (file)
@@ -58,6 +58,7 @@
   (number constant  "integers and floats")
   (ratio constant  "ratios")
   (declaration keyword "declaration words")
+  (ebnf-form constant "EBNF: ... ;EBNF form")
   (parsing-word keyword  "parsing words")
   (setter-word function-name "setter words (>>foo)")
   (getter-word function-name "getter words (foo>>)")
 (defun fuel-font-lock--syntactic-face (state)
   (if (nth 3 state) 'factor-font-lock-string
     (let ((c (char-after (nth 8 state))))
-      (cond ((or (char-equal c ?\ ) (char-equal c ?\n))
+      (cond ((or (char-equal c ?\ )
+                 (char-equal c ?\n)
+                 (char-equal c ?E))
              (save-excursion
                (goto-char (nth 8 state))
                (beginning-of-line)
-               (cond ((looking-at "USING: ")
+               (cond ((looking-at-p "USING: ")
                       'factor-font-lock-vocabulary-name)
-                     ((looking-at "\\(TUPLE\\|SYMBOLS\\|VARS\\): ")
+                     ((looking-at-p "\\(TUPLE\\|SYMBOLS\\|VARS\\|SINGLETONS\\):")
                       'factor-font-lock-symbol)
-                     ((looking-at "C-ENUM:\\( \\|\n\\)")
+                     ((looking-at-p "C-ENUM:\\( \\|\n\\)")
                       'factor-font-lock-constant)
+                     ((looking-at-p "E")
+                      'factor-font-lock-ebnf-form)
                      (t 'default))))
             ((or (char-equal c ?U) (char-equal c ?C))
              'factor-font-lock-parsing-word)
index 942d4394662fc28a0b7c1769a2ceb3f259fd4cc9..a410bb504716432469768fa8c52fad528ce3ed1d 100644 (file)
@@ -36,7 +36,7 @@
       (let ((name (match-string-no-properties 2))
             (body (match-string-no-properties 4))
             (end (match-end 0)))
-        (list (split-string body nil t) name pos end)))))
+        (list (split-string (or body "") nil t) name pos end)))))
 
 (defun fuel-refactor--find (code to)
   (let ((candidate) (result))
@@ -88,7 +88,7 @@
 (defun fuel-refactor--insert-word (word stack-effect code)
   (let ((start (goto-char (fuel-refactor--insertion-point))))
     (open-line 1)
-    (insert ": " word " " stack-effect "\n" code " ;\n")
+    (insert ": " word " " stack-effect "\n" (or code " ") " ;\n")
     (indent-region start (point))
     (move-overlay fuel-stack--overlay start (point))))
 
     (delete-overlay fuel-stack--overlay)))
 
 (defun fuel-refactor--extract (begin end)
-  (unless (< begin end) (error "No proper region to extract"))
-  (let* ((code (buffer-substring begin end))
-         (existing (fuel-refactor--reuse-existing code))
-         (code-str (or existing (fuel--region-to-string begin end)))
+  (let* ((rp (< begin end))
+         (code (and rp (buffer-substring begin end)))
+         (existing (and code (fuel-refactor--reuse-existing code)))
+         (code-str (and code (or existing (fuel--region-to-string begin end))))
          (word (or (car existing) (read-string "New word name: ")))
          (stack-effect (or existing
-                           (fuel-stack--infer-effect code-str)
+                           (and code-str (fuel-stack--infer-effect code-str))
                            (read-string "Stack effect: "))))
-    (goto-char begin)
-    (delete-region begin end)
-    (insert word)
-    (indent-region begin (point))
+    (when rp
+      (goto-char begin)
+      (delete-region begin end)
+      (insert word)
+      (indent-region begin (point)))
     (save-excursion
       (let ((start (or (cadr existing) (point))))
         (unless existing
           (fuel-refactor--insert-word word stack-effect code))
-        (fuel-refactor--extract-other start
-                                      (or (car (cddr existing)) (point))
-                                      code)))))
+        (if rp
+            (fuel-refactor--extract-other start
+                                          (or (car (cddr existing)) (point))
+                                          code)
+          (unwind-protect
+              (sit-for fuel-stack-highlight-period)
+            (delete-overlay fuel-stack--overlay)))))))
 
 (defun fuel-refactor-extract-region (begin end)
   "Extracts current region as a separate word."
   (interactive "r")
-  (let ((begin (save-excursion
-                 (goto-char begin)
-                 (when (zerop (skip-syntax-backward "w"))
-                   (skip-syntax-forward "-"))
-                 (point)))
-        (end (save-excursion
-               (goto-char end)
-               (skip-syntax-forward "w")
-               (point))))
-    (fuel-refactor--extract begin end)))
+  (if (= begin end)
+      (fuel-refactor--extract begin end)
+    (let ((begin (save-excursion
+                   (goto-char begin)
+                   (when (zerop (skip-syntax-backward "w"))
+                     (skip-syntax-forward "-"))
+                   (point)))
+          (end (save-excursion
+                 (goto-char end)
+                 (skip-syntax-forward "w")
+                 (point))))
+      (fuel-refactor--extract begin end))))
 
 (defun fuel-refactor-extract-sexp ()
   "Extracts current innermost sexp (up to point) as a separate
index b6409b2fead9606ed62d91b375f7d832042948a7..7aba6282d6c423211f80a710d5657a2df29c01c4 100644 (file)
@@ -48,7 +48,7 @@
     "B" "BIN:"
     "C:" "C-ENUM:" "C-STRUCT:" "C-UNION:" "CHAR:" "CONSTANT:" "call-next-method"
     "DEFER:"
-    "ERROR:" "EXCLUDE:"
+    "EBNF:" ";EBNF" "ERROR:" "EXCLUDE:"
     "f" "FORGET:" "FROM:" "FUNCTION:"
     "GENERIC#" "GENERIC:"
     "HELP:" "HEX:" "HOOK:"
   "\\_<\"[^>]\\([^\"\n]\\|\\\\\"\\)*\n")
 
 (defconst fuel-syntax--word-definition-regex
-  (fuel-syntax--second-word-regex
-   '(":" "::" "GENERIC:" "DEFER:" "HOOK:" "MAIN:" "MATH:" "POSTPONE:"
-     "SYMBOL:" "RENAME:")))
+  (format "\\_<\\(%s\\)?: +\\_<\\(\\w+\\)\\_>"
+          (regexp-opt
+           '(":" "GENERIC" "DEFER" "HOOK" "MAIN" "MATH" "POSTPONE"
+             "SYMBOL" "RENAME"))))
 
 (defconst fuel-syntax--alias-definition-regex
   "^ALIAS: +\\(\\_<.+?\\_>\\) +\\(\\_<.+?\\_>\\)")
 (defconst fuel-syntax--indent-def-start-regex
   (format "^\\(%s:\\)\\( \\|\n\\)" (regexp-opt fuel-syntax--indent-def-starts)))
 
-(defconst fuel-syntax--no-indent-def-start-regex
-  (format "^\\(%s:\\) " (regexp-opt fuel-syntax--no-indent-def-starts)))
-
 (defconst fuel-syntax--definition-start-regex
   (format "^\\(%s:\\) " (regexp-opt (append fuel-syntax--no-indent-def-starts
                                             fuel-syntax--indent-def-starts))))
     (modify-syntax-entry ?\r " " table)
     (modify-syntax-entry ?\  " " table)
     (modify-syntax-entry ?\n " " table)
-    (modify-syntax-entry ?\( "()" table)
-    (modify-syntax-entry ?\) ")(" table)
     table))
 
 (defconst fuel-syntax--syntactic-keywords
-  `(;; CHARs:
-    ("\\(CHAR:\\|POSTPONE:\\|\\\\\\) \\(.\\)\\( \\|$\\)" (2 "w"))
-    ;; Comments:
+  `(;; Comments
     ("\\_<\\(#?!\\) .*\\(\n\\|$\\)" (1 "<") (2 ">"))
     ("\\_<\\(#?!\\)\\(\n\\|$\\)" (1 "<") (2 ">"))
-    ;; Strings
+    ;; Strings and chars
+    ("CHAR: \\(\"\\) [^\\\"]*?\\(\"\\)\\([^\\\"]\\|\\\\.\\)*?\\(\"\\)"
+     (1 "w") (2 "\"") (4 "\""))
+    ("\\(CHAR:\\|POSTPONE:\\|\\\\\\) \\(.\\)\\( \\|$\\)" (2 "w"))
     ("\\( \\|^\\)\\(DLL\\|P\\|SBUF\\)\\(\"\\)\\([^\n\r\f\\\"]\\|\\\\.\\)*?\\(\"\\)"
      (3 "\"") (5 "\""))
-    ("\\(\"\\)\\([^\n\r\f\\\"]\\|\\\\.\\)*?\\(\"\\)" (1 "\"") (3 "\""))
+    ("\\_<\\(\"\\)\\([^\n\r\f\\\"]\\|\\\\.\\)*?\\(\"\\)" (1 "\"") (3 "\""))
     ("\\_<<\\(\"\\)\\_>" (1 "<b"))
     ("\\_<\\(\"\\)>\\_>" (1 ">b"))
     ;; Multiline constructs
+    ("\\_<\\(E\\)BNF:\\( \\|\n\\)" (1 "<b"))
+    ("\\_<;EBN\\(F\\)\\_>" (1 ">b"))
     ("\\_<\\(U\\)SING: \\(;\\)" (1 "<b") (2 ">b"))
     ("\\_<USING:\\( \\)" (1 "<b"))
     ("\\_<\\(C\\)-ENUM: \\(;\\)" (1 "<b") (2 ">b"))
     ("\\_<C-ENUM:\\( \\|\n\\)" (1 "<b"))
     ("\\_<TUPLE: +\\w+? +< +\\w+? *\\( \\|\n\\)\\([^;]\\|$\\)" (1 "<b"))
-    ("\\_<\\(TUPLE\\|SYMBOLS\\|VARS\\): +\\w+? *\\( \\|\n\\)\\([^;<\n]\\|\\_>\\)"
-     (2 "<b"))
+    ("\\_<TUPLE: +\\w+? *\\( \\|\n\\)\\([^;<\n]\\|\\_>\\)" (1 "<b"))
+    ("\\_<\\(SYMBOLS\\|VARS\\|SINGLETONS\\): *?\\( \\|\n\\)\\([^;\n]\\|\\_>\\)" (2 "<b"))
     ("\\(\n\\| \\);\\_>" (1 ">b"))
     ;; Let and lambda:
     ("\\_<\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))
     ;; Parenthesis:
     ("\\_<\\((\\)\\_>" (1 "()"))
     ("\\_<\\()\\)\\_>" (1 ")("))
+    ("\\_<(\\((\\)\\_>" (1 "()"))
+    ("\\_<\\()\\))\\_>" (1 ")("))
     ;; Quotations:
     ("\\_<'\\(\\[\\)\\_>" (1 "(]"))      ; fried
     ("\\_<\\(\\[\\)\\_>" (1 "(]"))
 (defsubst fuel-syntax--is-last-char (pos)
   (save-excursion
     (goto-char (1+ pos))
-    (fuel-syntax--looking-at-emptiness)))
+    (looking-at-p "[ ]*$")))
 
 (defsubst fuel-syntax--line-offset (pos)
   (- pos (save-excursion
diff --git a/unmaintained/trees/authors.txt b/unmaintained/trees/authors.txt
deleted file mode 100644 (file)
index 39c1f37..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Alex Chapman
-Daniel Ehrenberg
diff --git a/unmaintained/trees/avl/authors.txt b/unmaintained/trees/avl/authors.txt
deleted file mode 100644 (file)
index 39c1f37..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Alex Chapman
-Daniel Ehrenberg
diff --git a/unmaintained/trees/avl/avl-docs.factor b/unmaintained/trees/avl/avl-docs.factor
deleted file mode 100644 (file)
index 46f6474..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-USING: help.syntax help.markup assocs ;
-IN: trees.avl 
-
-HELP: AVL{
-{ $syntax "AVL{ { key value }... }" }
-{ $values { "key" "a key" } { "value" "a value" } }
-{ $description "Literal syntax for an AVL tree." } ;
-
-HELP: <avl>
-{ $values { "tree" avl } }
-{ $description "Creates an empty AVL tree" } ;
-
-HELP: >avl
-{ $values { "assoc" assoc } { "avl" avl } }
-{ $description "Converts any " { $link assoc } " into an AVL tree." } ;
-
-HELP: avl
-{ $class-description "This is the class for AVL trees. These conform to the assoc protocol and have efficient (logarithmic time) storage and retrieval operations." } ;
-
-ARTICLE: { "avl" "intro" } "AVL trees"
-"This is a library for AVL trees, with logarithmic time storage and retrieval operations. These trees conform to the assoc protocol."
-{ $subsection avl }
-{ $subsection <avl> }
-{ $subsection >avl }
-{ $subsection POSTPONE: AVL{ } ;
-
-ABOUT: { "avl" "intro" }
diff --git a/unmaintained/trees/avl/avl-tests.factor b/unmaintained/trees/avl/avl-tests.factor
deleted file mode 100755 (executable)
index 5cb6606..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-USING: kernel tools.test trees trees.avl math random sequences assocs ;
-IN: trees.avl.tests
-
-[ "key1" 0 "key2" 0 ] [
-    T{ avl-node f "key1" f f T{ avl-node f "key2" f f 1 } 2 }
-    [ single-rotate ] go-left
-    [ node-left dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance
-] unit-test
-
-[ "key1" 0 "key2" 0 ] [
-    T{ avl-node f "key1" f f T{ avl-node f "key2" f f f 1 } 2 }
-    [ select-rotate ] go-left
-    [ node-left dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance
-] unit-test
-
-[ "key1" 0 "key2" 0 ] [
-    T{ avl-node f "key1" f T{ avl-node f "key2" f f f -1 } f -2 }
-    [ single-rotate ] go-right
-    [ node-right dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance
-] unit-test
-
-[ "key1" 0 "key2" 0 ] [
-    T{ avl-node f "key1" f T{ avl-node f "key2" f f f -1 } f -2 }
-    [ select-rotate ] go-right
-    [ node-right dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance
-] unit-test
-
-[ "key1" -1 "key2" 0 "key3" 0 ]
-[ T{ avl-node f "key1" f f
-        T{ avl-node f "key2" f 
-            T{ avl-node f "key3" f f f 1 } f -1 } 2 }
-    [ double-rotate ] go-left
-    [ node-left dup node-key swap avl-node-balance ] keep
-    [ node-right dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance ] unit-test
-[ "key1" 0 "key2" 0 "key3" 0 ]
-[ T{ avl-node f "key1" f f
-        T{ avl-node f "key2" f
-            T{ avl-node f "key3" f f f 0 } f -1 } 2 } 
-    [ double-rotate ] go-left
-    [ node-left dup node-key swap avl-node-balance ] keep
-    [ node-right dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance ] unit-test
-[ "key1" 0 "key2" 1 "key3" 0 ]
-[ T{ avl-node f "key1" f f
-        T{ avl-node f "key2" f
-            T{ avl-node f "key3" f f f -1 } f -1 } 2 } 
-    [ double-rotate ] go-left
-    [ node-left dup node-key swap avl-node-balance ] keep
-    [ node-right dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance ] unit-test
-
-[ "key1" 1 "key2" 0 "key3" 0 ]
-[ T{ avl-node f "key1" f
-        T{ avl-node f "key2" f f
-            T{ avl-node f "key3" f f f -1 } 1 } f -2 }
-    [ double-rotate ] go-right
-    [ node-right dup node-key swap avl-node-balance ] keep
-    [ node-left dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance ] unit-test
-[ "key1" 0 "key2" 0 "key3" 0 ]
-[ T{ avl-node f "key1" f
-        T{ avl-node f "key2" f f
-            T{ avl-node f "key3" f f f 0 } 1 } f -2 }
-    [ double-rotate ] go-right
-    [ node-right dup node-key swap avl-node-balance ] keep
-    [ node-left dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance ] unit-test
-[ "key1" 0 "key2" -1 "key3" 0 ]
-[ T{ avl-node f "key1" f
-        T{ avl-node f "key2" f f
-            T{ avl-node f "key3" f f f 1 } 1 } f -2 }
-    [ double-rotate ] go-right
-    [ node-right dup node-key swap avl-node-balance ] keep
-    [ node-left dup node-key swap avl-node-balance ] keep
-    dup node-key swap avl-node-balance ] unit-test
-
-[ "eight" ] [
-    <avl> "seven" 7 pick set-at
-    "eight" 8 pick set-at "nine" 9 pick set-at
-    tree-root node-value
-] unit-test
-
-[ "another eight" ] [ ! ERROR!
-    <avl> "seven" 7 pick set-at
-    "another eight" 8 pick set-at 8 swap at
-] unit-test
-
-: test-tree ( -- tree )
-    AVL{
-        { 7 "seven" }
-        { 9 "nine" }
-        { 4 "four" } 
-        { 4 "replaced four" } 
-        { 7 "replaced seven" }
-    } clone ;
-
-! test set-at, at, at*
-[ t ] [ test-tree avl? ] unit-test
-[ "seven" ] [ <avl> "seven" 7 pick set-at 7 swap at ] unit-test
-[ "seven" t ] [ <avl> "seven" 7 pick set-at 7 swap at* ] unit-test
-[ f f ] [ <avl> "seven" 7 pick set-at 8 swap at* ] unit-test
-[ "seven" ] [ <avl> "seven" 7 pick set-at 7 swap at ] unit-test
-[ "replacement" ] [ <avl> "seven" 7 pick set-at "replacement" 7 pick set-at 7 swap at ] unit-test
-[ "nine" ] [ test-tree 9 swap at ] unit-test
-[ "replaced four" ] [ test-tree 4 swap at ] unit-test
-[ "replaced seven" ] [ test-tree 7 swap at ] unit-test
-
-! test delete-at--all errors!
-[ f ] [ test-tree 9 over delete-at 9 swap at ] unit-test
-[ "replaced seven" ] [ test-tree 9 over delete-at 7 swap at ] unit-test
-[ "nine" ] [ test-tree 7 over delete-at 4 over delete-at 9 swap at ] unit-test
diff --git a/unmaintained/trees/avl/avl.factor b/unmaintained/trees/avl/avl.factor
deleted file mode 100755 (executable)
index 866e035..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-! Copyright (C) 2007 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: combinators kernel generic math math.functions
-math.parser namespaces io prettyprint.backend sequences trees
-assocs parser accessors math.order ;
-IN: trees.avl
-
-TUPLE: avl < tree ;
-
-: <avl> ( -- tree )
-    avl new-tree ;
-
-TUPLE: avl-node < node balance ;
-
-: <avl-node> ( key value -- node )
-    avl-node new-node
-        0 >>balance ;
-
-: increase-balance ( node amount -- )
-    swap [ + ] change-balance drop ;
-
-: rotate ( node -- node )
-    dup node+link dup node-link pick set-node+link
-    tuck set-node-link ;    
-
-: single-rotate ( node -- node )
-    0 over (>>balance) 0 over node+link 
-    (>>balance) rotate ;
-
-: pick-balances ( a node -- balance balance )
-    balance>> {
-        { [ dup zero? ] [ 2drop 0 0 ] }
-        { [ over = ] [ neg 0 ] }
-        [ 0 swap ]
-    } cond ;
-
-: double-rotate ( node -- node )
-    [
-        node+link [
-            node-link current-side get neg
-            over pick-balances rot 0 swap (>>balance)
-        ] keep (>>balance)
-    ] keep swap >>balance
-    dup node+link [ rotate ] with-other-side
-    over set-node+link rotate ;
-
-: select-rotate ( node -- node )
-    dup node+link balance>> current-side get =
-    [ double-rotate ] [ single-rotate ] if ;
-
-: balance-insert ( node -- node taller? )
-    dup avl-node-balance {
-        { [ dup zero? ] [ drop f ] }
-        { [ dup abs 2 = ]
-          [ sgn neg [ select-rotate ] with-side f ] }
-        { [ drop t ] [ t ] } ! balance is -1 or 1, tree is taller
-    } cond ;
-
-DEFER: avl-set
-
-: avl-insert ( value key node -- node taller? )
-    2dup node-key before? left right ? [
-        [ node-link avl-set ] keep swap
-        >r tuck set-node-link r>
-        [ dup current-side get increase-balance balance-insert ]
-        [ f ] if
-    ] with-side ;
-
-: (avl-set) ( value key node -- node taller? )
-    2dup node-key = [
-        -rot pick set-node-key over set-node-value f
-    ] [ avl-insert ] if ;
-
-: avl-set ( value key node -- node taller? )
-    [ (avl-set) ] [ swap <avl-node> t ] if* ;
-
-M: avl set-at ( value key node -- node )
-    [ avl-set drop ] change-root drop ;
-
-: delete-select-rotate ( node -- node shorter? )
-    dup node+link avl-node-balance zero? [
-        current-side get neg over set-avl-node-balance
-        current-side get over node+link set-avl-node-balance rotate f
-    ] [
-        select-rotate t
-    ] if ;
-
-: rebalance-delete ( node -- node shorter? )
-    dup avl-node-balance {
-        { [ dup zero? ] [ drop t ] }
-        { [ dup abs 2 = ] [ sgn neg [ delete-select-rotate ] with-side ] }
-        { [ drop t ] [ f ] } ! balance is -1 or 1, tree is not shorter
-    } cond ;
-
-: balance-delete ( node -- node shorter? )
-    current-side get over balance>> {
-        { [ dup zero? ] [ drop neg over set-avl-node-balance f ] }
-        { [ dupd = ] [ drop 0 >>balance t ] }
-        [ dupd neg increase-balance rebalance-delete ]
-    } cond ;
-
-: avl-replace-with-extremity ( to-replace node -- node shorter? )
-    dup node-link [
-        swapd avl-replace-with-extremity >r over set-node-link r>
-        [ balance-delete ] [ f ] if
-    ] [
-        tuck copy-node-contents node+link t
-    ] if* ;
-
-: replace-with-a-child ( node -- node shorter? )
-    #! assumes that node is not a leaf, otherwise will recurse forever
-    dup node-link [
-        dupd [ avl-replace-with-extremity ] with-other-side
-        >r over set-node-link r> [ balance-delete ] [ f ] if
-    ] [
-        [ replace-with-a-child ] with-other-side
-    ] if* ;
-
-: avl-delete-node ( node -- node shorter? )
-    #! delete this node, returning its replacement, and whether this subtree is
-    #! shorter as a result
-    dup leaf? [
-        drop f t
-    ] [
-        left [ replace-with-a-child ] with-side
-    ] if ;
-
-GENERIC: avl-delete ( key node -- node shorter? deleted? )
-
-M: f avl-delete ( key f -- f f f ) nip f f ;
-
-: (avl-delete) ( key node -- node shorter? deleted? )
-    tuck node-link avl-delete >r >r over set-node-link r>
-    [ balance-delete r> ] [ f r> ] if ;
-
-M: avl-node avl-delete ( key node -- node shorter? deleted? )
-    2dup node-key key-side dup zero? [
-        drop nip avl-delete-node t
-    ] [
-        [ (avl-delete) ] with-side
-    ] if ;
-
-M: avl delete-at ( key node -- )
-    [ avl-delete 2drop ] change-root drop ;
-
-M: avl new-assoc 2drop <avl> ;
-
-: >avl ( assoc -- avl )
-    T{ avl f f 0 } assoc-clone-like ;
-
-M: avl assoc-like
-    drop dup avl? [ >avl ] unless ;
-
-: AVL{
-    \ } [ >avl ] parse-literal ; parsing
-
-M: avl pprint-delims drop \ AVL{ \ } ;
diff --git a/unmaintained/trees/avl/summary.txt b/unmaintained/trees/avl/summary.txt
deleted file mode 100644 (file)
index c2360c2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Balanced AVL trees
diff --git a/unmaintained/trees/avl/tags.txt b/unmaintained/trees/avl/tags.txt
deleted file mode 100644 (file)
index 42d711b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-collections
diff --git a/unmaintained/trees/splay/authors.txt b/unmaintained/trees/splay/authors.txt
deleted file mode 100644 (file)
index 06a7cfb..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Mackenzie Straight
-Daniel Ehrenberg
diff --git a/unmaintained/trees/splay/splay-docs.factor b/unmaintained/trees/splay/splay-docs.factor
deleted file mode 100644 (file)
index 253d3f4..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-USING: help.syntax help.markup assocs ;
-IN: trees.splay 
-
-HELP: SPLAY{
-{ $syntax "SPLAY{ { key value }... }" }
-{ $values { "key" "a key" } { "value" "a value" } }
-{ $description "Literal syntax for an splay tree." } ;
-
-HELP: <splay>
-{ $values { "tree" splay } }
-{ $description "Creates an empty splay tree" } ;
-
-HELP: >splay
-{ $values { "assoc" assoc } { "tree" splay } }
-{ $description "Converts any " { $link assoc } " into an splay tree." } ;
-
-HELP: splay
-{ $class-description "This is the class for splay trees. Splay trees have amortized average-case logarithmic time storage and retrieval operations, and better complexity on more skewed lookup distributions, though in bad situations they can degrade to linear time, resembling a linked list. These conform to the assoc protocol." } ;
-
-ARTICLE: { "splay" "intro" } "Splay trees"
-"This is a library for splay trees. Splay trees have amortized average-case logarithmic time storage and retrieval operations, and better complexity on more skewed lookup distributions, though in bad situations they can degrade to linear time, resembling a linked list. These trees conform to the assoc protocol."
-{ $subsection splay }
-{ $subsection <splay> }
-{ $subsection >splay }
-{ $subsection POSTPONE: SPLAY{ } ;
-
-ABOUT: { "splay" "intro" }
diff --git a/unmaintained/trees/splay/splay-tests.factor b/unmaintained/trees/splay/splay-tests.factor
deleted file mode 100644 (file)
index e54e3cd..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-! Copyright (c) 2005 Mackenzie Straight.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel tools.test trees.splay math namespaces assocs
-sequences random sets ;
-IN: trees.splay.tests
-
-: randomize-numeric-splay-tree ( splay-tree -- )
-    100 [ drop 100 random swap at drop ] with each ;
-
-: make-numeric-splay-tree ( n -- splay-tree )
-    <splay> [ [ conjoin ] curry each ] keep ;
-
-[ t ] [
-    100 make-numeric-splay-tree dup randomize-numeric-splay-tree
-    [ [ drop , ] assoc-each ] { } make [ < ] monotonic?
-] unit-test
-
-[ 10 ] [ 10 make-numeric-splay-tree keys length ] unit-test
-[ 10 ] [ 10 make-numeric-splay-tree values length ] unit-test
-
-[ f ] [ <splay> f 4 pick set-at 4 swap at ] unit-test
-
-! Ensure that f can be a value
-[ t ] [ <splay> f 4 pick set-at 4 swap key? ] unit-test
-
-[
-{ { 1 "a" } { 2 "b" } { 3 "c" } { 4 "d" } { 5 "e" } { 6 "f" } }
-] [
-{
-    { 4 "d" } { 5 "e" } { 6 "f" }
-    { 1 "a" } { 2 "b" } { 3 "c" }
-} >splay >alist
-] unit-test
diff --git a/unmaintained/trees/splay/splay.factor b/unmaintained/trees/splay/splay.factor
deleted file mode 100755 (executable)
index 923df4b..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-! Copyright (c) 2005 Mackenzie Straight.
-! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math namespaces sequences assocs parser
-prettyprint.backend trees generic math.order ;
-IN: trees.splay
-
-TUPLE: splay < tree ;
-
-: <splay> ( -- tree )
-    \ splay new-tree ;
-
-: rotate-right ( node -- node )
-    dup node-left
-    [ node-right swap set-node-left ] 2keep
-    [ set-node-right ] keep ;
-                                                        
-: rotate-left ( node -- node )
-    dup node-right
-    [ node-left swap set-node-right ] 2keep
-    [ set-node-left ] keep ;
-
-: link-right ( left right key node -- left right key node )
-    swap >r [ swap set-node-left ] 2keep
-    nip dup node-left r> swap ;
-
-: link-left ( left right key node -- left right key node )
-    swap >r rot [ set-node-right ] 2keep
-    drop dup node-right swapd r> swap ;
-
-: cmp ( key node -- obj node -1/0/1 )
-    2dup node-key key-side ;
-
-: lcmp ( key node -- obj node -1/0/1 ) 
-    2dup node-left node-key key-side ;
-
-: rcmp ( key node -- obj node -1/0/1 ) 
-    2dup node-right node-key key-side ;
-
-DEFER: (splay)
-
-: splay-left ( left right key node -- left right key node )
-    dup node-left [
-        lcmp 0 < [ rotate-right ] when
-        dup node-left [ link-right (splay) ] when
-    ] when ;
-
-: splay-right ( left right key node -- left right key node )
-    dup node-right [
-        rcmp 0 > [ rotate-left ] when
-        dup node-right [ link-left (splay) ] when
-    ] when ;
-
-: (splay) ( left right key node -- left right key node )
-    cmp dup 0 <
-    [ drop splay-left ] [ 0 > [ splay-right ] when ] if ;
-
-: assemble ( head left right node -- root )
-    [ node-right swap set-node-left ] keep
-    [ node-left swap set-node-right ] keep
-    [ swap node-left swap set-node-right ] 2keep
-    [ swap node-right swap set-node-left ] keep ;
-
-: splay-at ( key node -- node )
-    >r >r T{ node } clone dup dup r> r>
-    (splay) nip assemble ;
-
-: splay ( key tree -- )
-    [ tree-root splay-at ] keep set-tree-root ;
-
-: splay-split ( key tree -- node node )
-    2dup splay tree-root cmp 0 < [
-        nip dup node-left swap f over set-node-left
-    ] [
-        nip dup node-right swap f over set-node-right swap
-    ] if ;
-
-: get-splay ( key tree -- node ? )
-    2dup splay tree-root cmp 0 = [
-        nip t
-    ] [
-        2drop f f
-    ] if ;
-
-: get-largest ( node -- node )
-    dup [ dup node-right [ nip get-largest ] when* ] when ;
-
-: splay-largest ( node -- node )
-    dup [ dup get-largest node-key swap splay-at ] when ;
-
-: splay-join ( n2 n1 -- node )
-    splay-largest [
-        [ set-node-right ] keep
-    ] [
-        drop f
-    ] if* ;
-
-: remove-splay ( key tree -- )
-    tuck get-splay nip [
-        dup dec-count
-        dup node-right swap node-left splay-join
-        swap set-tree-root
-    ] [ drop ] if* ;
-
-: set-splay ( value key tree -- )
-    2dup get-splay [ 2nip set-node-value ] [
-       drop dup inc-count
-       2dup splay-split rot
-       >r >r swapd r> node boa r> set-tree-root
-    ] if ;
-
-: new-root ( value key tree -- )
-    [ 1 swap set-tree-count ] keep
-    >r swap <node> r> set-tree-root ;
-
-M: splay set-at ( value key tree -- )
-    dup tree-root [ set-splay ] [ new-root ] if ;
-
-M: splay at* ( key tree -- value ? )
-    dup tree-root [
-        get-splay >r dup [ node-value ] when r>
-    ] [
-        2drop f f
-    ] if ;
-
-M: splay delete-at ( key tree -- )
-    dup tree-root [ remove-splay ] [ 2drop ] if ;
-
-M: splay new-assoc
-    2drop <splay> ;
-
-: >splay ( assoc -- tree )
-    T{ splay f f 0 } assoc-clone-like ;
-
-: SPLAY{
-    \ } [ >splay ] parse-literal ; parsing
-
-M: splay assoc-like
-    drop dup splay? [ >splay ] unless ;
-
-M: splay pprint-delims drop \ SPLAY{ \ } ;
diff --git a/unmaintained/trees/splay/summary.txt b/unmaintained/trees/splay/summary.txt
deleted file mode 100644 (file)
index 46391bb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Splay trees
diff --git a/unmaintained/trees/splay/tags.txt b/unmaintained/trees/splay/tags.txt
deleted file mode 100644 (file)
index fb6cea7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-collections
-trees
diff --git a/unmaintained/trees/summary.txt b/unmaintained/trees/summary.txt
deleted file mode 100644 (file)
index 18ad35d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Binary search trees
diff --git a/unmaintained/trees/tags.txt b/unmaintained/trees/tags.txt
deleted file mode 100644 (file)
index fb6cea7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-collections
-trees
diff --git a/unmaintained/trees/trees-docs.factor b/unmaintained/trees/trees-docs.factor
deleted file mode 100644 (file)
index df04f1c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-USING: help.syntax help.markup assocs ;
-IN: trees
-
-HELP: TREE{
-{ $syntax "TREE{ { key value }... }" }
-{ $values { "key" "a key" } { "value" "a value" } }
-{ $description "Literal syntax for an unbalanced tree." } ;
-
-HELP: <tree>
-{ $values { "tree" tree } }
-{ $description "Creates an empty unbalanced binary tree" } ;
-
-HELP: >tree
-{ $values { "assoc" assoc } { "tree" tree } }
-{ $description "Converts any " { $link assoc } " into an unbalanced binary tree." } ;
-
-HELP: tree
-{ $class-description "This is the class for unbalanced binary search trees. It is not usually intended to be used directly but rather as a basis for other trees." } ;
-
-ARTICLE: { "trees" "intro" } "Binary search trees"
-"This is a library for unbalanced binary search trees. It is not intended to be used directly in most situations but rather as a base class for new trees, because performance can degrade to linear time storage/retrieval by the number of keys. These binary search trees conform to the assoc protocol."
-{ $subsection tree }
-{ $subsection <tree> }
-{ $subsection >tree }
-{ $subsection POSTPONE: TREE{ } ;
-
-IN: trees
-ABOUT: { "trees" "intro" }
diff --git a/unmaintained/trees/trees-tests.factor b/unmaintained/trees/trees-tests.factor
deleted file mode 100644 (file)
index fd26b37..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-USING: trees assocs tools.test kernel sequences ;
-IN: trees.tests
-
-: test-tree ( -- tree )
-    TREE{
-        { 7 "seven" }
-        { 9 "nine" }
-        { 4 "four" } 
-        { 4 "replaced four" } 
-        { 7 "replaced seven" }
-    } clone ;
-
-! test set-at, at, at*
-[ "seven" ] [ <tree> "seven" 7 pick set-at 7 swap at ] unit-test
-[ "seven" t ] [ <tree> "seven" 7 pick set-at 7 swap at* ] unit-test
-[ f f ] [ <tree> "seven" 7 pick set-at 8 swap at* ] unit-test
-[ "seven" ] [ <tree> "seven" 7 pick set-at 7 swap at ] unit-test
-[ "replacement" ] [ <tree> "seven" 7 pick set-at "replacement" 7 pick set-at 7 swap at ] unit-test
-[ "replaced four" ] [ test-tree 4 swap at ] unit-test
-[ "nine" ] [ test-tree 9 swap at ] unit-test
-
-! test delete-at
-[ f ] [ test-tree 9 over delete-at 9 swap at ] unit-test
-[ "replaced seven" ] [ test-tree 9 over delete-at 7 swap at ] unit-test
-[ "replaced four" ] [ test-tree 9 over delete-at 4 swap at ] unit-test
-[ "nine" "replaced four" ] [ test-tree 7 over delete-at 9 over at 4 rot at ] unit-test
-[ "nine" ] [ test-tree 7 over delete-at 4 over delete-at 9 swap at ] unit-test
-
diff --git a/unmaintained/trees/trees.factor b/unmaintained/trees/trees.factor
deleted file mode 100755 (executable)
index d22dfdb..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-! Copyright (C) 2007 Alex Chapman
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel generic math sequences arrays io namespaces
-prettyprint.private kernel.private assocs random combinators
-parser prettyprint.backend math.order accessors ;
-IN: trees
-
-TUPLE: tree root count ;
-
-: new-tree ( class -- tree )
-    new
-        f >>root
-        0 >>count ; inline
-
-: <tree> ( -- tree )
-    tree new-tree ;
-
-INSTANCE: tree assoc
-
-TUPLE: node key value left right ;
-
-: new-node ( key value class -- node )
-    new swap >>value swap >>key ;
-
-: <node> ( key value -- node )
-    node new-node ;
-
-SYMBOL: current-side
-
-: left ( -- symbol ) -1 ; inline
-: right ( -- symbol ) 1 ; inline
-
-: key-side ( k1 k2 -- n )
-    <=> {
-        { +lt+ [ -1 ] }
-        { +eq+ [ 0 ] }
-        { +gt+ [ 1 ] }
-    } case ;
-
-: go-left? ( -- ? ) current-side get left eq? ;
-
-: inc-count ( tree -- ) [ 1+ ] change-count drop ;
-
-: dec-count ( tree -- ) [ 1- ] change-count drop ;
-
-: node-link@ ( node ? -- node )
-    go-left? xor [ left>> ] [ right>> ] if ;
-: set-node-link@ ( left parent ? -- ) 
-    go-left? xor [ set-node-left ] [ set-node-right ] if ;
-
-: node-link ( node -- child ) f node-link@  ;
-: set-node-link ( child node -- ) f set-node-link@ ;
-: node+link ( node -- child ) t node-link@ ;
-: set-node+link ( child node -- ) t set-node-link@ ;
-
-: with-side ( side quot -- ) [ swap current-side set call ] with-scope ; inline
-: with-other-side ( quot -- )
-    current-side get neg swap with-side ; inline
-: go-left ( quot -- ) left swap with-side ; inline
-: go-right ( quot -- ) right swap with-side ; inline
-
-: leaf? ( node -- ? )
-    [ left>> ] [ right>> ] bi or not ;
-
-: random-side ( -- side ) left right 2array random ;
-
-: choose-branch ( key node -- key node-left/right )
-    2dup node-key key-side [ node-link ] with-side ;
-
-: node-at* ( key node -- value ? )
-    [
-        2dup node-key = [
-            nip node-value t
-        ] [
-            choose-branch node-at*
-        ] if
-    ] [ drop f f ] if* ;
-
-M: tree at* ( key tree -- value ? )
-    root>> node-at* ;
-
-: node-set ( value key node -- node )
-    2dup key>> key-side dup 0 eq? [
-        drop nip swap >>value
-    ] [
-        [
-            [ node-link [ node-set ] [ swap <node> ] if* ] keep
-            [ set-node-link ] keep
-        ] with-side
-    ] if ;
-
-M: tree set-at ( value key tree -- )
-    [ [ node-set ] [ swap <node> ] if* ] change-root drop ;
-
-: valid-node? ( node -- ? )
-    [
-        dup dup left>> [ node-key swap node-key before? ] when* >r
-        dup dup right>> [ node-key swap node-key after? ] when* r> and swap
-        dup left>> valid-node? swap right>> valid-node? and and
-    ] [ t ] if* ;
-
-: valid-tree? ( tree -- ? ) root>> valid-node? ;
-
-: (node>alist) ( node -- )
-    [
-        [ left>> (node>alist) ]
-        [ [ node-key ] [ node-value ] bi 2array , ]
-        [ right>> (node>alist) ]
-        tri
-    ] when* ;
-
-M: tree >alist [ root>> (node>alist) ] { } make ;
-
-M: tree clear-assoc
-    0 >>count
-    f >>root drop ;
-
-: copy-node-contents ( new old -- )
-    dup node-key pick set-node-key node-value swap set-node-value ;
-
-! Deletion
-DEFER: delete-node
-
-: (prune-extremity) ( parent node -- new-extremity )
-    dup node-link [
-        rot drop (prune-extremity)
-    ] [
-        tuck delete-node swap set-node-link
-    ] if* ;
-
-: prune-extremity ( node -- new-extremity )
-    #! remove and return the leftmost or rightmost child of this node.
-    #! assumes at least one child
-    dup node-link (prune-extremity) ;
-
-: replace-with-child ( node -- node )
-    dup dup node-link copy-node-contents dup node-link delete-node over set-node-link ;
-
-: replace-with-extremity ( node -- node )
-    dup node-link dup node+link [
-        ! predecessor/successor is not the immediate child
-        [ prune-extremity ] with-other-side dupd copy-node-contents
-    ] [
-        ! node-link is the predecessor/successor
-        drop replace-with-child
-    ] if ;
-
-: delete-node-with-two-children ( node -- node )
-    #! randomised to minimise tree unbalancing
-    random-side [ replace-with-extremity ] with-side ;
-
-: delete-node ( node -- node )
-    #! delete this node, returning its replacement
-    dup left>> [
-        dup right>> [
-            delete-node-with-two-children
-        ] [
-            left>> ! left but no right
-        ] if
-    ] [
-        dup right>> [
-            right>> ! right but not left
-        ] [
-            drop f ! no children
-        ] if
-    ] if ;
-
-: delete-bst-node ( key node -- node )
-    2dup node-key key-side dup 0 eq? [
-        drop nip delete-node
-    ] [
-        [ tuck node-link delete-bst-node over set-node-link ] with-side
-    ] if ;
-
-M: tree delete-at
-    [ delete-bst-node ] change-root drop ;
-
-M: tree new-assoc
-    2drop <tree> ;
-
-M: tree clone dup assoc-clone-like ;
-
-: >tree ( assoc -- tree )
-    T{ tree f f 0 } assoc-clone-like ;
-
-M: tree assoc-like drop dup tree? [ >tree ] unless ;
-
-: TREE{
-    \ } [ >tree ] parse-literal ; parsing
-                                                        
-M: tree pprint-delims drop \ TREE{ \ } ;
-M: tree assoc-size count>> ;
-M: tree >pprint-sequence >alist ;
-M: tree pprint-narrow? drop t ;
index 42334a0524c41aac6be856d2a3b0b35a36dc143c..98d14cfdf46588d259f032f95ba77c93d5438410 100644 (file)
@@ -4,6 +4,9 @@ CFLAGS += -fPIC
 PLAF_DLL_OBJS += vm/os-macosx.o vm/mach_signal.o
 
 DLL_EXTENSION = .dylib
+SHARED_DLL_EXTENSION = .dylib
+
+SHARED_FLAG = -dynamiclib
 
 ifdef X11
        LIBS = -lm -framework Cocoa -L/opt/local/lib $(X11_UI_LIBS) -Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib
index e8cb877249e1afeb02421f482540f1084b564e1d..1f488475423178a3838c2ad5e7de940b487c0f6c 100644 (file)
@@ -5,7 +5,8 @@ endif
 EXE_SUFFIX =
 DLL_PREFIX = lib
 DLL_EXTENSION = .a
-# DLL_EXTENSION = .so
+SHARED_DLL_EXTENSION = .so
+SHARED_FLAG = -shared
 
 PLAF_DLL_OBJS = vm/os-unix.o
 PLAF_EXE_OBJS += vm/main-unix.o
@@ -13,7 +14,7 @@ PLAF_EXE_OBJS += vm/main-unix.o
 ifdef NO_UI
        X11_UI_LIBS =
 else
-       X11_UI_LIBS = -lpango-1.0 -lpangocairo-1.0 -lcairo -lglib-2.0 -lgobject-2.0 -lGL -lGLU -lX11
+       X11_UI_LIBS = -lpango-1.0 -lpangocairo-1.0 -lcairo -lglib-2.0 -lgobject-2.0 -lGL -lX11
 endif
 
 # CFLAGS += -fPIC
index 45d2f0cb98f4151657078409f2382b840d1b477f..cdb72f4e2403a1f233f0056f009bc5c169fb9eac 100644 (file)
@@ -1,8 +1,10 @@
 CFLAGS += -DWINDOWS -mno-cygwin
 LIBS = -lm
 PLAF_DLL_OBJS += vm/os-windows.o
+SHARED_FLAG = -shared
 EXE_EXTENSION=.exe
 CONSOLE_EXTENSION=.com
 DLL_EXTENSION=.dll
+SHARED_DLL_EXTENSION=.dll
 LINKER = $(CC) -shared -mno-cygwin -o 
 LINK_WITH_ENGINE = -l$(DLL_PREFIX)factor$(DLL_SUFFIX)
index 8b7df45e9ada4bb060c01020064ce178bdb4a3c9..2681579c5d47005f241a3bc4284c632349d83a3b 100755 (executable)
@@ -160,7 +160,7 @@ void box_value_struct(void *src, CELL size)
        dpush(tag_object(array));
 }
 
-/* On OS X, structs <= 8 bytes are returned in registers. */
+/* On some x86 OSes, structs <= 8 bytes are returned in registers. */
 void box_small_struct(CELL x, CELL y, CELL size)
 {
        CELL data[2];
@@ -169,6 +169,17 @@ void box_small_struct(CELL x, CELL y, CELL size)
        box_value_struct(data,size);
 }
 
+/* On OS X/PPC, complex numbers are returned in registers. */
+void box_medium_struct(CELL x1, CELL x2, CELL x3, CELL x4, CELL size)
+{
+       CELL data[4];
+       data[0] = x1;
+       data[1] = x2;
+       data[2] = x3;
+       data[3] = x4;
+       box_value_struct(data,size);
+}
+
 /* open a native library and push a handle */
 void primitive_dlopen(void)
 {
index ec1eb08acf9fcaece8760195883d4bfa4003c8b0..dc76d49810c422740393919014ddb02aa55c4c5a 100755 (executable)
@@ -40,6 +40,7 @@ void primitive_set_alien_cell(void);
 DLLEXPORT void to_value_struct(CELL src, void *dest, CELL size);
 DLLEXPORT void box_value_struct(void *src, CELL size);
 DLLEXPORT void box_small_struct(CELL x, CELL y, CELL size);
+void box_medium_struct(CELL x1, CELL x2, CELL x3, CELL x4, CELL size);
 
 DEFINE_UNTAG(F_DLL,DLL_TYPE,dll)
 
index ae3f52411287ce2e088d7c75d6b25858d31c9bb0..b7e6b946bb4ec0c123ab70f5a6f3080ec86aca2d 100755 (executable)
@@ -97,13 +97,13 @@ F_CODE_BLOCK *frame_code(F_STACK_FRAME *frame)
 
 CELL frame_type(F_STACK_FRAME *frame)
 {
-       return frame_code(frame)->type;
+       return frame_code(frame)->block.type;
 }
 
 CELL frame_executing(F_STACK_FRAME *frame)
 {
        F_CODE_BLOCK *compiled = frame_code(frame);
-       if(compiled->literals == F)
+       if(compiled->literals == F || !stack_traces_p())
                return F;
        else
        {
index 68937980f6ed0667030c686a7c58b13ca4f4416a..3c13e7b1cdf39d47473872f40c8803c3eabf291b 100755 (executable)
@@ -14,8 +14,6 @@ CELL frame_scan(F_STACK_FRAME *frame);
 CELL frame_type(F_STACK_FRAME *frame);
 
 void primitive_callstack(void);
-void primitive_set_datastack(void);
-void primitive_set_retainstack(void);
 void primitive_set_callstack(void);
 void primitive_callstack_to_array(void);
 void primitive_innermost_stack_frame_quot(void);
index a1369a3f99b8f25a687d28b6f459f8c9436a0efb..8dda8bc16e6d5a684ceb81dcb18c5bb13130419d 100644 (file)
@@ -1,9 +1,8 @@
 #include "master.h"
 
-void flush_icache_for(F_CODE_BLOCK *compiled)
+void flush_icache_for(F_CODE_BLOCK *block)
 {
-       CELL start = (CELL)(compiled + 1);
-       flush_icache(start,compiled->code_length);
+       flush_icache((CELL)block,block->block.size);
 }
 
 void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter)
@@ -12,12 +11,34 @@ void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter)
        {
                F_BYTE_ARRAY *relocation = untag_object(compiled->relocation);
 
+               CELL index = stack_traces_p() ? 1 : 0;
+
                F_REL *rel = (F_REL *)(relocation + 1);
                F_REL *rel_end = (F_REL *)((char *)rel + byte_array_capacity(relocation));
 
                while(rel < rel_end)
                {
-                       iter(rel,compiled);
+                       iter(*rel,index,compiled);
+
+                       switch(REL_TYPE(*rel))
+                       {
+                       case RT_PRIMITIVE:
+                       case RT_XT:
+                       case RT_IMMEDIATE:
+                       case RT_HERE:
+                               index++;
+                               break;
+                       case RT_DLSYM:
+                               index += 2;
+                               break;
+                       case RT_THIS:
+                       case RT_STACK_CHAIN:
+                               break;
+                       default:
+                               critical_error("Bad rel type",*rel);
+                               return; /* Can't happen */
+                       }
+
                        rel++;
                }
        }
@@ -86,13 +107,13 @@ void store_address_in_code_block(CELL class, CELL offset, F_FIXNUM absolute_valu
        }
 }
 
-void update_literal_references_step(F_REL *rel, F_CODE_BLOCK *compiled)
+void update_literal_references_step(F_REL rel, CELL index, F_CODE_BLOCK *compiled)
 {
        if(REL_TYPE(rel) == RT_IMMEDIATE)
        {
-               CELL offset = rel->offset + (CELL)(compiled + 1);
+               CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
                F_ARRAY *literals = untag_object(compiled->literals);
-               F_FIXNUM absolute_value = array_nth(literals,REL_ARGUMENT(rel));
+               F_FIXNUM absolute_value = array_nth(literals,index);
                store_address_in_code_block(REL_CLASS(rel),offset,absolute_value);
        }
 }
@@ -108,12 +129,12 @@ void update_literal_references(F_CODE_BLOCK *compiled)
 aging and nursery collections */
 void copy_literal_references(F_CODE_BLOCK *compiled)
 {
-       if(collecting_gen >= compiled->last_scan)
+       if(collecting_gen >= compiled->block.last_scan)
        {
                if(collecting_accumulation_gen_p())
-                       compiled->last_scan = collecting_gen;
+                       compiled->block.last_scan = collecting_gen;
                else
-                       compiled->last_scan = collecting_gen + 1;
+                       compiled->block.last_scan = collecting_gen + 1;
 
                /* initialize chase pointer */
                CELL scan = newspace->here;
@@ -137,13 +158,13 @@ CELL object_xt(CELL obj)
                return (CELL)untag_quotation(obj)->xt;
 }
 
-void update_word_references_step(F_REL *rel, F_CODE_BLOCK *compiled)
+void update_word_references_step(F_REL rel, CELL index, F_CODE_BLOCK *compiled)
 {
        if(REL_TYPE(rel) == RT_XT)
        {
-               CELL offset = rel->offset + (CELL)(compiled + 1);
+               CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
                F_ARRAY *literals = untag_object(compiled->literals);
-               CELL xt = object_xt(array_nth(literals,REL_ARGUMENT(rel)));
+               CELL xt = object_xt(array_nth(literals,index));
                store_address_in_code_block(REL_CLASS(rel),offset,xt);
        }
 }
@@ -154,7 +175,7 @@ to update references to other words, without worrying about literals
 or dlsyms. */
 void update_word_references(F_CODE_BLOCK *compiled)
 {
-       if(compiled->needs_fixup)
+       if(compiled->block.needs_fixup)
                relocate_code_block(compiled);
        else
        {
@@ -170,12 +191,10 @@ is added to the heap. */
 collections */
 void mark_code_block(F_CODE_BLOCK *compiled)
 {
-       mark_block(compiled_to_block(compiled));
+       mark_block(&compiled->block);
 
        copy_handle(&compiled->literals);
        copy_handle(&compiled->relocation);
-
-       flush_icache_for(compiled);
 }
 
 void mark_stack_frame_step(F_STACK_FRAME *frame)
@@ -229,11 +248,10 @@ void undefined_symbol(void)
 }
 
 /* Look up an external library symbol referenced by a compiled code block */
-void *get_rel_symbol(F_REL *rel, F_ARRAY *literals)
+void *get_rel_symbol(F_ARRAY *literals, CELL index)
 {
-       CELL arg = REL_ARGUMENT(rel);
-       CELL symbol = array_nth(literals,arg);
-       CELL library = array_nth(literals,arg + 1);
+       CELL symbol = array_nth(literals,index);
+       CELL library = array_nth(literals,index + 1);
 
        F_DLL *dll = (library == F ? NULL : untag_dll(library));
 
@@ -266,37 +284,37 @@ void *get_rel_symbol(F_REL *rel, F_ARRAY *literals)
 }
 
 /* Compute an address to store at a relocation */
-void relocate_code_block_step(F_REL *rel, F_CODE_BLOCK *compiled)
+void relocate_code_block_step(F_REL rel, CELL index, F_CODE_BLOCK *compiled)
 {
-       CELL offset = rel->offset + (CELL)(compiled + 1);
+       CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
        F_ARRAY *literals = untag_object(compiled->literals);
        F_FIXNUM absolute_value;
 
        switch(REL_TYPE(rel))
        {
        case RT_PRIMITIVE:
-               absolute_value = (CELL)primitives[REL_ARGUMENT(rel)];
+               absolute_value = (CELL)primitives[to_fixnum(array_nth(literals,index))];
                break;
        case RT_DLSYM:
-               absolute_value = (CELL)get_rel_symbol(rel,literals);
+               absolute_value = (CELL)get_rel_symbol(literals,index);
                break;
        case RT_IMMEDIATE:
-               absolute_value = array_nth(literals,REL_ARGUMENT(rel));
+               absolute_value = array_nth(literals,index);
                break;
        case RT_XT:
-               absolute_value = object_xt(array_nth(literals,REL_ARGUMENT(rel)));
+               absolute_value = object_xt(array_nth(literals,index));
                break;
        case RT_HERE:
-               absolute_value = rel->offset + (CELL)(compiled + 1) + (short)REL_ARGUMENT(rel);
+               absolute_value = offset + (short)to_fixnum(array_nth(literals,index));
                break;
-       case RT_LABEL:
-               absolute_value = (CELL)(compiled + 1) + REL_ARGUMENT(rel);
+       case RT_THIS:
+               absolute_value = (CELL)(compiled + 1);
                break;
        case RT_STACK_CHAIN:
                absolute_value = (CELL)&stack_chain;
                break;
        default:
-               critical_error("Bad rel type",rel->type);
+               critical_error("Bad rel type",rel);
                return; /* Can't happen */
        }
 
@@ -306,8 +324,8 @@ void relocate_code_block_step(F_REL *rel, F_CODE_BLOCK *compiled)
 /* Perform all fixups on a code block */
 void relocate_code_block(F_CODE_BLOCK *compiled)
 {
-       compiled->last_scan = NURSERY;
-       compiled->needs_fixup = false;
+       compiled->block.last_scan = NURSERY;
+       compiled->block.needs_fixup = false;
        iterate_relocations(compiled,relocate_code_block_step);
        flush_icache_for(compiled);
 }
@@ -350,29 +368,24 @@ void deposit_integers(CELL here, F_ARRAY *array, CELL format)
        }
 }
 
-bool stack_traces_p(void)
-{
-       return to_boolean(userenv[STACK_TRACES_ENV]);
-}
-
 CELL compiled_code_format(void)
 {
        return untag_fixnum_fast(userenv[JIT_CODE_FORMAT]);
 }
 
 /* Might GC */
-void *allot_code_block(CELL size)
+F_CODE_BLOCK *allot_code_block(CELL size)
 {
-       void *start = heap_allot(&code_heap,size);
+       F_BLOCK *block = heap_allot(&code_heap,size + sizeof(F_CODE_BLOCK));
 
        /* If allocation failed, do a code GC */
-       if(start == NULL)
+       if(block == NULL)
        {
                gc();
-               start = heap_allot(&code_heap,size);
+               block = heap_allot(&code_heap,size + sizeof(F_CODE_BLOCK));
 
                /* Insufficient room even after code GC, give up */
-               if(start == NULL)
+               if(block == NULL)
                {
                        CELL used, total_free, max_free;
                        heap_usage(&code_heap,&used,&total_free,&max_free);
@@ -385,11 +398,11 @@ void *allot_code_block(CELL size)
                }
        }
 
-       return start;
+       return (F_CODE_BLOCK *)block;
 }
 
 /* Might GC */
-F_CODE_BLOCK *add_compiled_block(
+F_CODE_BLOCK *add_code_block(
        CELL type,
        F_ARRAY *code,
        F_ARRAY *labels,
@@ -404,18 +417,21 @@ F_CODE_BLOCK *add_compiled_block(
        REGISTER_UNTAGGED(code);
        REGISTER_UNTAGGED(labels);
 
-       F_CODE_BLOCK *compiled = allot_code_block(sizeof(F_CODE_BLOCK) + code_length);
+       F_CODE_BLOCK *compiled = allot_code_block(code_length);
 
        UNREGISTER_UNTAGGED(labels);
        UNREGISTER_UNTAGGED(code);
        UNREGISTER_ROOT(relocation);
        UNREGISTER_ROOT(literals);
 
+       /* slight space optimization */
+       if(type_of(literals) == ARRAY_TYPE && array_capacity(untag_object(literals)) == 0)
+               literals = F;
+
        /* compiled header */
-       compiled->type = type;
-       compiled->last_scan = NURSERY;
-       compiled->needs_fixup = true;
-       compiled->code_length = code_length;
+       compiled->block.type = type;
+       compiled->block.last_scan = NURSERY;
+       compiled->block.needs_fixup = true;
        compiled->literals = literals;
        compiled->relocation = relocation;
 
index 5ebe04f9c37366ff6842719b8366aa53848b5499..cb8ebf5e19ea1d078aa03dcd03ed6fb0812d8232 100644 (file)
@@ -9,8 +9,8 @@ typedef enum {
        RT_XT,
        /* current offset */
        RT_HERE,
-       /* a local label */
-       RT_LABEL,
+       /* current code block */
+       RT_THIS,
        /* immediate literal */
        RT_IMMEDIATE,
        /* address of stack_chain var */
@@ -43,21 +43,15 @@ typedef enum {
 #define REL_INDIRECT_ARM_MASK 0xfff
 #define REL_RELATIVE_ARM_3_MASK 0xffffff
 
-/* the rel type is built like a cell to avoid endian-specific code in
-the compiler */
-#define REL_TYPE(r) ((r)->type & 0x000000ff)
-#define REL_CLASS(r) (((r)->type & 0x0000ff00) >> 8)
-#define REL_ARGUMENT(r) (((r)->type & 0xffff0000) >> 16)
-
-/* code relocation consists of a table of entries for each fixup */
-typedef struct {
-       unsigned int type;
-       unsigned int offset;
-} F_REL;
+/* code relocation table consists of a table of entries for each fixup */
+typedef u32 F_REL;
+#define REL_TYPE(r)   (((r) & 0xf0000000) >> 28)
+#define REL_CLASS(r)  (((r) & 0x0f000000) >> 24)
+#define REL_OFFSET(r)  ((r) & 0x00ffffff)
 
 void flush_icache_for(F_CODE_BLOCK *compiled);
 
-typedef void (*RELOCATION_ITERATOR)(F_REL *rel, F_CODE_BLOCK *compiled);
+typedef void (*RELOCATION_ITERATOR)(F_REL rel, CELL index, F_CODE_BLOCK *compiled);
 
 void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter);
 
@@ -81,9 +75,12 @@ void relocate_code_block(F_CODE_BLOCK *relocating);
 
 CELL compiled_code_format(void);
 
-bool stack_traces_p(void);
+INLINE bool stack_traces_p(void)
+{
+       return userenv[STACK_TRACES_ENV] != F;
+}
 
-F_CODE_BLOCK *add_compiled_block(
+F_CODE_BLOCK *add_code_block(
        CELL type,
        F_ARRAY *code,
        F_ARRAY *labels,
index 8c734c263c33bbf34a4afa087933cb9e0efd292b..c3c5bc9a108c04c010f1386e461b18b925d8aa01 100755 (executable)
@@ -13,7 +13,7 @@ void new_heap(F_HEAP *heap, CELL size)
 
 /* If there is no previous block, next_free becomes the head of the free list,
 else its linked in */
-INLINE void update_free_list(F_HEAP *heap, F_BLOCK *prev, F_BLOCK *next_free)
+INLINE void update_free_list(F_HEAP *heap, F_FREE_BLOCK *prev, F_FREE_BLOCK *next_free)
 {
        if(prev)
                prev->next_free = next_free;
@@ -28,18 +28,18 @@ compiling.limit. */
 void build_free_list(F_HEAP *heap, CELL size)
 {
        F_BLOCK *prev = NULL;
-       F_BLOCK *prev_free = NULL;
+       F_FREE_BLOCK *prev_free = NULL;
        F_BLOCK *scan = first_block(heap);
-       F_BLOCK *end = (F_BLOCK *)(heap->segment->start + size);
+       F_FREE_BLOCK *end = (F_FREE_BLOCK *)(heap->segment->start + size);
 
        /* Add all free blocks to the free list */
-       while(scan && scan < end)
+       while(scan && scan < (F_BLOCK *)end)
        {
                switch(scan->status)
                {
                case B_FREE:
-                       update_free_list(heap,prev_free,scan);
-                       prev_free = scan;
+                       update_free_list(heap,prev_free,(F_FREE_BLOCK *)scan);
+                       prev_free = (F_FREE_BLOCK *)scan;
                        break;
                case B_ALLOCATED:
                        break;
@@ -56,9 +56,9 @@ void build_free_list(F_HEAP *heap, CELL size)
        branch is only taken after loading a new image, not after code GC */
        if((CELL)(end + 1) <= heap->segment->end)
        {
-               end->status = B_FREE;
+               end->block.status = B_FREE;
+               end->block.size = heap->segment->end - (CELL)end;
                end->next_free = NULL;
-               end->size = heap->segment->end - (CELL)end;
 
                /* add final free block */
                update_free_list(heap,prev_free,end);
@@ -80,21 +80,19 @@ void build_free_list(F_HEAP *heap, CELL size)
 }
 
 /* Allocate a block of memory from the mark and sweep GC heap */
-void *heap_allot(F_HEAP *heap, CELL size)
+F_BLOCK *heap_allot(F_HEAP *heap, CELL size)
 {
-       F_BLOCK *prev = NULL;
-       F_BLOCK *scan = heap->free_list;
+       F_FREE_BLOCK *prev = NULL;
+       F_FREE_BLOCK *scan = heap->free_list;
 
        size = (size + 31) & ~31;
 
        while(scan)
        {
-               CELL this_size = scan->size - sizeof(F_BLOCK);
-
-               if(scan->status != B_FREE)
+               if(scan->block.status != B_FREE)
                        critical_error("Invalid block in free list",(CELL)scan);
 
-               if(this_size < size)
+               if(scan->block.size < size)
                {
                        prev = scan;
                        scan = scan->next_free;
@@ -102,9 +100,9 @@ void *heap_allot(F_HEAP *heap, CELL size)
                }
 
                /* we found a candidate block */
-               F_BLOCK *next_free;
+               F_FREE_BLOCK *next_free;
 
-               if(this_size - size <= sizeof(F_BLOCK))
+               if(scan->block.size - size <= sizeof(F_BLOCK) * 2)
                {
                        /* too small to be split */
                        next_free = scan->next_free;
@@ -112,12 +110,11 @@ void *heap_allot(F_HEAP *heap, CELL size)
                else
                {
                        /* split the block in two */
-                       CELL new_size = size + sizeof(F_BLOCK);
-                       F_BLOCK *split = (F_BLOCK *)((CELL)scan + new_size);
-                       split->status = B_FREE;
-                       split->size = scan->size - new_size;
+                       F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)scan + size);
+                       split->block.status = B_FREE;
+                       split->block.size = scan->block.size - size;
                        split->next_free = scan->next_free;
-                       scan->size = new_size;
+                       scan->block.size = size;
                        next_free = split;
                }
 
@@ -125,9 +122,8 @@ void *heap_allot(F_HEAP *heap, CELL size)
                update_free_list(heap,prev,next_free);
 
                /* this is our new block */
-               scan->status = B_ALLOCATED;
-
-               return scan + 1;
+               scan->block.status = B_ALLOCATED;
+               return &scan->block;
        }
 
        return NULL;
index 4d4637d0e190fe11e7922e42066c12dbb1755db1..cc2c42f120acd2d52e469878225318a1ff4bff09 100644 (file)
@@ -1,32 +1,11 @@
-typedef enum
-{
-       B_FREE,
-       B_ALLOCATED,
-       B_MARKED
-} F_BLOCK_STATUS;
-
-typedef struct _F_BLOCK
-{
-       F_BLOCK_STATUS status;
-
-       /* In bytes, includes this header */
-       CELL size;
-
-       /* Filled in on image load */
-       struct _F_BLOCK *next_free;
-
-       /* Used during compaction */
-       struct _F_BLOCK *forwarding;
-} F_BLOCK;
-
 typedef struct {
        F_SEGMENT *segment;
-       F_BLOCK *free_list;
+       F_FREE_BLOCK *free_list;
 } F_HEAP;
 
 void new_heap(F_HEAP *heap, CELL size);
 void build_free_list(F_HEAP *heap, CELL size);
-void *heap_allot(F_HEAP *heap, CELL size);
+F_BLOCK *heap_allot(F_HEAP *heap, CELL size);
 void mark_block(F_BLOCK *block);
 void unmark_marked(F_HEAP *heap);
 void free_unmarked(F_HEAP *heap);
index 325aed50378689bfcbef615118c9b6f57e1771a8..65a28c6de304f88efde88041dd72c2a0790df012 100755 (executable)
@@ -14,7 +14,7 @@ bool in_code_heap_p(CELL ptr)
 
 void set_word_code(F_WORD *word, F_CODE_BLOCK *compiled)
 {
-       if(compiled->type != WORD_TYPE)
+       if(compiled->block.type != WORD_TYPE)
                critical_error("bad param to set_word_xt",(CELL)compiled);
 
        word->code = compiled;
@@ -40,7 +40,7 @@ void iterate_code_heap(CODE_HEAP_ITERATOR iter)
        while(scan)
        {
                if(scan->status != B_FREE)
-                       iter(block_to_compiled(scan));
+                       iter((F_CODE_BLOCK *)scan);
                scan = next_block(&code_heap,scan);
        }
 }
@@ -103,7 +103,7 @@ void primitive_modify_code_heap(void)
                        REGISTER_UNTAGGED(alist);
                        REGISTER_UNTAGGED(word);
 
-                       F_CODE_BLOCK *compiled = add_compiled_block(
+                       F_CODE_BLOCK *compiled = add_code_block(
                                WORD_TYPE,
                                code,
                                labels,
@@ -137,7 +137,7 @@ void primitive_code_room(void)
 
 F_CODE_BLOCK *forward_xt(F_CODE_BLOCK *compiled)
 {
-       return block_to_compiled(compiled_to_block(compiled)->forwarding);
+       return (F_CODE_BLOCK *)compiled->block.forwarding;
 }
 
 void forward_frame_xt(F_STACK_FRAME *frame)
index 17a32aedd3d8281f217d86cb4b96bf106204178a..4f52819547a268e860f346850821bea08a7e3f39 100755 (executable)
@@ -1,16 +1,6 @@
 /* compiled code */
 F_HEAP code_heap;
 
-INLINE F_BLOCK *compiled_to_block(F_CODE_BLOCK *compiled)
-{
-       return (F_BLOCK *)compiled - 1;
-}
-
-INLINE F_CODE_BLOCK *block_to_compiled(F_BLOCK *block)
-{
-       return (F_CODE_BLOCK *)(block + 1);
-}
-
 void init_code_heap(CELL size);
 
 bool in_code_heap_p(CELL ptr);
index 30b61b5c0c527ec1dc82156ffa72cb701f9f4d28..8b3141218b0d0fb7cdf53118d71d36b9c4ad08f4 100755 (executable)
@@ -45,7 +45,7 @@ multiply_overflow:
        
 /* Note that the XT is passed to the quotation in r11 */
 #define CALL_OR_JUMP_QUOT \
-       lwz r11,9(r3)      /* load quotation-xt slot */ XX \
+       lwz r11,17(r3)     /* load quotation-xt slot */ XX \
 
 #define CALL_QUOT \
        CALL_OR_JUMP_QUOT XX \
index 36db5d6c80bcdc489db117f0ff4a162a0a610429..7a8e579c6227a282e9fb684b7b537f3a6a6bacdf 100755 (executable)
@@ -29,7 +29,7 @@ and the callstack top is passed in EDX */
        pop %ebp ; \
        pop %ebx
 
-#define QUOT_XT_OFFSET 9
+#define QUOT_XT_OFFSET 17
 
 /* We pass a function pointer to memcpy to work around a Mac OS X
 ABI limitation which would otherwise require us to do a bizzaro PC-relative
index 7b5b5f3167fdfb9eb0ef43bc4fa4b423b5cad0bc..8cf8fb9ae71ff0718761654a6f7dd9fa1bfbb8bf 100644 (file)
@@ -61,7 +61,7 @@
 
 #endif
 
-#define QUOT_XT_OFFSET 21
+#define QUOT_XT_OFFSET 37
 
 /* We pass a function pointer to memcpy to work around a Mac OS X
 ABI limitation which would otherwise require us to do a bizzaro PC-relative
index 06beb7ea33e3c323629411c38a116c79e4b53007..354c9398a54a9f207d238a4a7d0788a1024ed308 100755 (executable)
@@ -30,7 +30,7 @@ u64 decks_scanned;
 CELL code_heap_scans;
 
 /* What generation was being collected when copy_code_heap_roots() was last
-called? Until the next call to add_compiled_block(), future
+called? Until the next call to add_code_block(), future
 collections of younger generations don't have to touch the code
 heap. */
 CELL last_code_heap_scan;
index 6b72b97bec2bfcbb0d80853b886afd25cd19cde8..6f7e883785f092f4befba49cdf1271d10b01350c 100755 (executable)
@@ -311,7 +311,7 @@ void find_data_references(CELL look_for_)
 /* Dump all code blocks for debugging */
 void dump_code_heap(void)
 {
-       CELL size = 0;
+       CELL reloc_size = 0, literal_size = 0;
 
        F_BLOCK *scan = first_block(&code_heap);
 
@@ -324,11 +324,13 @@ void dump_code_heap(void)
                        status = "free";
                        break;
                case B_ALLOCATED:
-                       size += object_size(block_to_compiled(scan)->relocation);
+                       reloc_size += object_size(((F_CODE_BLOCK *)scan)->relocation);
+                       literal_size += object_size(((F_CODE_BLOCK *)scan)->literals);
                        status = "allocated";
                        break;
                case B_MARKED:
-                       size += object_size(block_to_compiled(scan)->relocation);
+                       reloc_size += object_size(((F_CODE_BLOCK *)scan)->relocation);
+                       literal_size += object_size(((F_CODE_BLOCK *)scan)->literals);
                        status = "marked";
                        break;
                default:
@@ -343,7 +345,8 @@ void dump_code_heap(void)
                scan = next_block(&code_heap,scan);
        }
        
-       print_cell(size); print_string(" bytes of relocation data\n");
+       print_cell(reloc_size); print_string(" bytes of relocation data\n");
+       print_cell(literal_size); print_string(" bytes of literal data\n");
 }
 
 void factorbug(void)
index 7c06ec1310568a98a7058e1ff2bfa7a244a3e67e..9b7b7843d247fa4aac507490d269c37a1a006f73 100755 (executable)
@@ -144,12 +144,6 @@ void misc_signal_handler_impl(void)
        signal_error(signal_number,signal_callstack_top);
 }
 
-void primitive_throw(void)
-{
-       dpop();
-       throw_impl(dpop(),stack_chain->callstack_top);
-}
-
 void primitive_call_clear(void)
 {
        throw_impl(dpop(),stack_chain->callstack_bottom);
index c7f8bc8712a5a918235c5199f7dbd9f91949cd41..da3ee8bbe04bf04c3136acdb7799f8599925dabb 100755 (executable)
@@ -32,7 +32,6 @@ void signal_error(int signal, F_STACK_FRAME *native_stack);
 void type_error(CELL type, CELL tagged);
 void not_implemented_error(void);
 
-void primitive_throw(void);
 void primitive_call_clear(void);
 
 INLINE void type_check(CELL type, CELL tagged)
index d9042c945563a854a3b149dc9df24ea554b72c25..9b5d3de6020bce406b977b227e72c31c56cdfa27 100755 (executable)
@@ -132,9 +132,7 @@ void init_factor(F_PARAMETERS *p)
        userenv[CPU_ENV] = tag_object(from_char_string(FACTOR_CPU_STRING));
        userenv[OS_ENV] = tag_object(from_char_string(FACTOR_OS_STRING));
        userenv[CELL_SIZE_ENV] = tag_fixnum(sizeof(CELL));
-       userenv[STACK_TRACES_ENV] = tag_boolean(p->stack_traces);
-       userenv[EXECUTABLE_ENV] = (p->executable_path ?
-               tag_object(from_native_string(p->executable_path)) : F);
+       userenv[EXECUTABLE_ENV] = (p->executable_path ? tag_object(from_native_string(p->executable_path)) : F);
        userenv[ARGS_ENV] = F;
        userenv[EMBEDDED_ENV] = F;
 
@@ -142,7 +140,10 @@ void init_factor(F_PARAMETERS *p)
        gc_off = false;
 
        if(!stage2)
+       {
+               userenv[STACK_TRACES_ENV] = tag_boolean(p->stack_traces);
                do_stage1_init();
+       }
 }
 
 /* May allocate memory */
index 5ce7147200645c57e5d3e38e0de5ccb5a2394226..a1987180d0fa9280d3a002336a22081030a15aaf 100755 (executable)
@@ -86,7 +86,8 @@ void load_image(F_PARAMETERS *p)
        }
 
        F_HEADER h;
-       fread(&h,sizeof(F_HEADER),1,file);
+       if(fread(&h,sizeof(F_HEADER),1,file) != 1)
+               fatal_error("Cannot read image header",0);
 
        if(h.magic != IMAGE_MAGIC)
                fatal_error("Bad image: magic number check failed",h.magic);
@@ -145,27 +146,19 @@ bool save_image(const F_CHAR *filename)
                        h.userenv[i] = userenv[i];
        }
 
-       fwrite(&h,sizeof(F_HEADER),1,file);
+       bool ok = true;
 
-       if(fwrite((void*)tenured->start,h.data_size,1,file) != 1)
-       {
-               print_string("Save data heap failed: "); print_string(strerror(errno)); nl();
-               return false;
-       }
-
-       if(fwrite(first_block(&code_heap),h.code_size,1,file) != 1)
-       {
-               print_string("Save code heap failed: "); print_string(strerror(errno)); nl();
-               return false;
-       }
+       if(fwrite(&h,sizeof(F_HEADER),1,file) != 1) ok = false;
+       if(fwrite((void*)tenured->start,h.data_size,1,file) != 1) ok = false;
+       if(fwrite(first_block(&code_heap),h.code_size,1,file) != 1) ok = false;
+       if(fclose(file)) ok = false;
 
-       if(fclose(file))
+       if(!ok)
        {
-               print_string("Failed to close image file: "); print_string(strerror(errno)); nl();
-               return false;
+               print_string("save-image failed: "); print_string(strerror(errno)); nl();
        }
 
-       return true;
+       return ok;
 }
 
 void primitive_save_image(void)
diff --git a/vm/io.c b/vm/io.c
index bad4854775279ea82c276268c855af9f07237164..d88f1bab504aa205720e2054092b58c708c1db7a 100755 (executable)
--- a/vm/io.c
+++ b/vm/io.c
@@ -163,6 +163,31 @@ void primitive_fwrite(void)
        }
 }
 
+void primitive_fseek(void)
+{
+       int whence = to_fixnum(dpop());
+       FILE *file = unbox_alien();
+       off_t offset = to_signed_8(dpop());
+
+       switch(whence)
+       {
+       case 0: whence = SEEK_SET; break;
+       case 1: whence = SEEK_CUR; break;
+       case 2: whence = SEEK_END; break;
+       default:
+               critical_error("Bad value for whence",whence);
+               break;
+       }
+
+       if(FSEEK(file,offset,whence) == -1)
+       {
+               io_error();
+
+               /* Still here? EINTR */
+               critical_error("Don't know what to do; EINTR from fseek()?",0);
+       }
+}
+
 void primitive_fflush(void)
 {
        FILE *file = unbox_alien();
diff --git a/vm/io.h b/vm/io.h
index dc7d69edee84779afe941438946f7d0240890b3a..63a9c35490843993fc7c5fe32a52fdd7fc707563 100755 (executable)
--- a/vm/io.h
+++ b/vm/io.h
@@ -9,6 +9,7 @@ void primitive_fread(void);
 void primitive_fputc(void);
 void primitive_fwrite(void);
 void primitive_fflush(void);
+void primitive_fseek(void);
 void primitive_fclose(void);
 
 /* Platform specific primitives */
index 94e2f623a3190443d0c770be06197d9791a17e90..e9cdef62727947fe4d1c7aecb54ec775ea98a900 100755 (executable)
@@ -102,12 +102,38 @@ typedef struct {
 } F_STRING;
 
 /* The compiled code heap is structured into blocks. */
-typedef struct
+typedef enum
+{
+       B_FREE,
+       B_ALLOCATED,
+       B_MARKED
+} F_BLOCK_STATUS;
+
+typedef struct _F_BLOCK
 {
+       char status; /* free or allocated? */
        char type; /* this is WORD_TYPE or QUOTATION_TYPE */
        char last_scan; /* the youngest generation in which this block's literals may live */
        char needs_fixup; /* is this a new block that needs full fixup? */
-       CELL code_length; /* # bytes */
+
+       /* In bytes, includes this header */
+       CELL size;
+
+       /* Used during compaction */
+       struct _F_BLOCK *forwarding;
+} F_BLOCK;
+
+typedef struct _F_FREE_BLOCK
+{
+       F_BLOCK block;
+
+       /* Filled in on image load */
+       struct _F_FREE_BLOCK *next_free;
+} F_FREE_BLOCK;
+
+typedef struct
+{
+       F_BLOCK block;
        CELL literals; /* # bytes */
        CELL relocation; /* tagged pointer to byte-array or f */
 } F_CODE_BLOCK;
@@ -172,6 +198,10 @@ typedef struct {
        CELL array;
        /* tagged */
        CELL compiledp;
+       /* tagged */
+       CELL cached_effect;
+       /* tagged */
+       CELL cache_counter;
        /* UNTAGGED */
        XT xt;
        /* UNTAGGED compiled code block */
index d2f34b4bc4c26d50a1c419ce436619ac3c833d8e..35abfee41c66737d1eb3bb13958ac1ce6d491327 100755 (executable)
@@ -23,6 +23,8 @@ typedef char F_SYMBOL;
 #define STRNCMP strncmp
 #define STRDUP strdup
 
+#define FSEEK fseeko
+
 #define FIXNUM_FORMAT "%ld"
 #define CELL_FORMAT "%lu"
 #define CELL_HEX_FORMAT "%lx"
index 0704459dd0800996c2c1abff3a847d47a83737a8..36d350f50dc81f008008adbebb7833c430425ff3 100755 (executable)
@@ -20,6 +20,7 @@ typedef wchar_t F_CHAR;
 #define STRNCMP wcsncmp
 #define STRDUP _wcsdup
 #define MIN(a,b) ((a)>(b)?(b):(a))
+#define FSEEK fseek
 
 #ifdef WIN64
        #define CELL_FORMAT "%Iu"
index 21336e88bb334247baac661822152311db9a63cb..70804542b4fc318b65a1605d396256484ec6c972 100644 (file)
@@ -96,7 +96,7 @@
                        #if defined(FACTOR_X86)
                                #include "os-solaris-x86.32.h"
                        #elif defined(FACTOR_AMD64)
-                               #incluide "os-solaris-x86.64.h"
+                               #include "os-solaris-x86.64.h"
                        #else
                                #error "Unsupported Solaris flavor"
                        #endif
index 2bce9eedb7659d4e85fe829d784155d5600bc30d..80b672d9d2d34d20a406bfcd4ffaf6ad6c7ef6bf 100755 (executable)
@@ -102,7 +102,6 @@ void *primitives[] = {
        primitive_set_alien_double,
        primitive_alien_cell,
        primitive_set_alien_cell,
-       primitive_throw,
        primitive_alien_address,
        primitive_set_slot,
        primitive_string_nth,
@@ -122,6 +121,7 @@ void *primitives[] = {
        primitive_fputc,
        primitive_fwrite,
        primitive_fflush,
+       primitive_fseek,
        primitive_fclose,
        primitive_wrapper,
        primitive_clone,
@@ -144,4 +144,5 @@ void *primitives[] = {
        primitive_clear_gc_stats,
        primitive_jit_compile,
        primitive_load_locals,
+       primitive_check_datastack
 };
index 66cefcf891f7bcd0c244f5b85cd998f2c60e15ce..acafecdff5d3cb20c02c811fb5f9361e1648d26a 100755 (executable)
@@ -3,7 +3,7 @@
 /* Allocates memory */
 F_CODE_BLOCK *compile_profiling_stub(F_WORD *word)
 {
-       CELL literals = allot_array_1(tag_object(word));
+       CELL literals = allot_array_2(tag_object(word),tag_object(word));
        REGISTER_ROOT(literals);
 
        F_ARRAY *quadruple = untag_object(userenv[JIT_PROFILING]);
@@ -11,17 +11,17 @@ F_CODE_BLOCK *compile_profiling_stub(F_WORD *word)
        CELL code = array_nth(quadruple,0);
        REGISTER_ROOT(code);
 
-       F_REL rel;
-       rel.type = to_fixnum(array_nth(quadruple,2)) | (to_fixnum(array_nth(quadruple,1)) << 8);
-       rel.offset = to_fixnum(array_nth(quadruple,3)) * compiled_code_format();
+       F_REL rel = (to_fixnum(array_nth(quadruple,1)) << 24)
+               | (to_fixnum(array_nth(quadruple,2)) << 28)
+               | (to_fixnum(array_nth(quadruple,3)) * compiled_code_format());
 
        F_BYTE_ARRAY *relocation = allot_byte_array(sizeof(F_REL));
-       memcpy((void *)BREF(relocation,0),&rel,sizeof(F_REL));
+       memcpy(relocation + 1,&rel,sizeof(F_REL));
 
        UNREGISTER_ROOT(code);
        UNREGISTER_ROOT(literals);
 
-       return add_compiled_block(
+       return add_code_block(
                WORD_TYPE,
                untag_object(code),
                NULL, /* no labels */
index ca1a8bb3b56eefc291a13253a6734247f291432c..e18e6b609825fa5db2ca1dd9b6c6c8635e3069e1 100755 (executable)
@@ -94,37 +94,30 @@ F_ARRAY *code_to_emit(CELL code)
        return untag_object(array_nth(untag_object(code),0));
 }
 
-F_REL rel_to_emit(CELL code, CELL code_format, CELL code_length,
-       CELL rel_argument, bool *rel_p)
+F_REL rel_to_emit(CELL code, CELL code_format, CELL code_length, bool *rel_p)
 {
        F_ARRAY *quadruple = untag_object(code);
        CELL rel_class = array_nth(quadruple,1);
        CELL rel_type = array_nth(quadruple,2);
        CELL offset = array_nth(quadruple,3);
 
-       F_REL rel;
-
        if(rel_class == F)
        {
                *rel_p = false;
-               rel.type = 0;
-               rel.offset = 0;
+               return 0;
        }
        else
        {
                *rel_p = true;
-               rel.type = to_fixnum(rel_type)
-                       | (to_fixnum(rel_class) << 8)
-                       | (rel_argument << 16);
-               rel.offset = (code_length + to_fixnum(offset)) * code_format;
+               return (to_fixnum(rel_type) << 28)
+                       | (to_fixnum(rel_class) << 24)
+                       | ((code_length + to_fixnum(offset)) * code_format);
        }
-
-       return rel;
 }
 
-#define EMIT(name,rel_argument) { \
+#define EMIT(name) { \
                bool rel_p; \
-               F_REL rel = rel_to_emit(name,code_format,code_count,rel_argument,&rel_p); \
+               F_REL rel = rel_to_emit(name,code_format,code_count,&rel_p); \
                if(rel_p) GROWABLE_BYTE_ARRAY_APPEND(relocation,&rel,sizeof(F_REL)); \
                GROWABLE_ARRAY_APPEND(code,code_to_emit(name)); \
        }
@@ -157,8 +150,8 @@ bool jit_stack_frame_p(F_ARRAY *array)
 
 void set_quot_xt(F_QUOTATION *quot, F_CODE_BLOCK *code)
 {
-       if(code->type != QUOTATION_TYPE)
-               critical_error("bad param to set_quot_xt",(CELL)code);
+       if(code->block.type != QUOTATION_TYPE)
+               critical_error("Bad param to set_quot_xt",(CELL)code);
 
        quot->code = code;
        quot->xt = (XT)(code + 1);
@@ -187,12 +180,13 @@ void jit_compile(CELL quot, bool relocate)
        GROWABLE_ARRAY(literals);
        REGISTER_ROOT(literals);
 
-       GROWABLE_ARRAY_ADD(literals,stack_traces_p() ? quot : F);
+       if(stack_traces_p())
+               GROWABLE_ARRAY_ADD(literals,quot);
 
        bool stack_frame = jit_stack_frame_p(untag_object(array));
 
        if(stack_frame)
-               EMIT(userenv[JIT_PROLOG],0);
+               EMIT(userenv[JIT_PROLOG]);
 
        CELL i;
        CELL length = array_capacity(untag_object(array));
@@ -217,35 +211,36 @@ void jit_compile(CELL quot, bool relocate)
                                        GROWABLE_ARRAY_ADD(literals,T);
                                }
 
-                               EMIT(word->subprimitive,literals_count - 1);
+                               EMIT(word->subprimitive);
                        }
                        else
                        {
-                               GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
+                               GROWABLE_ARRAY_ADD(literals,obj);
 
                                if(i == length - 1)
                                {
                                        if(stack_frame)
-                                               EMIT(userenv[JIT_EPILOG],0);
+                                               EMIT(userenv[JIT_EPILOG]);
 
-                                       EMIT(userenv[JIT_WORD_JUMP],literals_count - 1);
+                                       EMIT(userenv[JIT_WORD_JUMP]);
 
                                        tail_call = true;
                                }
                                else
-                                       EMIT(userenv[JIT_WORD_CALL],literals_count - 1);
+                                       EMIT(userenv[JIT_WORD_CALL]);
                        }
                        break;
                case WRAPPER_TYPE:
                        wrapper = untag_object(obj);
                        GROWABLE_ARRAY_ADD(literals,wrapper->object);
-                       EMIT(userenv[JIT_PUSH_IMMEDIATE],literals_count - 1);
+                       EMIT(userenv[JIT_PUSH_IMMEDIATE]);
                        break;
                case FIXNUM_TYPE:
                        if(jit_primitive_call_p(untag_object(array),i))
                        {
-                               EMIT(userenv[JIT_SAVE_STACK],0);
-                               EMIT(userenv[JIT_PRIMITIVE],to_fixnum(obj));
+                               EMIT(userenv[JIT_SAVE_STACK]);
+                               GROWABLE_ARRAY_ADD(literals,obj);
+                               EMIT(userenv[JIT_PRIMITIVE]);
 
                                i++;
 
@@ -256,15 +251,15 @@ void jit_compile(CELL quot, bool relocate)
                        if(jit_fast_if_p(untag_object(array),i))
                        {
                                if(stack_frame)
-                                       EMIT(userenv[JIT_EPILOG],0);
+                                       EMIT(userenv[JIT_EPILOG]);
 
                                jit_compile(array_nth(untag_object(array),i),relocate);
                                jit_compile(array_nth(untag_object(array),i + 1),relocate);
 
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
-                               EMIT(userenv[JIT_IF_1],literals_count - 1);
+                               EMIT(userenv[JIT_IF_1]);
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i + 1));
-                               EMIT(userenv[JIT_IF_2],literals_count - 1);
+                               EMIT(userenv[JIT_IF_2]);
 
                                i += 2;
 
@@ -276,7 +271,7 @@ void jit_compile(CELL quot, bool relocate)
                                jit_compile(obj,relocate);
 
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
-                               EMIT(userenv[JIT_DIP],literals_count - 1);
+                               EMIT(userenv[JIT_DIP]);
 
                                i++;
                                break;
@@ -286,7 +281,7 @@ void jit_compile(CELL quot, bool relocate)
                                jit_compile(obj,relocate);
 
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
-                               EMIT(userenv[JIT_2DIP],literals_count - 1);
+                               EMIT(userenv[JIT_2DIP]);
 
                                i++;
                                break;
@@ -296,7 +291,7 @@ void jit_compile(CELL quot, bool relocate)
                                jit_compile(obj,relocate);
 
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
-                               EMIT(userenv[JIT_3DIP],literals_count - 1);
+                               EMIT(userenv[JIT_3DIP]);
 
                                i++;
                                break;
@@ -305,10 +300,10 @@ void jit_compile(CELL quot, bool relocate)
                        if(jit_fast_dispatch_p(untag_object(array),i))
                        {
                                if(stack_frame)
-                                       EMIT(userenv[JIT_EPILOG],0);
+                                       EMIT(userenv[JIT_EPILOG]);
 
                                GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
-                               EMIT(userenv[JIT_DISPATCH],literals_count - 1);
+                               EMIT(userenv[JIT_DISPATCH]);
 
                                i++;
 
@@ -322,7 +317,7 @@ void jit_compile(CELL quot, bool relocate)
                        }
                default:
                        GROWABLE_ARRAY_ADD(literals,obj);
-                       EMIT(userenv[JIT_PUSH_IMMEDIATE],literals_count - 1);
+                       EMIT(userenv[JIT_PUSH_IMMEDIATE]);
                        break;
                }
        }
@@ -330,16 +325,16 @@ void jit_compile(CELL quot, bool relocate)
        if(!tail_call)
        {
                if(stack_frame)
-                       EMIT(userenv[JIT_EPILOG],0);
+                       EMIT(userenv[JIT_EPILOG]);
 
-               EMIT(userenv[JIT_RETURN],0);
+               EMIT(userenv[JIT_RETURN]);
        }
 
        GROWABLE_ARRAY_TRIM(code);
        GROWABLE_ARRAY_TRIM(literals);
        GROWABLE_BYTE_ARRAY_TRIM(relocation);
 
-       F_CODE_BLOCK *compiled = add_compiled_block(
+       F_CODE_BLOCK *compiled = add_code_block(
                QUOTATION_TYPE,
                untag_object(code),
                NULL,
@@ -514,6 +509,8 @@ void primitive_array_to_quotation(void)
        quot->array = dpeek();
        quot->xt = lazy_jit_compile;
        quot->compiledp = F;
+       quot->cached_effect = F;
+       quot->cache_counter = F;
        drepl(tag_object(quot));
 }
 
index c7002eb0ecaadcccd23f935ff72e9ff8af9fad9a..e55eb904a74c9c93a768eacba40c04b10fe294c6 100755 (executable)
--- a/vm/run.c
+++ b/vm/run.c
@@ -155,6 +155,32 @@ void primitive_set_retainstack(void)
        rs = array_to_stack(untag_array(dpop()),rs_bot);
 }
 
+/* Used to implement call( */
+void primitive_check_datastack(void)
+{
+       F_FIXNUM out = to_fixnum(dpop());
+       F_FIXNUM in = to_fixnum(dpop());
+       F_FIXNUM height = out - in;
+       F_ARRAY *array = untag_array(dpop());
+       F_FIXNUM length = array_capacity(array);
+       F_FIXNUM depth = (ds - ds_bot + CELLS) / CELLS;
+       if(depth - height != length)
+               dpush(F);
+       else
+       {
+               F_FIXNUM i;
+               for(i = 0; i < length - in; i++)
+               {
+                       if(get(ds_bot + i * CELLS) != array_nth(array,i))
+                       {
+                               dpush(F);
+                               return;
+                       }
+               }
+               dpush(T);
+       }
+}
+
 void primitive_getenv(void)
 {
        F_FIXNUM e = untag_fixnum_fast(dpeek());
index 06b631701508d282f0640a22d34e1709e26c2657..2acff2cd5acd0a3ac6021f919781b0f5df03e265 100755 (executable)
--- a/vm/run.h
+++ b/vm/run.h
@@ -236,6 +236,9 @@ void init_stacks(CELL ds_size, CELL rs_size);
 
 void primitive_datastack(void);
 void primitive_retainstack(void);
+void primitive_set_datastack(void);
+void primitive_set_retainstack(void);
+void primitive_check_datastack(void);
 void primitive_getenv(void);
 void primitive_setenv(void);
 void primitive_exit(void);
index 2f8cafb768045122920f797a9fe1655db8e73e99..119dc675bc92f74d35da9d22ebc08b668134fb87 100755 (executable)
@@ -81,7 +81,7 @@ void primitive_word_xt(void)
        F_WORD *word = untag_word(dpop());
        F_CODE_BLOCK *code = (profiling_p ? word->profiling : word->code);
        dpush(allot_cell((CELL)code + sizeof(F_CODE_BLOCK)));
-       dpush(allot_cell((CELL)code + sizeof(F_CODE_BLOCK) + code->code_length));
+       dpush(allot_cell((CELL)code + code->block.size));
 }
 
 void primitive_wrapper(void)
@@ -139,6 +139,18 @@ CELL allot_array_1(CELL obj)
        return tag_object(a);
 }
 
+CELL allot_array_2(CELL v1, CELL v2)
+{
+       REGISTER_ROOT(v1);
+       REGISTER_ROOT(v2);
+       F_ARRAY *a = allot_array_internal(ARRAY_TYPE,2);
+       UNREGISTER_ROOT(v2);
+       UNREGISTER_ROOT(v1);
+       set_array_nth(a,0,v1);
+       set_array_nth(a,1,v2);
+       return tag_object(a);
+}
+
 CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4)
 {
        REGISTER_ROOT(v1);
index 5850489a4c1ae5bb07c3a17ff88b09443a51530a..2775f57bb24bd38b76285695b9a7cdd2595ce042 100755 (executable)
@@ -109,6 +109,7 @@ F_ARRAY *allot_array(CELL type, CELL capacity, CELL fill);
 F_BYTE_ARRAY *allot_byte_array(CELL size);
 
 CELL allot_array_1(CELL obj);
+CELL allot_array_2(CELL v1, CELL v2);
 CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4);
 
 void primitive_array(void);