Merge branch 'master' of git://factorcode.org/git/factor

db4
Doug Coleman 2008-02-15 20:38:42 -06:00
commit 863ace7ab3
34 changed files with 340 additions and 354 deletions

View File

@ -59,6 +59,7 @@ ARTICLE: "assocs-sets" "Set-theoretic operations on assocs"
{ $subsection diff }
{ $subsection remove-all }
{ $subsection substitute }
{ $subsection substitute-here }
{ $see-also key? } ;
ARTICLE: "assocs-mutation" "Storing keys and values in assocs"
@ -266,12 +267,16 @@ HELP: remove-all
{ $notes "The values of the keys in the assoc are disregarded, so this word is usually used for set-theoretic calculations where the assoc in question either has dummy sentinels as values, or the values equal the keys." }
{ $side-effects "assoc" } ;
HELP: substitute
{ $values { "assoc" assoc } { "seq" "a mutable sequence" } }
{ $description "Replaces elements of " { $snippet "seq" } " which appear in as keys in " { $snippet "assoc" } " with the corresponding values, acting as the identity on all other elements." }
HELP: substitute-here
{ $values { "seq" "a mutable sequence" } { "assoc" assoc } }
{ $description "Replaces elements of " { $snippet "seq" } " which appear as keys in " { $snippet "assoc" } " with the corresponding values, acting as the identity on all other elements." }
{ $errors "Throws an error if " { $snippet "assoc" } " contains values whose types are not permissible in " { $snippet "seq" } "." }
{ $side-effects "seq" } ;
HELP: substitute
{ $values { "seq" sequence } { "assoc" assoc } { "newseq" sequence } }
{ $description "Creates a new sequence where elements of " { $snippet "seq" } " which appear as keys in " { $snippet "assoc" } " are replaced by the corresponding values, and all other elements are unchanged." } ;
HELP: cache
{ $values { "key" "a key" } { "assoc" assoc } { "quot" "a quotation with stack effect " { $snippet "( key -- value )" } } { "value" "a previously-retained or freshly-computed value" } }
{ $description "If the key is present in the assoc, outputs the associated value, otherwise calls the quotation to produce a value and stores the key/value pair into the assoc." }

View File

@ -124,8 +124,14 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
: remove-all ( assoc seq -- subseq )
swap [ key? not ] curry subset ;
: substitute ( assoc seq -- )
swap [ dupd at* [ nip ] [ drop ] if ] curry change-each ;
: (substitute)
[ dupd at* [ nip ] [ drop ] if ] curry ; inline
: substitute-here ( seq assoc -- )
(substitute) change-each ;
: substitute ( seq assoc -- newseq )
(substitute) map ;
: cache ( key assoc quot -- value )
2over at [

View File

@ -59,7 +59,7 @@ SYMBOL: bootstrap-time
default-image-name "output-image" set-global
"math help compiler tools ui ui.tools io" "include" set-global
"math help handbook compiler tools ui ui.tools io" "include" set-global
"" "exclude" set-global
parse-command-line

View File

@ -0,0 +1,4 @@
IN: temporary
USING: debugger kernel continuations tools.test ;
[ ] [ [ drop ] [ error. ] recover ] unit-test

View File

@ -26,7 +26,7 @@ SYMBOL: compiling-word
SYMBOL: compiling-label
SYMBOL: compiling-loop?
SYMBOL: compiling-loops
! Label of current word, after prologue, makes recursion faster
SYMBOL: current-label-start
@ -34,7 +34,7 @@ SYMBOL: current-label-start
: compiled-stack-traces? ( -- ? ) 36 getenv ;
: begin-compiling ( word label -- )
compiling-loop? off
H{ } clone compiling-loops set
compiling-label set
compiling-word set
compiled-stack-traces?
@ -94,8 +94,8 @@ M: node generate-node drop iterate-next ;
: generate-call ( label -- next )
dup maybe-compile
end-basic-block
dup compiling-label get eq? compiling-loop? get and [
drop current-label-start get %jump-label f
dup compiling-loops get at [
%jump-label f
] [
tail-call? [
%jump f
@ -104,7 +104,7 @@ M: node generate-node drop iterate-next ;
%call
iterate-next
] if
] if ;
] ?if ;
! #label
M: #label generate-node
@ -113,17 +113,13 @@ M: #label generate-node
r> ;
! #loop
: compiling-loop ( word -- )
<label> dup resolve-label swap compiling-loops get set-at ;
M: #loop generate-node
end-basic-block
[
dup node-param compiling-label set
current-label-start define-label
current-label-start resolve-label
compiling-loop? on
dup node-param compiling-loop
node-child generate-nodes
end-basic-block
] with-scope
init-templates
iterate-next ;
! #if
@ -269,5 +265,6 @@ M: #r> generate-node
! #return
M: #return generate-node
node-param compiling-label get eq? compiling-loop? get and
[ end-basic-block %return ] unless f ;
end-basic-block
node-param compiling-loops get key?
[ %return ] unless f ;

2
core/generator/registers/registers.factor Normal file → Executable file
View File

@ -504,7 +504,7 @@ M: loc lazy-store
: substitute-vregs ( values vregs -- )
[ vreg-substitution ] 2map
[ substitute-vreg? ] assoc-subset >hashtable
[ swap substitute ] curry each-phantom ;
[ substitute-here ] curry each-phantom ;
: set-operand ( value var -- )
>r dup constant? [ constant-value ] when r> set ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2006, 2007 Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license.
USING: math kernel sequences sbufs vectors io.streams.lines io.streams.plain
namespaces unicode.syntax growable strings io classes io.streams.c
namespaces unicode growable strings io classes io.streams.c
continuations ;
IN: io.encodings
@ -19,7 +19,7 @@ SYMBOL: begin
over push 0 begin ;
: push-replacement ( buf -- buf ch state )
UNICHAR: replacement-character decoded ;
CHAR: replacement-character decoded ;
: finish-decoding ( buf ch state -- str )
begin eq? [ decode-error ] unless drop "" like ;

View File

@ -1,15 +1,15 @@
USING: tools.test io.utf16 arrays unicode.syntax ;
USING: tools.test io.utf16 arrays unicode ;
[ { CHAR: x } ] [ { 0 CHAR: x } decode-utf16be >array ] unit-test
[ { HEX: 1D11E } ] [ { HEX: D8 HEX: 34 HEX: DD HEX: 1E } decode-utf16be >array ] unit-test
[ { UNICHAR: replacement-character } ] [ { BIN: 11011111 CHAR: q } decode-utf16be >array ] unit-test
[ { UNICHAR: replacement-character } ] [ { BIN: 11011011 CHAR: x BIN: 11011011 CHAR: x } decode-utf16be >array ] unit-test
[ { CHAR: replacement-character } ] [ { BIN: 11011111 CHAR: q } decode-utf16be >array ] unit-test
[ { CHAR: replacement-character } ] [ { BIN: 11011011 CHAR: x BIN: 11011011 CHAR: x } decode-utf16be >array ] unit-test
[ B{ 0 120 216 52 221 30 } ] [ { CHAR: x HEX: 1d11e } encode-utf16be ] unit-test
[ { CHAR: x } ] [ { CHAR: x 0 } decode-utf16le >array ] unit-test
[ { 119070 } ] [ { HEX: 34 HEX: D8 HEX: 1E HEX: DD } decode-utf16le >array ] unit-test
[ { UNICHAR: replacement-character } ] [ { 0 BIN: 11011111 } decode-utf16le >array ] unit-test
[ { UNICHAR: replacement-character } ] [ { 0 BIN: 11011011 0 0 } decode-utf16le >array ] unit-test
[ { CHAR: replacement-character } ] [ { 0 BIN: 11011111 } decode-utf16le >array ] unit-test
[ { CHAR: replacement-character } ] [ { 0 BIN: 11011011 0 0 } decode-utf16le >array ] unit-test
[ B{ 120 0 52 216 30 221 } ] [ { CHAR: x HEX: 1d11e } encode-utf16le ] unit-test

View File

@ -1,5 +1,5 @@
USING: io.encodings.utf8 tools.test sbufs kernel io
sequences strings arrays unicode.syntax ;
sequences strings arrays unicode ;
: decode-utf8-w/stream ( array -- newarray )
>sbuf dup reverse-here <utf8> contents >array ;
@ -7,7 +7,7 @@ sequences strings arrays unicode.syntax ;
: encode-utf8-w/stream ( array -- newarray )
SBUF" " clone tuck <utf8> write >array ;
[ { UNICHAR: replacement-character } ] [ { BIN: 11110101 BIN: 10111111 BIN: 10000000 BIN: 11111111 } decode-utf8-w/stream >array ] unit-test
[ { CHAR: replacement-character } ] [ { BIN: 11110101 BIN: 10111111 BIN: 10000000 BIN: 11111111 } decode-utf8-w/stream >array ] unit-test
[ { BIN: 101111111000000111111 } ] [ { BIN: 11110101 BIN: 10111111 BIN: 10000000 BIN: 10111111 } decode-utf8-w/stream >array ] unit-test
@ -15,7 +15,7 @@ sequences strings arrays unicode.syntax ;
[ { BIN: 11111000000 } ] [ { BIN: 11011111 BIN: 10000000 } decode-utf8-w/stream >array ] unit-test
[ { UNICHAR: replacement-character } ] [ { BIN: 10000000 } decode-utf8-w/stream >array ] unit-test
[ { CHAR: replacement-character } ] [ { BIN: 10000000 } decode-utf8-w/stream >array ] unit-test
[ { BIN: 1111000000111111 } ] [ { BIN: 11101111 BIN: 10000000 BIN: 10111111 } decode-utf8-w/stream >array ] unit-test

View File

@ -37,10 +37,10 @@ GENERIC: optimize-node* ( node -- node/t changed? )
over assoc-empty? [
2drop
] [
2dup node-in-d substitute
2dup node-in-r substitute
2dup node-out-d substitute
node-out-r substitute
2dup node-in-d swap substitute-here
2dup node-in-r swap substitute-here
2dup node-out-d swap substitute-here
node-out-r swap substitute-here
] if ;
: perform-substitutions ( node -- )

35
core/optimizer/control/control-tests.factor Normal file → Executable file
View File

@ -113,7 +113,7 @@ optimizer ;
] unit-test
[ f ] [
[ [ [ ] map ] map ] dataflow optimize
[ [ [ ] map ] map ] dataflow dup detect-loops
[ dup #label? swap #loop? not and ] node-exists?
] unit-test
@ -146,3 +146,36 @@ DEFER: a
[ a ] dataflow dup detect-loops
\ b label-is-loop?
] unit-test
DEFER: a'
: b' ( -- )
blah [ b' b' ] [ a' ] if ; inline
: a' ( -- )
blah [ b' ] [ a' ] if ; inline
[ f ] [
[ a' ] dataflow dup detect-loops
\ a' label-is-loop?
] unit-test
[ f ] [
[ b' ] dataflow dup detect-loops
\ b' label-is-loop?
] unit-test
! I used to think this should be f, but doing this on pen and
! paper almost convinced me that a loop conversion here is
! sound. The loop analysis algorithm looks pretty solid -- its
! a standard iterative dataflow problem after all -- so I'm
! tempted to believe the computer here
[ t ] [
[ b' ] dataflow dup detect-loops
\ a' label-is-loop?
] unit-test
[ f ] [
[ a' ] dataflow dup detect-loops
\ b' label-is-loop?
] unit-test

View File

@ -7,7 +7,7 @@ combinators classes generic.math continuations optimizer.def-use
optimizer.backend generic.standard ;
IN: optimizer.control
! ! ! Loop detection
! ! ! Rudimentary CFA
! A LOOP
!
@ -36,7 +36,8 @@ IN: optimizer.control
! |
! #values
!
! NOT A LOOP (call to A nested inside another label/loop):
! NOT A LOOP (call to A nested inside another label which is
! not a loop):
!
!
! #label A
@ -53,38 +54,70 @@ IN: optimizer.control
! | |
! #call-label A |
! | |
! ... ...
! #values |
! #call-label B
! |
! ...
GENERIC: detect-loops* ( node -- )
! Mapping word => { node { nesting tail? }+ height }
! We record all calls to a label, their control nesting and
! whether it is a tail call or not
SYMBOL: label-info
M: node detect-loops* drop ;
GENERIC: collect-label-info* ( node -- )
M: #label detect-loops* t swap set-#label-loop? ;
M: #label collect-label-info*
[ V{ } clone node-stack get length 3array ] keep
node-param label-info get set-at ;
: not-a-loop ( #label -- )
f swap set-#label-loop? ;
USE: prettyprint
: tail-call? ( -- ? )
node-stack get
dup [ #label? ] find-last drop [ 1+ ] [ 0 ] if* tail
[ node-successor #tail? ] all? ;
USE: io
: detect-loop ( seen-other? label node -- seen-other? continue? )
#! seen-other?: have we seen another label?
{
{ [ dup #label? not ] [ 2drop t ] }
{ [ 2dup node-param eq? not ] [ 3drop t t ] }
{ [ tail-call? not ] [ not-a-loop drop f ] }
{ [ pick ] [ not-a-loop drop f ] }
{ [ t ] [ 2drop f ] }
} cond ;
M: #call-label collect-label-info*
node-param label-info get at
node-stack get over third tail
[ [ #label? ] subset [ node-param ] map ] keep
[ node-successor #tail? ] all? 2array
swap second push ;
M: #call-label detect-loops*
f swap node-param node-stack get <reversed>
[ detect-loop ] with all? 2drop ;
M: node collect-label-info*
drop ;
: detect-loops ( node -- )
[ detect-loops* ] each-node ;
: collect-label-info ( node -- )
H{ } clone label-info set
[ collect-label-info* ] each-node ;
! Mapping word => label
SYMBOL: potential-loops
: remove-non-tail-calls ( -- )
label-info get
[ nip second [ second ] all? ] assoc-subset
[ first ] assoc-map
potential-loops set ;
: remove-non-loop-calls ( -- )
! Boolean is set to t if something changed.
! We recurse until a fixed point is reached.
f label-info get [
! If label X is called from within a label Y that is
! no longer a potential loop, then X is no longer a
! potential loop either.
over potential-loops get key? [
second [ first ] map concat
potential-loops get [ key? ] curry all?
[ drop ] [ potential-loops get delete-at t or ] if
] [ 2drop ] if
] assoc-each [ remove-non-loop-calls ] when ;
: detect-loops ( nodes -- )
[
collect-label-info
remove-non-tail-calls
remove-non-loop-calls
potential-loops get [
nip t swap set-#label-loop?
] assoc-each
] with-scope ;
! ! ! Constant branch folding
!
@ -204,7 +237,7 @@ M: #if optimize-node*
! #label -> C -> #return 1
! |
! -> #if -> #merge -> #return 2
! -> #if -> #merge (*) -> #return 2
! |
! --------
! | |
@ -218,17 +251,17 @@ M: #if optimize-node*
! AFTER:
! #label -> #terminate
! #label -> #return 1
! |
! -> #if -> #terminate
! |
! --------
! | |
! A B
! | |
! -> #if -------> #merge (*) -> #return 2
! | \-------------------/
! ---------------- |
! | | |
! A B unreacachable code needed to
! | | preserve invariants
! #values |
! | #call-label
! #merge |
! #merge (*) |
! | |
! C #values
! |
@ -282,14 +315,22 @@ M: node add-loop-exit*
] [ 2drop f ] if
] [ drop f ] if ;
! M: #loop optimize-node*
! dup lift-loop-tail? dup [
! last-node >r
! dup detach-node-successor
! over node-child find-final-if detach-node-successor
! [ set-node-successor ] keep
! r> set-node-successor
! t
! ] [
! 2drop t f
! ] if ;
M: #loop optimize-node*
dup lift-loop-tail? dup [
last-node "values" set
dup node-successor "tail" set
dup node-successor last-node "return" set
dup node-child find-final-if node-successor "merge" set
! #label -> #return
"return" get clone-node over set-node-successor
! #merge -> C
"merge" get clone-node "tail" get over set-node-successor
! #values -> #merge ->C
"values" get set-node-successor
t
] [
2drop t f
] if ;

View File

@ -266,19 +266,10 @@ HELP: escape
{ $description "Converts from a single-character escape code and the corresponding character." }
{ $examples { $example "CHAR: n escape CHAR: \\n = ." "t" } } ;
HELP: next-escape
{ $values { "m" "an index into " { $snippet "str" } } { "str" string } { "n" "an index into " { $snippet "str" } } { "ch" "a character" } }
{ $description "Helper word for " { $link parse-string } " which parses an escape sequence starting at the " { $snippet "m" } "th index of " { $snippet "str" } "." }
{ $errors "Throws a " { $link bad-escape } " if the string contains an invalid escape sequence." } ;
HELP: next-char
{ $values { "m" "an index into " { $snippet "str" } } { "str" string } { "n" "an index into " { $snippet "str" } } { "ch" "a character" } }
{ $description "Helper word for " { $link parse-string } " which parses a character starting at the " { $snippet "m" } "th index of " { $snippet "str" } "." } ;
HELP: parse-string
{ $values { "str" "a new " { $link string } } }
{ $description "Parses the line until a quote (\"), interpreting escape codes along the way." }
{ $errors "Throws an " { $link bad-escape } " if the string contains an invalid escape sequence." }
{ $errors "Throws an error if the string contains an invalid escape sequence." }
$parsing-note ;
HELP: still-parsing?

View File

@ -119,22 +119,43 @@ M: bad-escape summary drop "Bad escape code" ;
{ CHAR: \" CHAR: \" }
} at [ bad-escape ] unless* ;
: next-escape ( m str -- n ch )
2dup nth CHAR: u =
[ >r 1+ dup 6 + tuck r> subseq hex> ]
[ over 1+ -rot nth escape ] if ;
SYMBOL: name>char-hook
: next-char ( m str -- n ch )
2dup nth CHAR: \\ =
[ >r 1+ r> next-escape ] [ over 1+ -rot nth ] if ;
name>char-hook global [
[ "Unicode support not available" throw ] or
] change-at
: (parse-string) ( m str -- n )
2dup nth CHAR: " =
[ drop 1+ ] [ [ next-char , ] keep (parse-string) ] if ;
: unicode-escape ( str -- ch str' )
"{" ?head-slice [
CHAR: } over index cut-slice
>r >string name>char-hook get call r>
1 tail-slice
] [
6 cut-slice >r hex> r>
] if ;
: next-escape ( str -- ch str' )
"u" ?head-slice [
unicode-escape
] [
unclip-slice escape swap
] if ;
: (parse-string) ( str -- m )
dup [ "\"\\" member? ] find dup [
>r cut-slice >r % r> 1 tail-slice r>
dup CHAR: " = [
drop slice-from
] [
drop next-escape >r , r> (parse-string)
] if
] [
"Unterminated string" throw
] if ;
: parse-string ( -- str )
lexer get [
[ (parse-string) ] "" make swap
[ swap tail-slice (parse-string) ] "" make swap
] change-column ;
TUPLE: parse-error file line col text ;

View File

@ -100,13 +100,9 @@ ARTICLE: "escape" "Character escape codes"
{ { $snippet "\\0" } "a null byte (ASCII 0)" }
{ { $snippet "\\e" } "escape (ASCII 27)" }
{ { $snippet "\\\"" } { $snippet "\"" } }
}
"A Unicode character can be specified by its code number by writing " { $snippet "\\u" } " followed by a six-digit hexadecimal number. That is, the following two expressions are equivalent:"
{ $code
"CHAR: \\u000078"
"78"
}
"While not useful for single characters, this syntax is also permitted inside strings." ;
{ { $snippet "\\u" { $emphasis "xxxxxx" } } { "The Unicode code point with hexadecimal number " { $snippet { $emphasis "xxxxxx" } } } }
{ { $snippet "\\u{" { $emphasis "name" } "}" } { "The Unicode code point named " { $snippet { $emphasis "name" } } } }
} ;
ARTICLE: "syntax-strings" "Character and string syntax"
"Factor has no distinct character type, however Unicode character value integers can be read by specifying a literal character, or an escaped representation thereof."
@ -412,8 +408,17 @@ HELP: IN:
HELP: CHAR:
{ $syntax "CHAR: token" }
{ $values { "token" "a literal character or escape code" } }
{ $description "Adds the Unicode code point of the character represented by the token to the parse tree." } ;
{ $values { "token" "a literal character, escape code, or Unicode character name" } }
{ $description "Adds a Unicode code point to the parse tree." }
{ $examples
{ $code
"CHAR: x"
"CHAR: \\u000032"
"CHAR: \\u{exclamation-mark}"
"CHAR: exclamation-mark"
"CHAR: ugaritic-letter-samka"
}
} ;
HELP: "
{ $syntax "\"string...\"" }

View File

@ -5,7 +5,8 @@ byte-vectors definitions generic hashtables kernel math
namespaces parser sequences strings sbufs vectors words
quotations io assocs splitting tuples generic.standard
generic.math classes io.files vocabs float-arrays float-vectors
classes.union classes.mixin classes.predicate compiler.units ;
classes.union classes.mixin classes.predicate compiler.units
combinators ;
IN: bootstrap.syntax
! These words are defined as a top-level form, instead of with
@ -56,7 +57,14 @@ IN: bootstrap.syntax
"f" [ f parsed ] define-syntax
"t" "syntax" lookup define-symbol
"CHAR:" [ 0 scan next-char nip parsed ] define-syntax
"CHAR:" [
scan {
{ [ dup length 1 = ] [ first ] }
{ [ "\\" ?head ] [ next-escape drop ] }
{ [ t ] [ name>char-hook get call ] }
} cond parsed
] define-syntax
"\"" [ parse-string parsed ] define-syntax
"SBUF\"" [

View File

@ -1,10 +1,10 @@
! Copyright (C) 2007, 2008 Eduardo Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces splitting sequences io.files kernel assocs
words vocabs definitions parser continuations inspector debugger
io io.styles io.streams.lines hashtables sorting prettyprint
source-files arrays combinators strings system math.parser
compiler.errors ;
USING: namespaces sequences io.files kernel assocs words vocabs
definitions parser continuations inspector debugger io io.styles
io.streams.lines hashtables sorting prettyprint source-files
arrays combinators strings system math.parser compiler.errors
splitting ;
IN: vocabs.loader
SYMBOL: vocab-roots
@ -16,7 +16,7 @@ V{
} clone vocab-roots set-global
: vocab-dir ( vocab -- dir )
vocab-name "." split "/" join ;
vocab-name { { CHAR: . CHAR: / } } substitute ;
: vocab-dir+ ( vocab str/f -- path )
>r vocab-name "." split r>

View File

@ -0,0 +1,3 @@
USING: vocabs.loader vocabs kernel ;
"bootstrap.help" vocab [ "help.handbook" require ] when

View File

@ -14,8 +14,6 @@ IN: bootstrap.help
[ vocab-root ] subset
[ vocab-source-loaded? ] subset
[ dup vocab-docs-loaded? [ drop ] [ load-docs ] if ] each
] with-variable
"help.handbook" require ;
] with-variable ;
load-help

View File

@ -4,10 +4,11 @@ USING: vocabs.loader sequences ;
"bootstrap.image"
"tools.annotations"
"tools.crossref"
! "tools.deploy"
"tools.deploy"
"tools.memory"
"tools.profiler"
"tools.test"
"tools.time"
"tools.disassembler"
"editors"
} [ require ] each

View File

@ -1,8 +1,8 @@
USING: help help.markup help.syntax help.topics
namespaces words sequences classes assocs vocabs kernel
arrays prettyprint.backend kernel.private io tools.browser
generic math tools.profiler system ui strings sbufs vectors
byte-arrays bit-arrays float-arrays quotations help.lint ;
USING: help help.markup help.syntax help.definitions help.topics
namespaces words sequences classes assocs vocabs kernel arrays
prettyprint.backend kernel.private io generic math system
strings sbufs vectors byte-arrays bit-arrays float-arrays
quotations ;
IN: help.handbook
ARTICLE: "conventions" "Conventions"
@ -161,15 +161,20 @@ ARTICLE: "io" "Input and output"
{ $subsection "io.timeouts" } ;
ARTICLE: "tools" "Developer tools"
{ $subsection "tools.annotations" }
{ $subsection "tools.crossref" }
"Exploratory tools:"
{ $subsection "editor" }
{ $subsection "tools.crossref" }
{ $subsection "inspector" }
"Debugging tools:"
{ $subsection "tools.annotations" }
{ $subsection "tools.test" }
{ $subsection "meta-interpreter" }
"Performance tools:"
{ $subsection "tools.memory" }
{ $subsection "profiling" }
{ $subsection "tools.test" }
{ $subsection "timing" }
{ $subsection "tools.disassembler" }
"Deployment tools:"
{ $subsection "tools.deploy" } ;
ARTICLE: "article-index" "Article index"
@ -201,7 +206,6 @@ ARTICLE: "handbook" "Factor documentation"
{ $subsection "cookbook" }
{ $subsection "first-program" }
{ $subsection "vocab-index" }
{ $subsection "changes" }
{ $heading "Language reference" }
{ $subsection "conventions" }
{ $subsection "syntax" }
@ -231,137 +235,6 @@ ARTICLE: "handbook" "Factor documentation"
{ $subsection "type-index" }
{ $subsection "class-index" } ;
USING: io.files io.sockets float-arrays inference ;
ARTICLE: "changes" "Changes in the latest release"
{ $heading "Factor 0.91" }
{ $subheading "Performance" }
{ $list
{ "Continuations are now supported by the static stack effect system. This means that the " { $link infer } " word and the optimizing compiler now both support code which uses continuations." }
{ "Many words which previously ran in the interpreter, such as error handling and I/O, are now compiled to optimized machine code." }
{ "A non-optimizing, just-in-time compiler replaces the interpreter with no loss in functionality or introspective ability." }
{ "The non-optimizing compiler compiles quotations the first time they are called, generating a series of stack pushes and subroutine calls. It offers a 33%-50% performance increase over the interpreter." }
{ "The optimizing compiler now performs some more representation inference. Alien pointers are unboxed where possible. This improves performance of the " { $vocab-link "ogg.player" } " Ogg Theora video player." }
{ "The queue of sleeping tasks is now a sorted priority queue. This reduces overhead for workloads involving large numbers of sleeping threads (Doug Coleman)" }
{ "Improved hash code algorithm for sequences" }
{ "New, efficient implementations of " { $link bit? } " and " { $link log2 } " runs in constant time for large bignums" }
{ "New " { $link big-random } " word for generating large random numbers quickly" }
{ "Improved profiler no longer has to be explicitly enabled and disabled with a full recompile; instead, the " { $link profile } " word can be used at any time, and it dynamically patches words to increment call counts. There is no overhead when the profiler is not in use." }
{ "Calls to " { $link member? } " with a literal sequence are now open-coded. If there are four or fewer elements, a series of conditionals are generated; if there are more than four elements, there is a hash dispatch followed by conditionals in each branch." }
}
{ $subheading "IO" }
{ $list
{ "More robust Windows CE native I/O" }
{ "New " { $link os-envs } " word to get the current set of environment variables" }
{ "Redesigned " { $vocab-link "io.launcher" } " supports passing environment variables to the child process" }
{ { $link <process-stream> } " implemented on Windows (Doug Coleman)" }
{ "Updated " { $vocab-link "io.mmap" } " for new module system, now supports Windows CE (Doug Coleman)" }
{ { $vocab-link "io.sniffer" } " - packet sniffer library (Doug Coleman, Elie Chaftari)" }
{ { $vocab-link "io.server" } " - improved logging support, logs to a file by default" }
{ { $vocab-link "io.files" } " - several new file system manipulation words added" }
{ { $vocab-link "tar" } " - tar file extraction in pure Factor (Doug Coleman)" }
{ { $vocab-link "unix.linux" } ", " { $vocab-link "raptor" } " - ``Raptor Linux'', a set of alien bindings to low-level Linux features, such as network interface configuration, file system mounting/unmounting, etc, together with experimental boot scripts intended to entirely replace " { $snippet "/sbin/init" } ", " { $snippet "/etc/inittab" } " and " { $snippet "/etc/init.d/" } " (Eduardo Cavazos)." }
}
{ $subheading "Tools" }
{ $list
{ "Graphical deploy tool added - see " { $link "ui.tools.deploy" } }
{ "The deploy tool now supports Windows" }
{ { $vocab-link "network-clipboard" } " - clipboard synchronization with a simple TCP/IP protocol" }
}
{ $subheading "UI" }
{ $list
{ { $vocab-link "cairo" } " - updated for new module system, new features (Sampo Vuori)" }
{ { $vocab-link "springies" } " - physics simulation UI demo (Eduardo Cavazos)" }
{ { $vocab-link "ui.gadgets.buttons" } " - added check box and radio button gadgets" }
{ "Double- and triple-click-drag now supported in the editor gadget to select words or lines at a time" }
{ "Windows can be closed on request now using " { $link close-window } }
{ "New icons (Elie Chaftari)" }
}
{ $subheading "Libraries" }
{ $list
{ "The " { $snippet "queues" } " vocabulary has been removed because its functionality is a subset of " { $vocab-link "dlists" } }
{ "The " { $vocab-link "webapps.cgi" } " vocabulary implements CGI support for the Factor HTTP server." }
{ "The optimizing compiler no longer depends on the number tower and it is possible to bootstrap a minimal image by just passing " { $snippet "-include=compiler" } " to stage 2 bootstrap." }
{ { $vocab-link "benchmark.knucleotide" } " - new benchmark (Eric Mertens)" }
{ { $vocab-link "channels" } " - concurrent message passing over message channels" }
{ { $vocab-link "destructors" } " - deterministic scope-based resource deallocation (Doug Coleman)" }
{ { $vocab-link "dlists" } " - various updates (Doug Coleman)" }
{ { $vocab-link "editors.emeditor" } " - EmEditor integration (Doug Coleman)" }
{ { $vocab-link "editors.editplus" } " - EditPlus integration (Aaron Schaefer)" }
{ { $vocab-link "editors.notepadpp" } " - Notepad++ integration (Doug Coleman)" }
{ { $vocab-link "editors.ted-notepad" } " - TED Notepad integration (Doug Coleman)" }
{ { $vocab-link "editors.ultraedit" } " - UltraEdit integration (Doug Coleman)" }
{ { $vocab-link "globs" } " - simple Unix shell-style glob patterns" }
{ { $vocab-link "heaps" } " - updated for new module system and cleaned up (Doug Coleman)" }
{ { $vocab-link "peg" } " - Parser Expression Grammars, a new appoach to parser construction, similar to parser combinators (Chris Double)" }
{ { $vocab-link "regexp" } " - revived from " { $snippet "unmaintained/" } " and completely redesigned (Doug Coleman)" }
{ { $vocab-link "rss" } " - add Atom feed generation (Daniel Ehrenberg)" }
{ { $vocab-link "tuples.lib" } " - some utility words for working with tuples (Doug Coleman)" }
{ { $vocab-link "webapps.pastebin" } " - improved appearance, add Atom feed generation, add syntax highlighting using " { $vocab-link "xmode" } }
{ { $vocab-link "webapps.planet" } " - add Atom feed generation" }
}
{ $heading "Factor 0.90" }
{ $subheading "Core" }
{ $list
{ "New module system; see " { $link "vocabs.loader" } ". (Eduardo Cavazos)" }
{ "Tuple constructors are defined differently now; see " { $link "tuple-constructors" } "." }
{ "Mixin classes implemented; these are essentially extensible unions. See " { $link "mixins" } "." }
{ "New " { $link float-array } " data type implements a space-efficient sequence of floats." }
{ "Moved " { $link <file-appender> } ", " { $link delete-file } ", " { $link make-directory } ", " { $link delete-directory } " words from " { $snippet "libs/io" } " into the core, and fixed them to work on more platforms." }
{ "New " { $link host-name } " word." }
{ "The " { $link directory } " word now outputs an array of pairs, with the second element of each pair indicating if that entry is a subdirectory. This saves an unnecessary " { $link stat } " call when traversing directory hierarchies, which speeds things up." }
{ "IPv6 is now supported, along with Unix domain sockets (the latter on Unix systems only). The stack effects of " { $link <client> } " and " { $link <server> } " have changed, since they now take generic address specifiers; see " { $link "network-streams" } "." }
{ "The stage 2 bootstrap process is more flexible, and various subsystems such as help, tools and the UI can be omitted by supplying command line switches; see " { $link "bootstrap-cli-args" } "." }
{ "The " { $snippet "-shell" } " command line switch has been replaced by a " { $snippet "-run" } " command line switch; see " { $link "standard-cli-args" } "." }
{ "Variable usage inference has been removed; the " { $link infer } " word no longer reports this information." }
}
{ $subheading "Tools" }
{ $list
{ "Stand-alone image deployment; see " { $link "tools.deploy" } "." }
{ "Stand-alone application bundle deployment on Mac OS X; see " { $vocab-link "tools.deploy.app" } "." }
{ "New vocabulary browser tool in the UI." }
{ "New profiler tool in the UI." }
}
{ $subheading "Extras" }
"Most existing libraries were improved when ported to the new module system; the most notable changes include:"
{ $list
{ { $vocab-link "asn1" } ": ASN1 parser and writer. (Elie Chaftari)" }
{ { $vocab-link "benchmark" } ": new set of benchmarks." }
{ { $vocab-link "cfdg" } ": Context-free design grammar implementation; see " { $url "http://www.chriscoyne.com/cfdg/" } ". (Eduardo Cavazos)" }
{ { $vocab-link "cryptlib" } ": Cryptlib library binding. (Elie Chaftari)" }
{ { $vocab-link "cryptlib.streams" } ": Streams which perform SSL encryption and decryption. (Matthew Willis)" }
{ { $vocab-link "hints" } ": Give type specialization hints to the compiler." }
{ { $vocab-link "inverse" } ": Invertible computation and concatenative pattern matching. (Daniel Ehrenberg)" }
{ { $vocab-link "ldap" } ": OpenLDAP library binding. (Elie Chaftari)" }
{ { $vocab-link "locals" } ": Efficient lexically scoped locals, closures, and local words." }
{ { $vocab-link "mortar" } ": Experimental message-passing object system. (Eduardo Cavazos)" }
{ { $vocab-link "openssl" } ": OpenSSL library binding. (Elie Chaftari)" }
{ { $vocab-link "pack" } ": Utility for reading and writing binary data. (Doug Coleman)" }
{ { $vocab-link "pdf" } ": Haru PDF library binding. (Elie Chaftari)" }
{ { $vocab-link "qualified" } ": Refer to words from another vocabulary without adding the entire vocabulary to the search path. (Daniel Ehrenberg)" }
{ { $vocab-link "roman" } ": Reading and writing Roman numerals. (Doug Coleman)" }
{ { $vocab-link "scite" } ": SciTE editor integration. (Clemens Hofreither)" }
{ { $vocab-link "smtp" } ": SMTP client with support for CRAM-MD5 authentication. (Elie Chaftari, Dirk Vleugels)" }
{ { $vocab-link "tuple-arrays" } ": Space-efficient packed tuple arrays. (Daniel Ehrenberg)" }
{ { $vocab-link "unicode" } ": major new functionality added. (Daniel Ehrenberg)" }
}
{ $subheading "Performance" }
{ $list
{ "The " { $link curry } " word now runs in constant time, and curried quotations can be called from compiled code; this allows for abstractions and idioms which were previously impractical due to performance issues. In particular, words such as " { $snippet "each-with" } " and " { $snippet "map-with" } " are gone; " { $snippet "each-with" } " can now be written as " { $snippet "with each" } ", and similarly for other " { $snippet "-with" } " combinators." }
"Improved generational promotion strategy in garbage collector reduces the amount of junk which makes its way into tenured space, which in turn reduces the frequency of full garbage collections."
"Faster generic word dispatch and union membership testing."
{ "Alien memory accessors (" { $link "reading-writing-memory" } ") are compiled as intrinsics where possible, which improves performance in code which iteroperates with C libraries." }
}
{ $subheading "Platforms" }
{ $list
"Networking support added for Windows CE. (Doug Coleman)"
"UDP/IP networking support added for all Windows platforms. (Doug Coleman)"
"Solaris/x86 fixes. (Samuel Tardieu)"
"Linux/AMD64 port works again."
} ;
{ <array> <string> <sbuf> <vector> <byte-array> <bit-array> <float-array> }
related-words

View File

@ -2,7 +2,7 @@ USING: continuations destructors io.buffers io.files io.backend
io.timeouts io.nonblocking io.windows io.windows.nt.backend
kernel libc math threads windows windows.kernel32 alien.c-types
alien.arrays sequences combinators combinators.lib sequences.lib
ascii splitting alien strings ;
ascii splitting alien strings assocs ;
IN: io.windows.nt.files
M: windows-nt-io cwd
@ -60,7 +60,7 @@ M: windows-nt-io root-directory? ( path -- ? )
M: windows-nt-io normalize-pathname ( string -- string )
dup string? [ "pathname must be a string" throw ] unless
"/" split "\\" join
{ { CHAR: / CHAR: \\ } } substitute
cwd swap windows-path+
[ "/\\." member? ] right-trim
dup peek CHAR: : = [ "\\" append ] when ;

View File

@ -9,13 +9,10 @@ quotations promises combinators io ;
IN: lazy-lists
! Lazy List Protocol
MIXIN: list
GENERIC: car ( cons -- car )
GENERIC: cdr ( cons -- cdr )
GENERIC: nil? ( cons -- ? )
GENERIC: list? ( object -- ? )
M: object list? ( object -- bool )
drop f ;
M: promise car ( promise -- car )
force car ;
@ -26,9 +23,6 @@ M: promise cdr ( promise -- cdr )
M: promise nil? ( cons -- bool )
force nil? ;
M: promise list? ( object -- bool )
drop t ;
TUPLE: cons car cdr ;
C: cons cons
@ -45,9 +39,6 @@ M: cons cdr ( cons -- cdr )
M: cons nil? ( cons -- bool )
nil eq? ;
M: cons list? ( object -- bool )
drop t ;
: 1list ( obj -- cons )
nil cons ;
@ -74,9 +65,6 @@ M: lazy-cons cdr ( lazy-cons -- cdr )
M: lazy-cons nil? ( lazy-cons -- bool )
nil eq? ;
M: lazy-cons list? ( object -- bool )
drop t ;
: 1lazy-list ( a -- lazy-cons )
[ nil ] lazy-cons ;
@ -138,9 +126,6 @@ M: memoized-cons nil? ( memoized-cons -- bool )
memoized-cons-nil?
] if ;
M: memoized-cons list? ( object -- bool )
drop t ;
TUPLE: lazy-map cons quot ;
C: <lazy-map> lazy-map
@ -159,9 +144,6 @@ M: lazy-map cdr ( lazy-map -- cdr )
M: lazy-map nil? ( lazy-map -- bool )
lazy-map-cons nil? ;
M: lazy-map list? ( object -- bool )
drop t ;
TUPLE: lazy-map-with value cons quot ;
C: <lazy-map-with> lazy-map-with
@ -182,9 +164,6 @@ M: lazy-map-with cdr ( lazy-map-with -- cdr )
M: lazy-map-with nil? ( lazy-map-with -- bool )
lazy-map-with-cons nil? ;
M: lazy-map-with list? ( object -- bool )
drop t ;
TUPLE: lazy-take n cons ;
C: <lazy-take> lazy-take
@ -206,9 +185,6 @@ M: lazy-take nil? ( lazy-take -- bool )
lazy-take-cons nil?
] if ;
M: lazy-take list? ( object -- bool )
drop t ;
TUPLE: lazy-until cons quot ;
C: <lazy-until> lazy-until
@ -226,9 +202,6 @@ M: lazy-until cdr ( lazy-until -- cdr )
M: lazy-until nil? ( lazy-until -- bool )
drop f ;
M: lazy-until list? ( lazy-until -- bool )
drop t ;
TUPLE: lazy-while cons quot ;
C: <lazy-while> lazy-while
@ -245,9 +218,6 @@ M: lazy-while cdr ( lazy-while -- cdr )
M: lazy-while nil? ( lazy-while -- bool )
[ car ] keep lazy-while-quot call not ;
M: lazy-while list? ( lazy-while -- bool )
drop t ;
TUPLE: lazy-subset cons quot ;
C: <lazy-subset> lazy-subset
@ -285,9 +255,6 @@ M: lazy-subset nil? ( lazy-subset -- bool )
] if
] if ;
M: lazy-subset list? ( object -- bool )
drop t ;
: list>vector ( list -- vector )
[ [ , ] leach ] V{ } make ;
@ -311,9 +278,6 @@ M: lazy-append cdr ( lazy-append -- cdr )
M: lazy-append nil? ( lazy-append -- bool )
drop f ;
M: lazy-append list? ( object -- bool )
drop t ;
TUPLE: lazy-from-by n quot ;
C: lfrom-by lazy-from-by ( n quot -- list )
@ -331,9 +295,6 @@ M: lazy-from-by cdr ( lazy-from-by -- cdr )
M: lazy-from-by nil? ( lazy-from-by -- bool )
drop f ;
M: lazy-from-by list? ( object -- bool )
drop t ;
TUPLE: lazy-zip list1 list2 ;
C: <lazy-zip> lazy-zip
@ -351,9 +312,6 @@ M: lazy-zip cdr ( lazy-zip -- cdr )
M: lazy-zip nil? ( lazy-zip -- bool )
drop f ;
M: lazy-zip list? ( object -- bool )
drop t ;
TUPLE: sequence-cons index seq ;
C: <sequence-cons> sequence-cons
@ -376,9 +334,6 @@ M: sequence-cons cdr ( sequence-cons -- cdr )
M: sequence-cons nil? ( sequence-cons -- bool )
drop f ;
M: sequence-cons list? ( object -- bool )
drop t ;
: >list ( object -- list )
{
{ [ dup sequence? ] [ 0 swap seq>list ] }
@ -419,9 +374,6 @@ M: lazy-concat nil? ( lazy-concat -- bool )
drop f
] if ;
M: lazy-concat list? ( object -- bool )
drop t ;
: lcartesian-product ( list1 list2 -- result )
swap [ swap [ 2array ] lmap-with ] lmap-with lconcat ;
@ -492,3 +444,20 @@ M: lazy-io cdr ( lazy-io -- cdr )
M: lazy-io nil? ( lazy-io -- bool )
car not ;
INSTANCE: cons list
INSTANCE: sequence-cons list
INSTANCE: memoized-cons list
INSTANCE: promise list
INSTANCE: lazy-io list
INSTANCE: lazy-concat list
INSTANCE: lazy-cons list
INSTANCE: lazy-map list
INSTANCE: lazy-map-with list
INSTANCE: lazy-take list
INSTANCE: lazy-append list
INSTANCE: lazy-from-by list
INSTANCE: lazy-zip list
INSTANCE: lazy-while list
INSTANCE: lazy-until list
INSTANCE: lazy-subset list

View File

@ -4,7 +4,7 @@ USING: classes inference inference.dataflow io kernel
kernel.private math.parser namespaces optimizer prettyprint
prettyprint.backend sequences words arrays match macros
assocs sequences.private optimizer.specializers generic
combinators sorting math ;
combinators sorting math quotations ;
IN: optimizer.debugger
! A simple tool for turning dataflow IR into quotations, for
@ -67,7 +67,7 @@ M: #shuffle node>quot
[ , ] [ >r drop t r> ] if*
dup effect-str "#shuffle: " swap append comment, ;
: pushed-literals node-out-d [ value-literal ] map ;
: pushed-literals node-out-d [ value-literal literalize ] map ;
M: #push node>quot nip pushed-literals % ;
@ -83,6 +83,7 @@ M: #call-label node>quot #call>quot ;
M: #label node>quot
[
dup node-param literalize ,
dup #label-loop? "#loop: " "#label: " ?
over node-param word-name append comment,
] 2keep

View File

@ -0,0 +1,28 @@
IN: optimizer.report
USING: assocs words sequences arrays compiler tools.time
io.styles io prettyprint vocabs kernel sorting generator
optimizer ;
: count-optimization-passes ( nodes n -- n )
>r optimize-1
[ r> 1+ count-optimization-passes ] [ drop r> ] if ;
: word-table
[ [ second ] swap compose compare ] curry sort 20 tail*
print
standard-table-style
[
[ [ [ pprint-cell ] each ] with-row ] each
] tabular-output ;
: optimizer-report
all-words [ compiled? ] subset
[
dup [
word-dataflow nip 1 count-optimization-passes
] benchmark nip 2array
] { } map>assoc
[ first ] "Worst number of optimizer passes:" results
[ second ] "Worst compile times:" results ;
MAIN: optimizer-report

View File

@ -205,6 +205,3 @@ PRIVATE>
: attempt-each ( seq quot -- result )
(each) iterate-prep (attempt-each-integer) ; inline
: replace ( seq old new -- newseq )
[ pick pick = [ 2nip ] [ 2drop ] if ] 2curry map ;

View File

@ -0,0 +1,13 @@
IN: tools.disassembler
USING: help.markup help.syntax sequences.private ;
HELP: disassemble
{ $values { "obj" "a word or a pair of addresses" } }
{ $description "Disassembles either a compiled word definition or an arbitrary memory range (in the case " { $snippet "obj" } " is a pair of integers) by attaching " { $snippet "gdb" } " to the Factor VM and capturing the output." }
{ $notes "In some cases the Factor compiler emits data inline with code, which can confuse " { $snippet "gdb" } ". This occurs in words which call " { $link dispatch } ", where the jump table addresses are compiled inline. Also on the ARM architecture, various pointers are often compiled inline, and the preceeding instruction jumps over the inline pinter." } ;
ARTICLE: "tools.disassembler" "Disassembling words"
"The " { $vocab-link "tools.disassembler" } " vocabulary integrates Factor with the GNU debugger (" { $snippet "gdb" } ") for viewing the assembly code generated by the compiler. It can be used on both Unix and Windows as long as a working copy of " { $snippet "gdb" } " is installed and available in the " { $snippet "PATH" } "."
{ $subsection disassemble } ;
ABOUT: "tools.disassembler"

11
extra/tools/disassembler/disassembler.factor Normal file → Executable file
View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: io.files io words alien kernel math.parser alien.syntax
io.launcher system assocs arrays sequences namespaces qualified
regexp system math sequences.lib windows.kernel32 ;
system math windows.kernel32 generator.fixup ;
IN: tools.disassembler
: in-file "gdb-in.txt" resource-path ;
@ -12,7 +12,7 @@ IN: tools.disassembler
GENERIC: make-disassemble-cmd ( obj -- )
M: word make-disassemble-cmd
word-xt cell - 2array make-disassemble-cmd ;
word-xt code-format - 2array make-disassemble-cmd ;
M: pair make-disassemble-cmd
in-file [
@ -30,12 +30,9 @@ M: pair make-disassemble-cmd
] { } make-assoc run-process drop
out-file file-lines ;
: relevant? ( line -- ? )
R/ 0x.*:.*/ matches? ;
: tabs>spaces ( str -- str' )
CHAR: \t CHAR: \s replace ;
{ { CHAR: \t CHAR: \s } } substitute ;
: disassemble ( word -- )
make-disassemble-cmd run-gdb
[ relevant? ] subset [ tabs>spaces ] map [ print ] each ;
[ tabs>spaces ] map [ print ] each ;

2
extra/tools/memory/memory-docs.factor Normal file → Executable file
View File

@ -17,7 +17,7 @@ ARTICLE: "tools.memory" "Object memory tools"
"The garbage collector can be invoked manually:"
{ $subsection data-gc }
{ $subsection code-gc }
{ $see-also "image" } ;
{ $see-also "images" } ;
ABOUT: "tools.memory"

View File

@ -51,7 +51,7 @@ GENERIC: command-word ( command -- word )
update-gestures ;
: (command-name) ( string -- newstring )
"-" split " " join >title ;
{ { CHAR: - CHAR: \s } } substitute >title ;
M: word command-name ( word -- str )
word-name

15
extra/unicode/data/data.factor Normal file → Executable file
View File

@ -1,7 +1,6 @@
USING: assocs math kernel sequences sequences.lib io.files
hashtables quotations splitting arrays math.parser
combinators.lib hash2 byte-arrays words namespaces words
compiler.units parser ;
USING: assocs math kernel sequences io.files hashtables
quotations splitting arrays math.parser combinators.lib hash2
byte-arrays words namespaces words compiler.units parser ;
IN: unicode.data
<<
@ -68,7 +67,7 @@ IN: unicode.data
: process-combining ( data -- hash )
3 swap (process-data)
[ string>number ] assoc-map
[ nip 0 = not ] assoc-subset
[ nip zero? not ] assoc-subset
>hashtable ;
: categories ( -- names )
@ -95,9 +94,9 @@ IN: unicode.data
[ dup CHAR: A CHAR: Z between? [ HEX: 20 + ] when ] map ;
: process-names ( data -- names-hash )
1 swap (process-data)
[ ascii-lower CHAR: \s CHAR: - replace swap ] assoc-map
>hashtable ;
1 swap (process-data) [
ascii-lower { { CHAR: \s CHAR: - } } substitute swap
] assoc-map >hashtable ;
: multihex ( hexstring -- string )
" " split [ hex> ] map [ ] subset ;

View File

@ -1,4 +0,0 @@
USING: unicode.syntax tools.test ;
[ CHAR: ! ] [ UNICHAR: exclamation-mark ] unit-test
! Write a test for CATEGORY and CATEGORY-NOT

4
extra/unicode/syntax/syntax.factor Normal file → Executable file
View File

@ -46,7 +46,3 @@ IN: unicode.syntax
: CATEGORY-NOT:
CREATE ";" parse-tokens
categories swap seq-minus define-category ; parsing
: UNICHAR:
! This should be part of CHAR:. Also, name-map at ==> name>char
scan name>char [ parsed ] [ "Invalid character" throw ] if* ; parsing

View File

@ -1,5 +1,9 @@
USING: unicode.syntax unicode.data unicode.breaks unicode.normalize
unicode.case unicode.categories ;
USING: unicode.syntax unicode.data unicode.breaks
unicode.normalize unicode.case unicode.categories
parser kernel namespaces ;
IN: unicode
! For now: convenience to load all Unicode vocabs
[ name>char [ "Invalid character" throw ] unless* ]
name>char-hook set-global