H{ } clone update-map set
! Builtin classes
-: builtin-predicate ( class predicate -- )
+: builtin-predicate-quot ( class -- quot )
[
- over "type" word-prop dup
+ "type" word-prop dup
\ tag-mask get < \ tag \ type ? , , \ eq? ,
- ] [ ] make define-predicate* ;
+ ] [ ] make ;
-: register-builtin ( class -- )
- dup "type" word-prop builtins get set-nth ;
+: define-builtin-predicate ( class -- )
+ dup
+ dup builtin-predicate-quot define-predicate
+ predicate-word make-inline ;
: lookup-type-number ( word -- n )
global [ target-word ] bind type-number ;
-: define-builtin ( symbol predicate slotspec -- )
- >r dup make-inline >r
- dup dup lookup-type-number "type" set-word-prop
+: register-builtin ( class -- )
+ dup
+ dup lookup-type-number "type" set-word-prop
+ dup "type" word-prop builtins get set-nth ;
+
+: define-builtin-slots ( symbol slotspec -- )
+ dupd 1 simple-slots
+ 2dup "slots" set-word-prop
+ define-slots ;
+
+: define-builtin ( symbol slotspec -- )
+ >r
+ dup register-builtin
dup f f builtin-class define-class
- dup r> builtin-predicate
- dup r> 1 simple-slots 2dup "slots" set-word-prop
- dupd define-slots
- register-builtin ;
+ dup define-builtin-predicate
+ r> define-builtin-slots ;
H{ } clone typemap set
num-types get f <array> builtins set
"null" "kernel" create drop
-"fixnum" "math" create "fixnum?" "math" create { } define-builtin
+"fixnum" "math" create { } define-builtin
"fixnum" "math" create ">fixnum" "math" create 1quotation "coercer" set-word-prop
-"bignum" "math" create "bignum?" "math" create { } define-builtin
+"bignum" "math" create { } define-builtin
"bignum" "math" create ">bignum" "math" create 1quotation "coercer" set-word-prop
-"tuple" "kernel" create "tuple?" "kernel" create
-{ } define-builtin
+"tuple" "kernel" create { } define-builtin
-"ratio" "math" create "ratio?" "math" create
-{
+"ratio" "math" create {
{
{ "integer" "math" }
"numerator"
}
} define-builtin
-"float" "math" create "float?" "math" create { } define-builtin
+"float" "math" create { } define-builtin
"float" "math" create ">float" "math" create 1quotation "coercer" set-word-prop
-"complex" "math" create "complex?" "math" create
-{
+"complex" "math" create {
{
{ "real" "math" }
"real-part"
}
} define-builtin
-"f" "syntax" lookup "not" "kernel" create
-{ } define-builtin
+"f" "syntax" lookup { } define-builtin
-"array" "arrays" create "array?" "arrays" create
-{ } define-builtin
+! do not word...
-"wrapper" "kernel" create "wrapper?" "kernel" create
-{
+"array" "arrays" create { } define-builtin
+
+"wrapper" "kernel" create {
{
{ "object" "kernel" }
"wrapped"
}
} define-builtin
-"string" "strings" create "string?" "strings" create
-{
+"string" "strings" create {
{
{ "array-capacity" "sequences.private" }
"length"
}
} define-builtin
-"quotation" "quotations" create "quotation?" "quotations" create
-{
+"quotation" "quotations" create {
{
{ "object" "kernel" }
"array"
}
} define-builtin
-"dll" "alien" create "dll?" "alien" create
-{
+"dll" "alien" create {
{
{ "byte-array" "byte-arrays" }
"path"
}
define-builtin
-"alien" "alien" create "alien?" "alien" create
-{
+"alien" "alien" create {
{
{ "c-ptr" "alien" }
"alien"
}
define-builtin
-"word" "words" create "word?" "words" create
-{
+"word" "words" create {
f
{
{ "object" "kernel" }
}
} define-builtin
-"byte-array" "byte-arrays" create
-"byte-array?" "byte-arrays" create
-{ } define-builtin
+"byte-array" "byte-arrays" create { } define-builtin
-"bit-array" "bit-arrays" create
-"bit-array?" "bit-arrays" create
-{ } define-builtin
+"bit-array" "bit-arrays" create { } define-builtin
-"float-array" "float-arrays" create
-"float-array?" "float-arrays" create
-{ } define-builtin
+"float-array" "float-arrays" create { } define-builtin
-"callstack" "kernel" create "callstack?" "kernel" create
-{ } define-builtin
+"callstack" "kernel" create { } define-builtin
! Define general-t type, which is any object that is not f.
"general-t" "kernel" create
"f" "syntax" lookup builtins get remove [ ] subset f union-class
define-class
+"f" "syntax" create [ not ] "predicate" set-word-prop
+"f?" "syntax" create "syntax" vocab-words delete-at
+
+"general-t" "kernel" create [ ] "predicate" set-word-prop
+"general-t?" "kernel" create "syntax" vocab-words delete-at
+
! Catch-all class for providing a default method.
"object" "kernel" create [ drop t ] "predicate" set-word-prop
"object" "kernel" create
USING: help.markup help.syntax kernel kernel.private
namespaces sequences words arrays layouts help effects math
layouts classes.private classes.union classes.mixin
-classes.predicate ;
+classes.predicate quotations ;
IN: classes
ARTICLE: "builtin-classes" "Built-in classes"
{ $values { "word" "a word" } { "predicate" "a predicate word" } }
{ $description "Suffixes the word's name with \"?\" and creates a word with that name in the same vocabulary as the word itself." } ;
-HELP: define-predicate*
-{ $values { "class" class } { "predicate" "a predicate word" } { "quot" "a quotation" } }
-{ $description
- "Defines a predicate word. This is identical to a word definition associating " { $snippet "quot" } " with " { $snippet "predicate" } " with the added perk that three word properties are set:"
- { $list
- { "the class word's " { $snippet "\"predicate\"" } " property is set to a quotation that calls the predicate" }
- { "the predicate word's " { $snippet "\"predicating\"" } " property is set to the class word" }
- { "the predicate word's " { $snippet "\"declared-effect\"" } " word property is set to a descriptive " { $link effect } }
- }
- "These properties are used by method dispatch and the help system."
-}
-$low-level-note ;
-
HELP: define-predicate
-{ $values { "class" class } { "quot" "a quotation" } }
-{ $description
- "Defines a predicate word named " { $snippet "class?" } " with " { $link define-predicate* } "."
-}
+{ $values { "class" class } { "quot" quotation } }
+{ $description "Defines a predicate word for a class." }
$low-level-note ;
HELP: superclass
[ f ] [ forget-class-bug-2 typemap get values [ memq? ] with contains? ] unit-test
-DEFER: mixin-forget-test-g
-
-[ "mixin-forget-test" forget-source ] with-compilation-unit
-
-[ ] [
- {
- "USING: sequences ;"
- "IN: classes.tests"
- "MIXIN: mixin-forget-test"
- "INSTANCE: sequence mixin-forget-test"
- "GENERIC: mixin-forget-test-g ( x -- y )"
- "M: mixin-forget-test mixin-forget-test-g ;"
- } "\n" join <string-reader> "mixin-forget-test"
- parse-stream drop
-] unit-test
-
-[ { } ] [ { } mixin-forget-test-g ] unit-test
-[ H{ } mixin-forget-test-g ] must-fail
-
-[ ] [
- {
- "USING: hashtables ;"
- "IN: classes.tests"
- "MIXIN: mixin-forget-test"
- "INSTANCE: hashtable mixin-forget-test"
- "GENERIC: mixin-forget-test-g ( x -- y )"
- "M: mixin-forget-test mixin-forget-test-g ;"
- } "\n" join <string-reader> "mixin-forget-test"
- parse-stream drop
-] unit-test
-
-[ { } mixin-forget-test-g ] must-fail
-[ H{ } ] [ H{ } mixin-forget-test-g ] unit-test
+2 [
+ [ "mixin-forget-test" forget-source ] with-compilation-unit
+
+ [ ] [
+ {
+ "USING: sequences ;"
+ "IN: classes.tests"
+ "MIXIN: mixin-forget-test"
+ "INSTANCE: sequence mixin-forget-test"
+ "GENERIC: mixin-forget-test-g ( x -- y )"
+ "M: mixin-forget-test mixin-forget-test-g ;"
+ } "\n" join <string-reader> "mixin-forget-test"
+ parse-stream drop
+ ] unit-test
+
+ [ { } ] [ { } "mixin-forget-test-g" "classes.tests" lookup execute ] unit-test
+ [ H{ } "mixin-forget-test-g" "classes.tests" lookup execute ] must-fail
+
+ [ ] [
+ {
+ "USING: hashtables ;"
+ "IN: classes.tests"
+ "MIXIN: mixin-forget-test"
+ "INSTANCE: hashtable mixin-forget-test"
+ "GENERIC: mixin-forget-test-g ( x -- y )"
+ "M: mixin-forget-test mixin-forget-test-g ;"
+ } "\n" join <string-reader> "mixin-forget-test"
+ parse-stream drop
+ ] unit-test
+
+ [ { } "mixin-forget-test-g" "classes.tests" lookup execute ] must-fail
+ [ H{ } ] [ H{ } "mixin-forget-test-g" "classes.tests" lookup execute ] unit-test
+] times
! Method flattening interfered with mixin update
MIXIN: flat-mx-1
PREDICATE: word predicate "predicating" word-prop >boolean ;
-: define-predicate* ( class predicate quot -- )
- over [
- dupd predicate-effect define-declared
- 2dup 1quotation "predicate" set-word-prop
- swap "predicating" set-word-prop
- ] [ 3drop ] if ;
-
: define-predicate ( class quot -- )
- over "forgotten" word-prop [ 2drop ] [
- >r dup predicate-word r> define-predicate*
- ] if ;
+ >r "predicate" word-prop first
+ r> predicate-effect define-declared ;
: superclass ( class -- super )
"superclass" word-prop ;
over reset-class
over deferred? [ over define-symbol ] when
>r dup word-props r> union over set-word-props
+ dup predicate-word 2dup 1quotation "predicate" set-word-prop
+ over "predicating" set-word-prop
t "class" set-word-prop ;
GENERIC: update-predicate ( class -- )
{ $subsection :errors }
{ $subsection :warnings }
{ $subsection :linkage }
-"Words such as " { $link require } " and " { $link refresh-all } " use a combinator which counts errors and prints a report at the end:"
+"Words such as " { $link require } " use a combinator which counts errors and prints a report at the end:"
{ $link with-compiler-errors } ;
HELP: compiler-errors
cpu.x86.architecture cpu.x86.intrinsics cpu.x86.sse2
cpu.x86.allot cpu.architecture kernel kernel.private math
namespaces sequences generator.registers generator.fixup system
-alien alien.accessors alien.compiler alien.structs slots
+layouts alien alien.accessors alien.compiler alien.structs slots
splitting assocs ;
IN: cpu.x86.64
USING: help.markup help.syntax io io.styles strings
-io.backend io.files.private quotations ;
+ io.backend io.files.private quotations ;
IN: io.files
ARTICLE: "file-streams" "Reading and writing files"
{ $subsection make-directory }
{ $subsection make-directories } ;
+! ARTICLE: "file-types" "File Types"
+
+! { $table { +directory+ "" } }
+
+! ;
+
ARTICLE: "fs-meta" "File meta-data"
+
+{ $subsection file-info }
+{ $subsection link-info }
{ $subsection exists? }
{ $subsection directory? }
-{ $subsection file-length }
-{ $subsection file-modified }
+! { $subsection file-modified }
{ $subsection stat } ;
ARTICLE: "delete-move-copy" "Deleting, moving, copying files"
{ $example "USING: io.files prettyprint ;" "\"/usr/libexec/awk/\" file-name ." "\"awk\"" }
} ;
+! need a $class-description file-info
+
+HELP: file-info
+
+ { $values { "path" "a pathname string" }
+ { "info" file-info } }
+ { $description "Queries the file system for meta data. "
+ "If path refers to a symbolic link, it is followed."
+ "If the file does not exist, an exception is thrown." }
+
+ { $class-description "File meta data" }
+
+ { $table
+ { "type" { "One of the following:"
+ { $list { $link +regular-file+ }
+ { $link +directory+ }
+ { $link +symbolic-link+ } } } }
+
+ { "size" "Size of the file in bytes" }
+ { "modified" "Last modification timestamp." } }
+
+ ;
+
+! need a see also to link-info
+
+HELP: link-info
+ { $values { "path" "a pathname string" }
+ { "info" "a file-info tuple" } }
+ { $description "Queries the file system for meta data. "
+ "If path refers to a symbolic link, information about "
+ "the symbolic link itself is returned."
+ "If the file does not exist, an exception is thrown." } ;
+! need a see also to file-info
+
+{ file-info link-info } related-words
+
HELP: <file-reader>
{ $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" { "stream" "an input stream" } }
{ "stream" "an input stream" } }
"Queries the file system for file meta data. If the file does not exist, outputs " { $link f } " for all four values."
} ;
-{ stat exists? directory? file-length file-modified } related-words
+{ stat exists? directory? } related-words
HELP: path+
{ $values { "str1" "a string" } { "str2" "a string" } { "str" "a string" } }
{ $description "Outputs the contents of a directory named by " { $snippet "path" } "." }
{ $notes "Unlike " { $link directory } ", this word prepends the directory's path to all file names in the list." } ;
-HELP: file-length
-{ $values { "path" "a pathname string" } { "n" "a non-negative integer or " { $link f } } }
-{ $description "Outputs the length of the file in bytes, or " { $link f } " if it does not exist." } ;
-
-HELP: file-modified
-{ $values { "path" "a pathname string" } { "n" "a non-negative integer or " { $link f } } }
-{ $description "Outputs a file's last modification time, since midnight January 1, 1970. If the file does not exist, outputs " { $link f } "." } ;
+! HELP: file-modified
+! { $values { "path" "a pathname string" } { "n" "a non-negative integer or " { $link f } } }
+! { $description "Outputs a file's last modification time, since midnight January 1, 1970. If the file does not exist, outputs " { $link f } "." } ;
HELP: resource-path
{ $values { "path" "a pathname string" } { "newpath" "a pathname string" } }
: stat ( path -- directory? permissions length modified )
normalize-pathname (stat) ;
-: file-length ( path -- n ) stat drop 2nip ;
+! : file-length ( path -- n ) stat drop 2nip ;
: file-modified ( path -- n ) stat >r 3drop r> ;
-: file-permissions ( path -- perm ) stat 2drop nip ;
+! : file-permissions ( path -- perm ) stat 2drop nip ;
: exists? ( path -- ? ) file-modified >boolean ;
>r <file-reader> r> with-stream ; inline
: file-contents ( path encoding -- str )
- dupd [ file-length read ] with-file-reader ;
+ dupd [ file-info file-info-size read ] with-file-reader ;
+
+! : file-contents ( path encoding -- str )
+! dupd [ file-length read ] with-file-reader ;
: with-file-writer ( path encoding quot -- )
>r <file-writer> r> with-stream ; inline
[ "resource:core/parser/test/assert-depth.factor" run-file ]
[ relative-overflow-stack { 1 2 3 } sequence= ]
must-fail-with
+
+2 [
+ [ ] [
+ "IN: parser.tests DEFER: d-f-s d-f-s SYMBOL: d-f-s d-f-s"
+ <string-reader> "d-f-s-test" parse-stream drop
+ ] unit-test
+
+ [ ] [
+ "IN: parser.tests DEFER: d-f-s d-f-s FORGET: d-f-s SYMBOL: d-f-s d-f-s"
+ <string-reader> "d-f-s-test" parse-stream drop
+ ] unit-test
+
+ [ ] [
+ "IN: parser.tests DEFER: d-f-s d-f-s SYMBOL: d-f-s d-f-s"
+ <string-reader> "d-f-s-test" parse-stream drop
+ ] unit-test
+] times
"tools.test"
"tools.threads"
"tools.time"
+ "tools.vocabs"
"vocabs"
"vocabs.loader"
"words"
: finish-parsing ( lines quot -- )
file get
[ record-form ] keep
- [ record-modified ] keep
[ record-definitions ] keep
record-checksum ;
IN: source-files
ARTICLE: "source-files" "Source files"
-"Words in the " { $vocab-link "source-files" } " vocabulary are used to keep track of loaded source files. This is used to implement features such as " { $link refresh-all } "."
+"Words in the " { $vocab-link "source-files" } " vocabulary are used to keep track of loaded source files. This is used to implement " { $link "tools.vocabs" } "."
$nl
"The source file database:"
{ $subsection source-files }
"The class of source files:"
{ $subsection source-file }
-"Testing if a source file has been changed on disk:"
-{ $subsection source-modified? }
"Words intended for the parser:"
-{ $subsection record-modified }
{ $subsection record-checksum }
{ $subsection record-form }
{ $subsection xref-source }
{ $class-description "Instances retain information about loaded source files, and have the following slots:"
{ $list
{ { $link source-file-path } " - a pathname string." }
- { { $link source-file-modified } " - the result of " { $link file-modified } " at the time the source file was most recently loaded." }
{ { $link source-file-checksum } " - the CRC32 checksum of the source file's contents at the time it was most recently loaded." }
{ { $link source-file-uses } " - an assoc whose keys are words referenced from this source file's top level form." }
{ { $link source-file-definitions } " - a pair of assocs, containing definitions and classes defined in this source file, respectively" }
}
} ;
-HELP: source-modified?
-{ $values { "path" "a pathname string" } { "?" "a boolean" } }
-{ $description "Tests if the source file has been modified since it was last loaded. This compares the file's modification time and CRC32 checksum of the file's contents against previously-recorded values." } ;
-
-HELP: record-modified
-{ $values { "source-file" source-file } }
-{ $description "Records the modification time of the source file." }
-$low-level-note ;
-
HELP: record-checksum
{ $values { "source-file" source-file } { "lines" "a sequence of strings" } }
{ $description "Records the CRC32 checksm of the source file's contents." }
$low-level-note ;
HELP: reset-checksums
-{ $description "Resets recorded modification times and CRC32 checksums for all loaded source files, creating a checkpoint for " { $link refresh } "." } ;
+{ $description "Resets recorded modification times and CRC32 checksums for all loaded source files, creating a checkpoint for " { $link "tools.vocabs" } "." } ;
HELP: forget-source
{ $values { "path" "a pathname string" } }
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: arrays definitions generic assocs kernel math
-namespaces prettyprint sequences strings vectors words
-quotations inspector io.styles io combinators sorting
-splitting math.parser effects continuations debugger
-io.files io.crc32 io.streams.string vocabs
-hashtables graphs compiler.units io.encodings.utf8 ;
+USING: arrays definitions generic assocs kernel math namespaces
+prettyprint sequences strings vectors words quotations inspector
+io.styles io combinators sorting splitting math.parser effects
+continuations debugger io.files io.crc32 vocabs hashtables
+graphs compiler.units io.encodings.utf8 ;
IN: source-files
SYMBOL: source-files
TUPLE: source-file
path
-modified checksum
+checksum
uses definitions ;
-: (source-modified?) ( path modified checksum -- ? )
- pick file-modified rot [ 0 or ] 2apply >
- [ swap utf8 file-lines lines-crc32 = not ] [ 2drop f ] if ;
-
-: source-modified? ( path -- ? )
- dup source-files get at [
- dup source-file-path ?resource-path
- over source-file-modified
- rot source-file-checksum
- (source-modified?)
- ] [
- resource-exists?
- ] ?if ;
-
-: record-modified ( source-file -- )
- dup source-file-path ?resource-path file-modified
- swap set-source-file-modified ;
-
: record-checksum ( lines source-file -- )
- swap lines-crc32 swap set-source-file-checksum ;
+ >r lines-crc32 r> set-source-file-checksum ;
: (xref-source) ( source-file -- pathname uses )
- dup source-file-path <pathname> swap source-file-uses
- [ crossref? ] subset ;
+ dup source-file-path <pathname>
+ swap source-file-uses [ crossref? ] subset ;
: xref-source ( source-file -- )
(xref-source) crossref get add-vertex ;
: reset-checksums ( -- )
source-files get [
- swap ?resource-path dup exists?
- [
- over record-modified
+ swap ?resource-path dup exists? [
utf8 file-lines swap record-checksum
] [ 2drop ] if
] assoc-each ;
"Application vocabularies can define a main entry point, giving the user a convenient way to run the application:"
{ $subsection POSTPONE: MAIN: }
{ $subsection run }
-"Reloading source files changed on disk:"
-{ $subsection refresh }
-{ $subsection refresh-all }
{ $see-also "vocabularies" "parser-files" "source-files" } ;
ABOUT: "vocabs.loader"
HELP: vocab-roots
{ $var-description "A sequence of pathname strings to search for vocabularies." } ;
-HELP: vocab-tests
-{ $values { "vocab" "a vocabulary specifier" } { "tests" "a sequence of pathname strings" } }
-{ $description "Outputs a sequence of pathnames where the unit tests for " { $snippet "vocab" } " are located." } ;
-
HELP: find-vocab-root
{ $values { "vocab" "a vocabulary specifier" } { "path/f" "a pathname string" } }
{ $description "Searches for a vocabulary in the vocabulary roots." } ;
{ vocab-root find-vocab-root } related-words
-HELP: vocab-files
-{ $values { "vocab" "a vocabulary specifier" } { "seq" "a sequence of pathname strings" } }
-{ $description "Outputs a sequence of files comprising this vocabulary, or " { $link f } " if the vocabulary does not have a directory on disk." } ;
-
HELP: no-vocab
{ $values { "name" "a vocabulary name" } }
{ $description "Throws a " { $link no-vocab } "." }
HELP: require
{ $values { "vocab" "a vocabulary specifier" } }
{ $description "Loads a vocabulary if it has not already been loaded." }
-{ $notes "To unconditionally reload a vocabulary, use " { $link reload } ". To reload changed source files, use " { $link refresh } " or " { $link refresh-all } "." } ;
+{ $notes "To unconditionally reload a vocabulary, use " { $link reload } ". To reload changed source files only, use the words in " { $link "tools.vocabs" } "." } ;
HELP: run
{ $values { "vocab" "a vocabulary specifier" } }
HELP: vocab-docs-path
{ $values { "vocab" "a vocabulary specifier" } { "path/f" "a pathname string or " { $link f } } }
{ $description "Outputs a pathname where the documentation for " { $snippet "vocab" } " might be found. Outputs " { $link f } " if the vocabulary does not have a directory on disk." } ;
-
-HELP: refresh
-{ $values { "prefix" string } }
-{ $description "Reloads source files and documentation belonging to loaded vocabularies whose names are prefixed by " { $snippet "prefix" } " which have been modified on disk." } ;
-
-HELP: refresh-all
-{ $description "Reloads source files and documentation for all loaded vocabularies which have been modified on disk." } ;
-
-{ refresh refresh-all } related-words
USING: vocabs.loader tools.test continuations vocabs math
kernel arrays sequences namespaces io.streams.string
parser source-files words assocs tuples definitions
-debugger compiler.units ;
+debugger compiler.units tools.vocabs ;
! This vocab should not exist, but just in case...
[ ] [
M: vocab-link vocab-root
vocab-link-root ;
-: vocab-tests ( vocab -- tests )
- dup vocab-root [
- [
- f >vocab-link dup
-
- dup "-tests.factor" vocab-dir+ vocab-path+
- dup resource-exists? [ , ] [ drop ] if
-
- dup vocab-dir "tests" path+ vocab-path+ dup
- ?resource-path directory keys [ ".factor" tail? ] subset
- [ path+ , ] with each
- ] { } make
- ] [ drop f ] if ;
-
-: vocab-files ( vocab -- seq )
- f >vocab-link [
- dup vocab-source-path [ , ] when*
- dup vocab-docs-path [ , ] when*
- vocab-tests %
- ] { } make ;
-
SYMBOL: load-help?
: source-was-loaded t swap set-vocab-source-loaded? ;
"To define one, refer to \\ MAIN: help" print
] ?if ;
-: modified ( seq quot -- seq )
- [ dup ] swap compose { } map>assoc
- [ nip ] assoc-subset
- [ nip source-modified? ] assoc-subset keys ; inline
-
-: modified-sources ( vocabs -- seq )
- [ vocab-source-path ] modified ;
-
-: modified-docs ( vocabs -- seq )
- [ vocab-docs-path ] modified ;
-
-: update-roots ( vocabs -- )
- [ dup find-vocab-root swap vocab set-vocab-root ] each ;
-
-: to-refresh ( prefix -- modified-sources modified-docs )
- child-vocabs
- dup update-roots
- dup modified-sources swap modified-docs ;
-
-: vocab-heading. ( vocab -- )
- nl
- "==== " write
- dup vocab-name swap vocab write-object ":" print
- nl ;
-
-: load-error. ( triple -- )
- dup first vocab-heading.
- dup second print-error
- drop ;
-
-: load-failures. ( failures -- )
- [ load-error. nl ] each ;
-
SYMBOL: blacklist
-SYMBOL: failures
-
-: require-all ( vocabs -- failures )
- [
- V{ } clone blacklist set
- V{ } clone failures set
- [
- [ require ]
- [ swap vocab-name failures get set-at ]
- recover
- ] each
- failures get
- ] with-compiler-errors ;
-
-: do-refresh ( modified-sources modified-docs -- )
- 2dup
- [ f swap set-vocab-docs-loaded? ] each
- [ f swap set-vocab-source-loaded? ] each
- append prune require-all load-failures. ;
-
-: refresh ( prefix -- ) to-refresh do-refresh ;
-
-SYMBOL: sources-changed?
-
-[ t sources-changed? set-global ] "vocabs.loader" add-init-hook
-
-: refresh-all ( -- )
- "" refresh f sources-changed? set-global ;
GENERIC: (load-vocab) ( name -- vocab )
! Copyright (C) 2007, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel vocabs vocabs.loader tools.time tools.browser
+USING: kernel vocabs vocabs.loader tools.time tools.vocabs
arrays assocs io.styles io help.markup prettyprint sequences
-continuations debugger ;
+continuations debugger combinators.cleave ;
IN: benchmark
: run-benchmark ( vocab -- result )
- [ dup require [ run ] benchmark ] [ error. drop f f ] recover 2array ;
+ [ [ require ] [ [ run ] benchmark nip ] bi ] curry
+ [ error. f ] recover ;
: run-benchmarks ( -- assoc )
- "benchmark" all-child-vocabs values concat [ vocab-name ] map
+ "benchmark" all-child-vocabs-seq
[ dup run-benchmark ] { } map>assoc ;
: benchmarks. ( assoc -- )
standard-table-style [
[
[ "Benchmark" write ] with-cell
- [ "Run time (ms)" write ] with-cell
- [ "GC time (ms)" write ] with-cell
+ [ "Time (ms)" write ] with-cell
] with-row
[
[
- swap [ dup ($vocab-link) ] with-cell
- first2 pprint-cell pprint-cell
+ [ [ 1array $vocab-link ] with-cell ]
+ [ pprint-cell ] bi*
] with-row
] assoc-each
] tabular-output ;
dup keys >byte-array
swap values >float-array unclip [ + ] accumulate swap add ;
-:: select-random ( seed chars floats -- elt )
+:: select-random ( seed chars floats -- seed elt )
floats seed random -rot
[ >= ] curry find drop
chars nth-unsafe ; inline
write-description
[ make-random-fasta ] 2curry split-lines ; inline
-:: make-repeat-fasta ( k len alu -- )
+:: make-repeat-fasta ( k len alu -- k' )
[let | kn [ alu length ] |
len [ k + kn mod alu nth-unsafe ] B{ } map-as print
k len +
"tools.test"
"tools.time"
"tools.threads"
+ "tools.vocabs"
+ "tools.vocabs.browser"
"editors"
} [ require ] each
[ benchmark-difference ] with map ;
: benchmark-deltas ( -- table )
- "../../benchmarks" "../benchmarks" [ eval-file ] 2apply
+ "../benchmarks" "benchmarks" [ eval-file ] 2apply
compare-tables
sort-values ;
bootstrap.image benchmark vars bake smtp builder.util accessors
io.encodings.utf8
calendar
+ tools.test
builder.common
builder.benchmark
builder.release ;
"Test time: " write "test-time" eval-file milli-seconds>time print nl
"Did not pass load-everything: " print "load-everything-vocabs" cat
+
"Did not pass test-all: " print "test-all-vocabs" cat
+ "test-all-vocabs" eval-file test-failures.
+
"help-lint results:" print "help-lint" cat
"Benchmarks: " print "benchmarks" eval-file benchmarks.
io
io.files
prettyprint
- tools.browser
+ tools.vocabs
tools.test
io.encodings.utf8
combinators.cleave
: do-tests ( -- )
run-all-tests
- "../test-all-vocabs" utf8
- [
- [ keys . ]
- [ test-failures. ]
- bi
- ]
- with-file-writer ;
+ [ keys "../test-all-vocabs" utf8 [ . ] with-file-writer ]
+ [ "../test-failures" utf8 [ test-failures. ] with-file-writer ]
+ bi ;
+
+! : do-tests ( -- )
+! run-all-tests
+! "../test-all-vocabs" utf8
+! [
+! [ keys . ]
+! [ test-failures. ]
+! bi
+! ]
+! with-file-writer ;
: do-help-lint ( -- )
"" run-help-lint "../help-lint" utf8 [ typos. ] with-file-writer ;
USING: tools.deploy.config ;
-V{
+H{
+ { deploy-math? t }
+ { deploy-reflection 1 }
+ { deploy-name "Bunny" }
+ { deploy-threads? t }
+ { deploy-word-props? f }
+ { "stop-after-last-window?" t }
{ deploy-ui? t }
{ deploy-io 3 }
- { deploy-reflection 1 }
{ deploy-compiler? t }
- { deploy-math? t }
- { deploy-word-props? f }
+ { deploy-word-defs? f }
{ deploy-c-types? f }
- { "stop-after-last-window?" t }
- { deploy-name "Bunny" }
}
USING: arrays bunny.model bunny.cel-shaded
combinators.lib continuations kernel math multiline
opengl opengl.shaders opengl.framebuffers opengl.gl
-opengl.capabilities sequences ui.gadgets ;
+opengl.capabilities sequences ui.gadgets combinators.cleave ;
IN: bunny.outlined
STRING: outlined-pass1-fragment-shader-main-source
[ bunny-outlined-normal-texture [ delete-texture ] when* ]
[ bunny-outlined-depth-texture [ delete-texture ] when* ]
[ f swap set-bunny-outlined-framebuffer-dim ]
- } call-with
+ } cleave
] [ drop ] if ;
: remake-framebuffer-if-needed ( draw -- )
[ bunny-outlined-pass1-program [ delete-gl-program ] when* ]
[ bunny-outlined-pass2-program [ delete-gl-program ] when* ]
[ dispose-framebuffer ]
- } call-with ;
+ } cleave ;
--- /dev/null
+
+USING: kernel quotations help.syntax help.markup ;
+
+IN: combinators.cleave
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "cleave-combinators" "Cleave Combinators"
+
+"Basic cleavers:"
+
+{ $subsection bi }
+{ $subsection tri }
+
+"General cleave: "
+{ $subsection cleave }
+
+"Cleave combinators for quotations with arity 2:"
+{ $subsection 2bi }
+{ $subsection 2tri }
+
+{ $notes
+ "From the Merriam-Webster Dictionary: "
+ $nl
+ { $strong "cleave" }
+ { $list
+ { $emphasis "To divide by or as if by a cutting blow" }
+ { $emphasis "To separate into distinct parts and especially into "
+ "groups having divergent views" } }
+ $nl
+ "The Joy programming language has a " { $emphasis "cleave" } " combinator." }
+
+;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: bi
+
+ { $values { "x" object }
+ { "p" quotation }
+ { "q" quotation }
+
+ { "p(x)" "p applied to x" }
+ { "q(x)" "q applied to x" } } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: tri
+
+ { $values { "x" object }
+ { "p" quotation }
+ { "q" quotation }
+ { "r" quotation }
+
+ { "p(x)" "p applied to x" }
+ { "q(x)" "q applied to x" }
+ { "r(x)" "r applied to x" } } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: cleave
+
+{ $code "( obj { q1 q2 ... qN } -- q1(obj) q2(obj) ... qN(obj) )" } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+{ bi tri cleave 2bi 2tri } related-words
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ARTICLE: "spread-combinators" "Spread Combinators"
+
+{ $subsection bi* }
+{ $subsection tri* }
+{ $subsection spread } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: bi*
+
+ { $values { "x" object }
+ { "y" object }
+ { "p" quotation }
+ { "q" quotation }
+
+ { "p(x)" "p applied to x" }
+ { "q(y)" "q applied to y" } } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: tri*
+
+ { $values { "x" object }
+ { "y" object }
+ { "z" object }
+ { "p" quotation }
+ { "q" quotation }
+ { "r" quotation }
+
+ { "p(x)" "p applied to x" }
+ { "q(y)" "q applied to y" }
+ { "r(z)" "r applied to z" } } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+HELP: spread
+
+{ $code "( v1 v2 ... vN { q1 q2 ... qN } -- q1(v1) q2(v2) ... qN(vN) )" } ;
\ No newline at end of file
! The cleaver family
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-: bi ( obj quot quot -- val val ) >r keep r> call ; inline
-
-: tri ( obj quot quot quot -- val val val )
- >r pick >r bi r> r> call ; inline
+: bi ( x p q -- p(x) q(x) ) >r keep r> call ; inline
+: tri ( x p q r -- p(x) q(x) r(x) ) >r pick >r bi r> r> call ; inline
: tetra ( obj quot quot quot quot -- val val val val )
>r >r pick >r bi r> r> r> bi ; inline
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-: 2bi ( obj obj quot quot -- val val ) >r 2keep r> call ; inline
+: 2bi ( x y p q -- p(x,y) q(x,y) ) >r 2keep r> call ; inline
+
+: 2tri ( x y z p q r -- p(x,y,z) q(x,y,z) r(x,y,z) )
+ >r >r 2keep r> 2keep r> call ; inline
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[ drop ]
append ;
+MACRO: 2cleave ( seq -- )
+ dup
+ [ drop [ 2dup ] ] map concat
+ swap
+ dup
+ [ drop [ >r >r ] ] map concat
+ swap
+ [ [ r> r> ] append ] map concat
+ 3append
+ [ 2drop ]
+ append ;
+
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! The spread family
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-: bi* ( obj obj quot quot -- val val ) >r swap slip r> call ; inline
+: bi* ( x y p q -- p(x) q(y) ) >r swap slip r> call ; inline
-: tri* ( obj obj obj quot quot quot -- val val val )
+: tri* ( x y z p q r -- p(x) q(y) r(z) )
>r rot >r bi* r> r> call ; inline
: tetra* ( obj obj obj obj quot quot quot quot -- val val val val )
: (make-call-with) ( quots -- quot )
[ [ keep ] curry ] map concat [ drop ] append ;
-MACRO: call-with ( quots -- )
- (make-call-with) ;
-
MACRO: map-call-with ( quots -- )
[ (make-call-with) ] keep length [ narray ] curry compose ;
[ [ 2dup >r >r ] swap append [ r> r> ] append ] map concat
[ 2drop ] append ;
-MACRO: call-with2 ( quots -- )
- (make-call-with2) ;
-
MACRO: map-call-with2 ( quots -- )
[ (make-call-with2) ] keep length [ narray ] curry append ;
SYMBOL: person4
: test-tuples ( -- )
- [ person drop-table ] [ drop ] recover
+ [ ] [ person ensure-table ] unit-test
+ [ ] [ person drop-table ] unit-test
[ ] [ person create-table ] unit-test
[ person create-table ] must-fail
+ [ ] [ person ensure-table ] unit-test
[ ] [ person1 get insert-tuple ] unit-test
[ native-person-schema test-tuples ] test-sqlite
[ assigned-person-schema test-tuples ] test-sqlite
-[ native-person-schema test-tuples ] test-postgresql
-[ assigned-person-schema test-tuples ] test-postgresql
+! [ native-person-schema test-tuples ] test-postgresql
+! [ assigned-person-schema test-tuples ] test-postgresql
TUPLE: serialize-me id data ;
] [ T{ serialize-me f 1 } select-tuples ] unit-test ;
[ test-serialize ] test-sqlite
-[ test-serialize ] test-postgresql
+! [ test-serialize ] test-postgresql
TUPLE: exam id name score ;
USING: arrays assocs classes db kernel namespaces
tuples words sequences slots math
math.parser io prettyprint db.types continuations
-mirrors sequences.lib tools.walker combinators.lib ;
+mirrors sequences.lib tools.walker combinators.lib
+combinators.cleave ;
IN: db.tuples
: define-persistent ( class table columns -- )
: drop-table ( class -- )
drop-sql-statement [ execute-statement ] with-disposals ;
+: ensure-table ( class -- )
+ [ dup drop-table ] ignore-errors create-table ;
+
: insert-native ( tuple -- )
dup class
db get db-insert-statements [ <insert-native-statement> ] cache
! Copyright (C) 2005, 2007 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: parser kernel namespaces sequences definitions io.files
-inspector continuations tuples tools.crossref tools.browser
+inspector continuations tuples tools.crossref tools.vocabs
io prettyprint source-files assocs vocabs vocabs.loader ;
IN: editors
SYMBOL: edit-hook
: available-editors ( -- seq )
- "editors" all-child-vocabs
- values concat [ vocab-name ] map ;
+ "editors" all-child-vocabs-seq [ vocab-name ] map ;
: editor-restarts ( -- alist )
available-editors
--- /dev/null
+! Generate a new factor.vim file for syntax highlighting
+USING: http.server.templating.fhtml io.files ;
+IN: editors.vim.generate-syntax
+
+: generate-vim-syntax ( -- )
+ "misc/factor.vim.fgen" resource-path
+ "misc/factor.vim" resource-path
+ template-convert ;
+
+MAIN: generate-vim-syntax
+++ /dev/null
-! Generate a new factor.vim file for syntax highlighting
-REQUIRES: apps/http-server ;
-
-IN: vim
-
-USING: embedded io ;
-
-"extras/factor.vim.fgen" resource-path
-"extras/factor.vim" resource-path
-embedded-convert
[ "<p><strong>foo</strong>\n</p><h1>aheading</h1>\n<p>adfasd</p>" ]
[ "*foo*\n=aheading=\nadfasd" convert-farkup ] unit-test
-[ "<p>=foo\n</p>" ] [ "=foo\n" 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
+[ "<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
+[ "<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
+
+[ "<span class='KEYWORD3'>int</span> <span class='FUNCTION'>main</span><span class='OPERATOR'>(</span><span class='OPERATOR'>)</span><br/>" ]
+[ "[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=\"teh lol\"/></p>" ] [ "[[image:lol.jpg|teh lol]]" convert-farkup ] unit-test
+[ "<p><a href=\"lol.com\"></a></p>" ] [ "[[lol.com]]" convert-farkup ] unit-test
+[ "<p><a href=\"lol.com\">haha</a></p>" ] [ "[[lol.com|haha]]" convert-farkup ] unit-test
MEMO: h3 ( -- parser ) "===" "h3" delimited ;
MEMO: h4 ( -- parser ) "====" "h4" delimited ;
+MEMO: eq ( -- parser )
+ [
+ h1 ensure-not ,
+ h2 ensure-not ,
+ h3 ensure-not ,
+ h4 ensure-not ,
+ "=" token ,
+ ] seq* ;
+
: render-code ( string mode -- string' )
>r string-lines r>
[ [ htmlize-lines ] with-html-stream ] with-string-writer ;
+: escape-link ( href text -- href-esc text-esc )
+ >r escape-quoted-string r> escape-string ;
+
: make-link ( href text -- seq )
- >r escape-quoted-string r> escape-string
+ escape-link
[ "<a href=\"" , >r , r> "\">" , [ , ] when* "</a>" , ] { } make ;
+: make-image-link ( href alt -- seq )
+ escape-link
+ [
+ "<img src=\"" , swap , "\"" ,
+ dup empty? [ drop ] [ " alt=\"" , , "\"" , ] if
+ "/>" , ]
+ { } make ;
+
+MEMO: image-link ( -- parser )
+ [
+ "[[image:" token hide ,
+ [ "|]" member? not ] satisfy repeat1 [ >string ] action ,
+ "|" token hide
+ [ CHAR: ] = not ] satisfy repeat0 2seq
+ [ first >string ] action optional ,
+ "]]" token hide ,
+ ] seq* [ first2 make-image-link ] action ;
+
MEMO: simple-link ( -- parser )
[
"[[" token hide ,
"]]" token hide ,
] seq* [ first2 make-link ] action ;
-MEMO: link ( -- parser ) [ simple-link , labelled-link , ] choice* ;
+MEMO: link ( -- parser ) [ image-link , simple-link , labelled-link , ] choice* ;
DEFER: line
MEMO: list-item ( -- parser )
MEMO: code ( -- parser )
[
"[" token hide ,
- [ "{" member? not ] satisfy repeat1 optional [ >string ] action ,
+ [ CHAR: { = not ] satisfy repeat1 optional [ >string ] action ,
"{" token hide ,
- [
- [ any-char , "}]" token ensure-not , ] seq*
- repeat1 [ concat >string ] action ,
- [ any-char , "}]" token hide , ] seq* optional [ >string ] action ,
- ] seq* [ concat ] action ,
+ "}]" token ensure-not any-char 2seq repeat0 [ concat >string ] action ,
+ "}]" token hide ,
] seq* [ first2 swap render-code ] action ;
MEMO: line ( -- parser )
[
text , strong , emphasis , link ,
superscript , subscript , inline-code ,
- escaped-char , delimiter ,
+ escaped-char , delimiter , eq ,
] choice* repeat1 ;
MEMO: paragraph ( -- parser )
}
"Convert a file of 4-byte cells from little to big endian or vice versa, by directly mapping it into memory and operating on it with sequence words:"
{ $code
- "\"mydata.dat\" dup file-length ["
+ "\"mydata.dat\" dup file-info file-info-length ["
" 4 <sliced-groups> [ reverse-here ] change-each"
"] with-mapped-file"
}
{ $subsection "io.timeouts" } ;
ARTICLE: "tools" "Developer tools"
+{ $subsection "tools.vocabs" }
"Exploratory tools:"
{ $subsection "editor" }
{ $subsection "tools.crossref" }
HELP: $notes
{ $values { "element" "a markup element" } }
-{ $description "Prints the errors subheading found on the help page of some words. This section should usage tips and pitfalls." } ;
+{ $description "Prints the notes subheading found on the help page of some words. This section should document usage tips and pitfalls." } ;
HELP: $see
{ $values { "element" "a markup element of the form " { $snippet "{ word }" } } }
! Copyright (C) 2006, 2007 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: sequences parser kernel help help.markup help.topics
-words strings classes tools.browser namespaces io
+words strings classes tools.vocabs namespaces io
io.streams.string prettyprint definitions arrays vectors
combinators splitting debugger hashtables sorting effects vocabs
vocabs.loader assocs editors continuations classes.predicate
] if
] ($subsection) ;
-: $vocab-link ( element -- ) first dup ($vocab-link) ;
+: $vocab-link ( element -- )
+ first dup vocab-name swap ($vocab-link) ;
: $vocabulary ( element -- )
first word-vocabulary [
TUPLE: link name ;
+MIXIN: topic
+INSTANCE: link topic
+INSTANCE: word topic
+
GENERIC: >link ( obj -- obj )
M: link >link ;
M: vocab-spec >link ;
USING: help.markup help.syntax ui.commands ui.operations
ui.tools.search ui.tools.workspace editors vocabs.loader
-kernel sequences prettyprint tools.test strings
+kernel sequences prettyprint tools.test tools.vocabs strings
unicode.categories unicode.case ;
IN: help.tutorial
swap >>post-data-type ;
: http-post ( content-type content url -- response string )
- #! The content is URL encoded for you.
- >r url-encode r> <post-request> http-request contents ;
+ <post-request> http-request contents ;
namespaces math.parser assocs sequences strings splitting ascii
io.encodings.utf8 io.encodings.string namespaces unicode.case
combinators vectors sorting new-slots accessors calendar
-calendar.format quotations arrays ;
+calendar.format quotations arrays combinators.cleave
+combinators.lib byte-arrays ;
IN: http
: http-port 80 ; inline
: url-quotable? ( ch -- ? )
#! In a URL, can this character be used without
#! URL-encoding?
- dup letter?
- over LETTER? or
- over digit? or
- swap "/_-." member? or ; foldable
+ {
+ [ dup letter? ]
+ [ dup LETTER? ]
+ [ dup digit? ]
+ [ dup "/_-.:" member? ]
+ } || nip ; foldable
: push-utf8 ( ch -- )
- 1string utf8 encode [ CHAR: % , >hex 2 CHAR: 0 pad-left % ] each ;
+ 1string utf8 encode
+ [ CHAR: % , >hex 2 CHAR: 0 pad-left % ] each ;
: url-encode ( str -- str )
- [ [
- dup url-quotable? [ , ] [ push-utf8 ] if
- ] each ] "" make ;
+ [
+ [ dup url-quotable? [ , ] [ push-utf8 ] if ] each
+ ] "" make ;
: url-decode-hex ( index str -- )
2dup length 2 - >= [
] when ;
: assoc>query ( hash -- str )
- [ [ url-encode ] 2apply "=" swap 3append ] { } assoc>map
+ [
+ [ url-encode ]
+ [ dup number? [ number>string ] when url-encode ]
+ bi*
+ "=" swap 3append
+ ] { } assoc>map
"&" join ;
TUPLE: cookie name value path domain expires http-only ;
: <request>
request construct-empty
- "1.1" >>version
- http-port >>port
- H{ } clone >>query
- V{ } clone >>cookies ;
+ "1.1" >>version
+ http-port >>port
+ H{ } clone >>query
+ V{ } clone >>cookies ;
: query-param ( request key -- value )
swap query>> at ;
: extract-post-data-type ( request -- request )
dup "content-type" header >>post-data-type ;
+: parse-post-data ( request -- request )
+ dup post-data-type>> "application/x-www-form-urlencoded" =
+ [ dup post-data>> query>assoc >>post-data ] when ;
+
: extract-cookies ( request -- request )
dup "cookie" header [ parse-cookies >>cookies ] when* ;
read-post-data
extract-host
extract-post-data-type
+ parse-post-data
extract-cookies ;
: write-method ( request -- request )
dup method>> write bl ;
-: write-url ( request -- request )
- dup path>> url-encode write
- dup query>> dup assoc-empty? [ drop ] [
- "?" write
- assoc>query write
- ] if ;
+: (link>string) ( url query -- url' )
+ [ url-encode ] [ assoc>query ] bi*
+ dup empty? [ drop ] [ "?" swap 3append ] if ;
+
+: write-url ( request -- )
+ [ path>> ] [ query>> ] bi (link>string) write ;
: write-request-url ( request -- request )
- write-url bl ;
+ dup write-url bl ;
: write-version ( request -- request )
"HTTP/" write dup request-version write crlf ;
+: unparse-post-data ( request -- request )
+ dup post-data>> dup sequence? [ drop ] [
+ assoc>query >>post-data
+ "application/x-www-form-urlencoded" >>post-data-type
+ ] if ;
+
: write-request-header ( request -- request )
dup header>> >hashtable
over host>> [ "host" pick set-at ] when*
dup post-data>> [ write ] when* ;
: write-request ( request -- )
+ unparse-post-data
write-method
write-request-url
write-version
: request-url ( request -- url )
[
- dup host>> [
- "http://" write
- dup host>> url-encode write
- ":" write
- dup port>> number>string write
- ] when
- dup path>> "/" head? [ "/" write ] unless
- write-url
- drop
+ [
+ dup host>> [
+ [ "http://" write host>> url-encode write ]
+ [ ":" write port>> number>string write ]
+ bi
+ ] [ drop ] if
+ ]
+ [ path>> "/" head? [ "/" write ] unless ]
+ [ write-url ]
+ tri
] with-string-writer ;
: set-header ( request/response value key -- request/response )
STRING: action-request-test-2
POST http://foo/bar/baz HTTP/1.1
content-length: 5
+content-type: application/x-www-form-urlencoded
xxx=4
;
[ <400> ] >>display\r
[ <400> ] >>submit ;\r
\r
-: extract-params ( path -- assoc )\r
- +path+ associate\r
- request get dup method>> {\r
- { "GET" [ query>> ] }\r
- { "HEAD" [ query>> ] }\r
- { "POST" [ post-data>> query>assoc ] }\r
- } case union ;\r
-\r
: with-validator ( string quot -- result error? )\r
'[ , @ f ] [\r
dup validation-error? [ t ] [ rethrow ] if\r
action get display>> call exit-with ;\r
\r
M: action call-responder ( path action -- response )\r
- [ extract-params params set ]\r
- [\r
- action set\r
- request get method>> {\r
- { "GET" [ handle-get ] }\r
- { "HEAD" [ handle-get ] }\r
- { "POST" [ handle-post ] }\r
- } case\r
- ] bi* ;\r
+ [ +path+ associate request-params union params set ]\r
+ [ action set ] bi*\r
+ request get method>> {\r
+ { "GET" [ handle-get ] }\r
+ { "HEAD" [ handle-get ] }\r
+ { "POST" [ handle-post ] }\r
+ } case ;\r
\r
: successful-login ( user -- response )\r
logged-in-user sset\r
- post-login-url sget f <permanent-redirect> ;\r
+ post-login-url sget "" or f <permanent-redirect>\r
+ f post-login-url sset ;\r
\r
:: <login-action> ( -- action )\r
[let | form [ <login-form> ] |\r
-<% USING: http.server.auth.login http.server.components kernel\r
-namespaces ; %>\r
+<% USING: http.server.auth.login http.server.components http.server\r
+kernel namespaces ; %>\r
<html>\r
<body>\r
<h1>Login required</h1>\r
\r
<form method="POST" action="login">\r
+\r
+<% hidden-form-field %>\r
+\r
<table>\r
\r
<tr>\r
\r
<p>\r
<% allow-registration? [ %>\r
- <a href="register">Register</a>\r
+ <a href="<% "register" f write-link %>">Register</a>\r
<% ] when %>\r
<% allow-password-recovery? [ %>\r
- <a href="recover-password">Recover Password</a>\r
+ <a href="<% "recover-password" f write-link %>">\r
+ Recover Password\r
+ </a>\r
<% ] when %>\r
</p>\r
\r
-<% USING: http.server.components ; %>\r
+<% USING: http.server.components http.server ; %>\r
<html>\r
<body>\r
<h1>Recover lost password: step 1 of 4</h1>\r
<p>Enter the username and e-mail address you used to register for this site, and you will receive a link for activating a new password.</p>\r
\r
<form method="POST" action="recover-password">\r
+\r
+<% hidden-form-field %>\r
+\r
<table>\r
\r
<tr>\r
-<% USING: http.server.components http.server.auth.login\r
+<% USING: http.server.components http.server.auth.login http.server\r
namespaces kernel combinators ; %>\r
<html>\r
<body>\r
<p>Choose a new password for your account.</p>\r
\r
<form method="POST" action="new-password">\r
+\r
+<% hidden-form-field %>\r
+\r
<table>\r
\r
<% "username" component render-edit %>\r
<p><input type="submit" value="Set password" />\r
\r
<% password-mismatch? get [\r
-"passwords do not match" render-error\r
+ "passwords do not match" render-error\r
] when %>\r
\r
</p>\r
-<% USING: http.server.components http.server.auth.login\r
-namespaces kernel combinators ; %>\r
+<% USING: http.server ; %>\r
<html>\r
<body>\r
<h1>Recover lost password: step 4 of 4</h1>\r
\r
-<p>Your password has been reset. You may now <a href="login">log in</a>.</p>\r
+<p>Your password has been reset.\r
+You may now <a href="<% "login" f write-link %>">log in</a>.</p>\r
\r
</body>\r
</html>\r
<% USING: http.server.components http.server.auth.login\r
-namespaces kernel combinators ; %>\r
+http.server namespaces kernel combinators ; %>\r
<html>\r
<body>\r
<h1>New user registration</h1>\r
\r
<form method="POST" action="register">\r
+<% hidden-form-field %>\r
+\r
<table>\r
\r
<tr>\r
{ "profile" "PROFILE" FACTOR-BLOB }\r
} define-persistent\r
\r
-: init-users-table ( -- )\r
- [ user drop-table ] ignore-errors\r
- user create-table ;\r
+: init-users-table user ensure-table ;\r
\r
TUPLE: from-db ;\r
\r
USING: assocs kernel namespaces io io.timeouts strings splitting
threads http sequences prettyprint io.server logging calendar
new-slots html.elements accessors math.parser combinators.lib
-vocabs.loader debugger html continuations random combinators
+tools.vocabs debugger html continuations random combinators
destructors io.encodings.latin1 fry combinators.cleave ;
IN: http.server
GENERIC: call-responder ( path responder -- response )
+: request-params ( -- assoc )
+ request get dup method>> {
+ { "GET" [ query>> ] }
+ { "HEAD" [ query>> ] }
+ { "POST" [ post-data>> ] }
+ } case ;
+
: <content> ( content-type -- response )
<response>
200 >>code
+ "Document follows" >>message
swap set-content-type ;
TUPLE: trivial-responder response ;
[ <404> ] <trivial-responder> 404-responder set-global
-: url-redirect ( to query -- url )
- #! Different host.
- dup assoc-empty? [
- drop
- ] [
- assoc>query "?" swap 3append
- ] if ;
+SYMBOL: link-hook
+
+: modify-query ( query -- query )
+ link-hook get [ ] or call ;
+
+: link>string ( url query -- url' )
+ modify-query (link>string) ;
+
+: write-link ( url query -- )
+ link>string write ;
+
+SYMBOL: form-hook
+
+: hidden-form-field ( -- )
+ form-hook get [ ] or call ;
: absolute-redirect ( to query -- url )
#! Same host.
request get clone
swap [ >>query ] when*
- swap >>path
+ swap url-encode >>path
request-url ;
: replace-last-component ( path with -- path' )
request get clone
swap [ >>query ] when*
swap [ '[ , replace-last-component ] change-path ] when*
+ dup query>> modify-query >>query
request-url ;
: derive-url ( to query -- url )
{
- { [ over "http://" head? ] [ url-redirect ] }
+ { [ over "http://" head? ] [ link>string ] }
{ [ over "/" head? ] [ absolute-redirect ] }
{ [ t ] [ relative-redirect ] }
} cond ;
USING: tools.test http.server.sessions math namespaces\r
kernel accessors ;\r
\r
+[ H{ } ] [ H{ } add-session-id ] unit-test\r
+\r
: with-session \ session swap with-variable ; inline\r
\r
TUPLE: foo ;\r
\r
M: foo init-session* drop 0 "x" sset ;\r
\r
-f <session> [\r
+f <session> "123" >>id [\r
+ [ H{ { "factorsessid" "123" } } ] [ H{ } add-session-id ] unit-test\r
+\r
[ ] [ 3 "x" sset ] unit-test\r
\r
[ 9 ] [ "x" sget sq ] unit-test\r
! See http://factorcode.org/license.txt for BSD license.
USING: assocs calendar kernel math.parser namespaces random
boxes alarms new-slots accessors http http.server
-quotations hashtables sequences fry combinators.cleave ;
+quotations hashtables sequences fry combinators.cleave
+html.elements ;
IN: http.server.sessions
! ! ! ! ! !
: sessions ( -- manager/f )
\ session get dup [ manager>> ] when ;
-GENERIC: session-link* ( url query sessions -- string )
-
-M: object session-link* 2drop url-encode ;
-
-: session-link ( url query -- string ) sessions session-link* ;
-
TUPLE: null-sessions ;
: <null-sessions>
: sess-id "factorsessid" ;
-: current-session ( responder request -- session )
- sess-id query-param swap get-session ;
+: current-session ( responder -- session )
+ >r request-params sess-id swap at r> get-session ;
+
+: add-session-id ( query -- query' )
+ \ session get [ id>> sess-id associate union ] when* ;
+
+: session-form-field ( -- )
+ <input
+ "hidden" =type
+ sess-id =id
+ sess-id =name
+ \ session get id>> =value
+ input/> ;
M: url-sessions call-responder ( path responder -- response )
- dup request get current-session [
+ [ add-session-id ] link-hook set
+ [ session-form-field ] form-hook set
+ dup current-session [
call-responder/session
] [
nip
f swap new-session sess-id associate <temporary-redirect>
] if* ;
-M: url-sessions session-link*
- drop
- url-encode
- \ session get id>> sess-id associate union assoc>query
- dup assoc-empty? [ drop ] [ "?" swap 3append ] if ;
-
TUPLE: cookie-sessions ;
: <cookie-sessions> ( responder -- responder' )
combinators.cleave fry ;\r
IN: http.server.static\r
\r
-SYMBOL: responder\r
-\r
! special maps mime types to quots with effect ( path -- )\r
TUPLE: file-responder root hook special ;\r
\r
-: unix-time>timestamp ( n -- timestamp )\r
- >r unix-1970 r> seconds time+ ;\r
-\r
: file-http-date ( filename -- string )\r
- file-modified unix-time>timestamp timestamp>http-string ;\r
+ file-info file-info-modified timestamp>http-string ;\r
\r
: last-modified-matches? ( filename -- ? )\r
file-http-date dup [\r
[\r
<content>\r
swap\r
- [ file-length "content-length" set-header ]\r
+ [ file-info file-info-size "content-length" set-header ]\r
[ file-http-date "last-modified" set-header ]\r
[ '[ , binary <file-reader> stdio get stream-copy ] >>body ]\r
tri\r
--- /dev/null
+USING: io.encodings.string io.encodings.ascii tools.test strings arrays ;
+IN: io.encodings.ascii.tests
+
+[ B{ CHAR: f CHAR: o CHAR: o } ] [ "foo" ascii encode ] unit-test
+[ { 128 } >string ascii encode ] must-fail
+[ B{ 127 } ] [ { 127 } ascii encode ] unit-test
+
+[ "bar" ] [ "bar" ascii decode ] unit-test
+[ { CHAR: b HEX: fffd CHAR: r } ] [ { CHAR: b 233 CHAR: r } ascii decode >array ] unit-test
USING: io io.encodings strings kernel math sequences byte-arrays io.encodings ;
IN: io.encodings.ascii
-: encode-check<= ( string stream max -- )
+: encode-check< ( string stream max -- )
[ pick <= [ encode-error ] [ stream-write1 ] if ] 2curry each ;
+: push-if< ( sbuf character max -- )
+ over <= [ drop HEX: fffd ] when swap push ;
+
TUPLE: ascii ;
M: ascii stream-write-encoded ( string stream encoding -- )
- drop 128 encode-check<= ;
+ drop 128 encode-check< ;
M: ascii decode-step
- drop dup 128 >= [ decode-error ] [ swap push ] if ;
+ drop 128 push-if< ;
--- /dev/null
+USING: io.encodings.string io.encodings.latin1 tools.test strings arrays ;
+IN: io.encodings.latin1.tests
+
+[ B{ CHAR: f CHAR: o CHAR: o } ] [ "foo" latin1 encode ] unit-test
+[ { 256 } >string latin1 encode ] must-fail
+[ B{ 255 } ] [ { 255 } latin1 encode ] unit-test
+
+[ "bar" ] [ "bar" latin1 decode ] unit-test
+[ { CHAR: b 233 CHAR: r } ] [ { CHAR: b 233 CHAR: r } latin1 decode >array ] unit-test
TUPLE: latin1 ;
M: latin1 stream-write-encoded
- drop 256 encode-check<= ;
+ drop 256 encode-check< ;
M: latin1 decode-step
drop swap push ;
[ "mmap-test-file.txt" resource-path delete-file ] ignore-errors
[ ] [ "12345" "mmap-test-file.txt" resource-path ascii set-file-contents ] unit-test
-[ ] [ "mmap-test-file.txt" resource-path dup file-length [ CHAR: 2 0 pick set-nth drop ] with-mapped-file ] unit-test
-[ 5 ] [ "mmap-test-file.txt" resource-path dup file-length [ length ] with-mapped-file ] unit-test
+[ ] [ "mmap-test-file.txt" resource-path dup file-info file-info-size [ CHAR: 2 0 pick set-nth drop ] with-mapped-file ] unit-test
+[ 5 ] [ "mmap-test-file.txt" resource-path dup file-info file-info-size [ length ] with-mapped-file ] unit-test
[ "22345" ] [ "mmap-test-file.txt" resource-path ascii file-contents ] unit-test
[ "mmap-test-file.txt" resource-path delete-file ] ignore-errors
! Copyright (C) 2005, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: io.backend io.nonblocking io.unix.backend io.files io
-unix unix.stat unix.time kernel math continuations math.bitfields
-byte-arrays alien combinators combinators.cleave calendar
-io.encodings.binary ;
+unix unix.stat unix.time kernel math continuations
+math.bitfields byte-arrays alien combinators combinators.cleave
+calendar io.encodings.binary ;
IN: io.unix.files
M: unix-io cwd
- MAXPATHLEN dup <byte-array> swap
- getcwd [ (io-error) ] unless* ;
+ MAXPATHLEN [ <byte-array> ] [ ] bi getcwd
+ [ (io-error) ] unless* ;
M: unix-io cd
chdir io-error ;
] with-disposal ;
M: unix-io copy-file ( from to -- )
- [ (copy-file) ] 2keep swap file-permissions chmod io-error ;
+ [ (copy-file) ]
+ [ swap file-info file-info-permissions chmod io-error ]
+ 2bi ;
: stat>type ( stat -- type )
stat-st_mode {
{ [ t ] [ +unknown+ ] }
} cond nip ;
-M: unix-io file-info ( path -- info )
- stat* {
+: stat>file-info ( stat -- info )
+ {
[ stat>type ]
[ stat-st_size ]
[ stat-st_mode ]
} cleave
\ file-info construct-boa ;
+M: unix-io file-info ( path -- info )
+ stat* stat>file-info ;
+
M: unix-io link-info ( path -- info )
- lstat* {
- [ stat>type ]
- [ stat-st_size ]
- [ stat-st_mode ]
- [ stat-st_mtim timespec-sec seconds unix-1970 time+ ]
- } cleave
- \ file-info construct-boa ;
+ lstat* stat>file-info ;
"io.unix." os append require
-"vocabs.monitor" require
+"tools.vocabs.monitor" require
USING: alien.c-types io.files io.windows kernel
math windows windows.kernel32 combinators.cleave
windows.time calendar combinators math.functions
-sequences combinators.lib namespaces words symbols ;
+sequences namespaces words symbols ;
IN: io.windows.files
SYMBOLS: +read-only+ +hidden+ +system+
+sparse-file+ +reparse-point+ +compressed+ +offline+
+not-content-indexed+ +encrypted+ ;
-: expand-constants ( word/obj -- obj'/obj )
- dup word? [ execute ] when ;
+: win32-file-attribute ( n attr symbol -- n )
+ >r dupd mask? [ r> , ] [ r> drop ] if ;
-: get-flags ( n seq -- seq' )
+: win32-file-attributes ( n -- seq )
[
- [
- first2 expand-constants
- [ swapd mask? [ , ] [ drop ] if ] 2curry
- ] map call-with
+ FILE_ATTRIBUTE_READONLY +read-only+ win32-file-attribute
+ FILE_ATTRIBUTE_HIDDEN +hidden+ win32-file-attribute
+ FILE_ATTRIBUTE_SYSTEM +system+ win32-file-attribute
+ FILE_ATTRIBUTE_DIRECTORY +directory+ win32-file-attribute
+ FILE_ATTRIBUTE_ARCHIVE +archive+ win32-file-attribute
+ FILE_ATTRIBUTE_DEVICE +device+ win32-file-attribute
+ FILE_ATTRIBUTE_NORMAL +normal+ win32-file-attribute
+ FILE_ATTRIBUTE_TEMPORARY +temporary+ win32-file-attribute
+ FILE_ATTRIBUTE_SPARSE_FILE +sparse-file+ win32-file-attribute
+ FILE_ATTRIBUTE_REPARSE_POINT +reparse-point+ win32-file-attribute
+ FILE_ATTRIBUTE_COMPRESSED +compressed+ win32-file-attribute
+ FILE_ATTRIBUTE_OFFLINE +offline+ win32-file-attribute
+ FILE_ATTRIBUTE_NOT_CONTENT_INDEXED +not-content-indexed+ win32-file-attribute
+ FILE_ATTRIBUTE_ENCRYPTED +encrypted+ win32-file-attribute
+ drop
] { } make ;
-: win32-file-attributes ( n -- seq )
- {
- { +read-only+ FILE_ATTRIBUTE_READONLY }
- { +hidden+ FILE_ATTRIBUTE_HIDDEN }
- { +system+ FILE_ATTRIBUTE_SYSTEM }
- { +directory+ FILE_ATTRIBUTE_DIRECTORY }
- { +archive+ FILE_ATTRIBUTE_ARCHIVE }
- { +device+ FILE_ATTRIBUTE_DEVICE }
- { +normal+ FILE_ATTRIBUTE_NORMAL }
- { +temporary+ FILE_ATTRIBUTE_TEMPORARY }
- { +sparse-file+ FILE_ATTRIBUTE_SPARSE_FILE }
- { +reparse-point+ FILE_ATTRIBUTE_REPARSE_POINT }
- { +compressed+ FILE_ATTRIBUTE_COMPRESSED }
- { +offline+ FILE_ATTRIBUTE_OFFLINE }
- { +not-content-indexed+ FILE_ATTRIBUTE_NOT_CONTENT_INDEXED }
- { +encrypted+ FILE_ATTRIBUTE_ENCRYPTED }
- } get-flags ;
-
: win32-file-type ( n -- symbol )
FILE_ATTRIBUTE_DIRECTORY mask? +directory+ +regular-file+ ? ;
io.streams.duplex windows.types math windows.kernel32 windows
namespaces io.launcher kernel sequences windows.errors assocs
splitting system threads init strings combinators
-io.backend new-slots accessors ;
+io.backend new-slots accessors concurrency.flags ;
IN: io.windows.launcher
TUPLE: CreateProcess-args
dup HEX: ffffffff = [ win32-error ] when
dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth process-exited f ] if ;
+SYMBOL: wait-flag
+
: wait-loop ( -- )
processes get dup assoc-empty?
- [ drop f sleep-until ]
+ [ drop wait-flag get-global lower-flag ]
[ wait-for-processes [ 100 sleep ] when ] if ;
-SYMBOL: wait-thread
-
: start-wait-thread ( -- )
- [ wait-loop t ] "Process wait" spawn-server
- wait-thread set-global ;
+ <flag> wait-flag set-global
+ [ wait-loop t ] "Process wait" spawn-server drop ;
M: windows-io register-process
- drop wait-thread get-global interrupt ;
+ drop wait-flag get-global raise-flag ;
[ start-wait-thread ] "io.windows.launcher" add-init-hook
T{ windows-nt-io } set-io-backend
-"vocabs.monitor" require
+"tools.vocabs.monitor" require
] when drop ;
: open-append ( path -- handle length )
- dup file-length dup [
+ dup file-info file-info-size dup [
>r (open-append) r> 2dup set-file-pointer
] [
drop open-write
USE: vocabs.loader
jamshred-gadget H{
- { T{ key-down f f "r" } [ jamshred-restart refresh-all ] }
+ { T{ key-down f f "r" } [ jamshred-restart ] }
{ T{ key-down f f " " } [ jamshred-gadget-jamshred toggle-running ] }
{ T{ motion } [ handle-mouse-motion ] }
} set-gestures
arrays macros splitting combinators prettyprint.backend
definitions prettyprint hashtables combinators.lib
prettyprint.sections sequences.private effects generic
-compiler.units ;
+compiler.units combinators.cleave ;
IN: locals
! Inspired by
if ;
: (point-free) ( quot args -- newquot )
- { [ load-locals ] [ point-free-body ] [ point-free-end ] }
- map-call-with2 concat >quotation ;
+ [ load-locals ] [ point-free-body ] [ point-free-end ]
+ 2tri 3append >quotation ;
: point-free ( quot args -- newquot )
over empty? [ drop ] [ (point-free) ] if ;
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays kernel sequences math math.functions
-math.vectors ;
+math.vectors combinators.cleave ;
IN: math.matrices
! Matrices
: mmax ( m -- n ) >r -1/0. r> [ [ max ] each ] each ;
: mnorm ( m -- n ) dup mmax abs m/n ;
-: cross-i ( vec1 vec2 -- i )
- over third over second * >r
- swap second swap third * r> - ;
+<PRIVATE
-: cross-j ( vec1 vec2 -- j )
- over first over third * >r
- swap third swap first * r> - ;
+: x first ; inline
+: y second ; inline
+: z third ; inline
-: cross-k ( vec1 vec2 -- k )
- over first over second * >r
- swap second swap first * r> - ;
+: i [ [ y ] [ z ] bi* * ] [ [ z ] [ y ] bi* * ] 2bi - ;
+: j [ [ z ] [ x ] bi* * ] [ [ x ] [ z ] bi* * ] 2bi - ;
+: k [ [ y ] [ x ] bi* * ] [ [ x ] [ y ] bi* * ] 2bi - ;
-: cross ( vec1 vec2 -- vec3 )
- [ cross-i ] 2keep [ cross-j ] 2keep cross-k 3array ;
+PRIVATE>
+
+: cross ( vec1 vec2 -- vec3 ) [ i ] [ j ] [ k ] 2tri 3array ;
: proj ( v u -- w )
- [ [ v. ] keep norm-sq / ] keep n*v ;
+ [ [ v. ] [ norm-sq ] bi / ] keep n*v ;
: (gram-schmidt) ( v seq -- newseq )
[ dupd proj v- ] each ;
USING: arrays combinators.lib kernel math math.functions math.vectors namespaces
- opengl opengl.gl sequences ui ui.gadgets ui.gestures ui.render ;
+ opengl opengl.gl sequences ui ui.gadgets ui.gestures ui.render combinators.cleave ;
IN: opengl.demo-support
: NEAR-PLANE 1.0 64.0 / ; inline
GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear
GL_MODELVIEW glMatrixMode
glLoadIdentity
- { [ >r 0.0 0.0 r> demo-gadget-distance neg glTranslatef ]
- [ demo-gadget-pitch 1.0 0.0 0.0 glRotatef ]
- [ demo-gadget-yaw 0.0 1.0 0.0 glRotatef ] } call-with ;
+ [ >r 0.0 0.0 r> demo-gadget-distance neg glTranslatef ]
+ [ demo-gadget-pitch 1.0 0.0 0.0 glRotatef ]
+ [ demo-gadget-yaw 0.0 1.0 0.0 glRotatef ]
+ tri ;
: reset-last-drag-rel ( -- )
- { 0 0 } last-drag-loc set ;
+ { 0 0 } last-drag-loc set-global ;
: last-drag-rel ( -- rel )
- drag-loc [ last-drag-loc get v- ] keep last-drag-loc set ;
+ drag-loc [ last-drag-loc get v- ] keep last-drag-loc set-global ;
: drag-yaw-pitch ( -- yaw pitch )
last-drag-rel MOUSE-MOTION-SCALE v*n first2 ;
! See http://factorcode.org/license.txt for BSD license.
USING: kernel opengl.gl alien.c-types continuations namespaces
assocs alien libc opengl math sequences combinators.lib
-macros arrays ;
+macros arrays combinators.cleave ;
IN: opengl.shaders
: with-gl-shader-source-ptr ( string quot -- )
: (make-with-gl-program) ( uniforms quot -- q )
[
\ dup ,
- [ swap (with-gl-program-uniforms) , \ call-with , % ]
+ [ swap (with-gl-program-uniforms) , \ cleave , % ]
[ ] make ,
\ (with-gl-program) ,
] [ ] make ;
read [ zero? ] right-trim dup empty? [ drop f ] when ;
: (read-128-ber) ( n -- n )
- 1 read first
+ read1
[ >r 7 shift r> 7 clear-bit bitor ] keep
7 bit? [ (read-128-ber) ] when ;
-! Copyright (C) 2007 Chris Double.
+! Copyright (C) 2008 Chris Double, Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax peg peg.parsers.private
unicode.categories ;
IN: peg.parsers
+HELP: 1token
+{ $values
+ { "ch" "a character" }
+ { "parser" "a parser" }
+} { $description
+ "Calls 1string on a character and returns a parser that matches that character."
+} { $examples
+ { $example "USING: peg peg.parsers prettyprint ;" "\"a\" CHAR: a 1token parse parse-result-ast ." "\"a\"" }
+} { $see-also 'string' } ;
+
HELP: (list-of)
{ $values
{ "items" "a sequence" }
MEMO: just ( parser -- parser )
just-parser construct-boa init-parser ;
+MEMO: 1token ( ch -- parser ) 1string token ;
+
<PRIVATE
MEMO: (list-of) ( items separator repeat1? -- parser )
>r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
! Copyright (C) 2008 Alex Chapman
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors db.tuples kernel new-slots semantic-db
-semantic-db.relations sorting sequences sequences.deep ;
+USING: accessors db.tuples hashtables kernel new-slots
+semantic-db semantic-db.relations sequences sequences.deep ;
IN: semantic-db.hierarchy
TUPLE: tree id children ;
: get-node-hierarchy ( node-id -- tree )
dup children [ get-node-hierarchy ] map <tree> ;
-: uniq ( sorted-seq -- seq )
- f swap [ tuck = not ] subset nip ;
-
: (get-root-nodes) ( node-id -- root-nodes/node-id )
dup parents dup empty? [
drop
] if ;
: get-root-nodes ( node-id -- root-nodes )
- (get-root-nodes) flatten natural-sort uniq ;
+ (get-root-nodes) flatten prune ;
-USING: accessors arrays continuations db db.sqlite db.tuples io.files
-kernel math namespaces semantic-db semantic-db.context
-semantic-db.hierarchy semantic-db.relations sequences tools.test
+USING: accessors arrays continuations db db.sqlite
+db.tuples io.files kernel math namespaces semantic-db
+semantic-db.context semantic-db.hierarchy
+semantic-db.relations sequences sorting tools.test
tools.walker ;
IN: semantic-db.tests
[ { "bob" "fran" } ] [ "eve" get children [ node-content ] map ] unit-test
[ { "adam" "eve" } ] [ "bob" get parents [ node-content ] map ] unit-test
[ "fran" { "charlie" } ] [ "fran" get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test
- [ { "adam" "eve" } ] [ "charlie" get get-root-nodes [ node-content ] map ] unit-test
+ [ { "adam" "eve" } ] [ "charlie" get get-root-nodes [ node-content ] map natural-sort >array ] unit-test
[ { } ] [ "fran" get "charlie" get tuck un-parent-child parents [ node-content ] map ] unit-test
] with-context
] with-db
+++ /dev/null
-Slava Pestov
+++ /dev/null
-USING: help.markup help.syntax io strings ;
-IN: tools.browser
-
-ARTICLE: "vocab-index" "Vocabulary index"
-{ $tags }
-{ $authors }
-{ $describe-vocab "" } ;
-
-ARTICLE: "tools.browser" "Vocabulary browser"
-"Getting and setting vocabulary meta-data:"
-{ $subsection vocab-file-contents }
-{ $subsection set-vocab-file-contents }
-{ $subsection vocab-summary }
-{ $subsection set-vocab-summary }
-{ $subsection vocab-tags }
-{ $subsection set-vocab-tags }
-{ $subsection add-vocab-tags }
-"Global meta-data:"
-{ $subsection all-vocabs }
-{ $subsection all-vocabs-seq }
-{ $subsection all-tags }
-{ $subsection all-authors }
-"Because loading the above data is expensive, it is cached. The cache is flushed by the " { $vocab-link "vocabs.monitor" } " vocabulary. It can also be flushed manually when file system change monitors are not available:"
-{ $subsection reset-cache } ;
-
-HELP: vocab-file-contents
-{ $values { "vocab" "a vocabulary specifier" } { "name" string } { "seq" "a sequence of lines, or " { $link f } } }
-{ $description "Outputs the contents of the file named " { $snippet "name" } " from the vocabulary's directory, or " { $link f } " if the file does not exist." } ;
-
-HELP: set-vocab-file-contents
-{ $values { "seq" "a sequence of lines" } { "vocab" "a vocabulary specifier" } { "name" string } }
-{ $description "Stores a sequence of lines to the file named " { $snippet "name" } " from the vocabulary's directory." } ;
-
-HELP: vocab-summary
-{ $values { "vocab" "a vocabulary specifier" } { "summary" "a string or " { $link f } } }
-{ $description "Outputs a one-line string description of the vocabulary's intended purpose from the " { $snippet "summary.txt" } " file in the vocabulary's directory. Outputs " { $link f } " if the file does not exist." } ;
-
-HELP: set-vocab-summary
-{ $values { "string" "a string or " { $link f } } { "vocab" "a vocabulary specifier" } }
-{ $description "Stores a one-line string description of the vocabulary to the " { $snippet "summary.txt" } " file in the vocabulary's directory." } ;
-
-HELP: vocab-tags
-{ $values { "vocab" "a vocabulary specifier" } { "tags" "a sequence of strings" } }
-{ $description "Outputs a list of short tags classifying the vocabulary from the " { $snippet "tags.txt" } " file in the vocabulary's directory. Outputs " { $link f } " if the file does not exist." } ;
-
-HELP: set-vocab-tags
-{ $values { "tags" "a sequence of strings" } { "vocab" "a vocabulary specifier" } }
-{ $description "Stores a list of short tags classifying the vocabulary to the " { $snippet "tags.txt" } " file in the vocabulary's directory." } ;
-
-HELP: all-vocabs
-{ $values { "assoc" "an association list mapping vocabulary roots to sequences of vocabulary specifiers" } }
-{ $description "Outputs an association list of all vocabularies which have been loaded or are available for loading." } ;
+++ /dev/null
-IN: tools.browser.tests
-USING: tools.browser tools.test help.markup ;
-
-[ ] [ { $describe-vocab "scratchpad" } print-content ] unit-test
+++ /dev/null
-! Copyright (C) 2007, 2008 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces splitting sequences io.files kernel assocs
-words vocabs vocabs.loader definitions parser continuations
-inspector debugger io io.styles hashtables
-sorting prettyprint source-files arrays combinators strings
-system math.parser help.markup help.topics help.syntax
-help.stylesheet memoize io.encodings.utf8 ;
-IN: tools.browser
-
-MEMO: (vocab-file-contents) ( path -- lines )
- ?resource-path dup exists?
- [ utf8 file-lines ] [ drop f ] if ;
-
-: vocab-file-contents ( vocab name -- seq )
- vocab-path+ dup [ (vocab-file-contents) ] when ;
-
-: set-vocab-file-contents ( seq vocab name -- )
- dupd vocab-path+ [
- ?resource-path utf8 set-file-lines
- ] [
- "The " swap vocab-name
- " vocabulary was not loaded from the file system"
- 3append throw
- ] ?if ;
-
-: vocab-summary-path ( vocab -- string )
- vocab-dir "summary.txt" path+ ;
-
-: vocab-summary ( vocab -- summary )
- dup dup vocab-summary-path vocab-file-contents
- dup empty? [
- drop vocab-name " vocabulary" append
- ] [
- nip first
- ] if ;
-
-M: vocab summary
- [
- dup vocab-summary %
- " (" %
- vocab-words assoc-size #
- " words)" %
- ] "" make ;
-
-M: vocab-link summary vocab-summary ;
-
-: set-vocab-summary ( string vocab -- )
- >r 1array r>
- dup vocab-summary-path
- set-vocab-file-contents ;
-
-: vocab-tags-path ( vocab -- string )
- vocab-dir "tags.txt" path+ ;
-
-: vocab-tags ( vocab -- tags )
- dup vocab-tags-path vocab-file-contents ;
-
-: set-vocab-tags ( tags vocab -- )
- dup vocab-tags-path set-vocab-file-contents ;
-
-: add-vocab-tags ( tags vocab -- )
- [ vocab-tags append prune ] keep set-vocab-tags ;
-
-: vocab-authors-path ( vocab -- string )
- vocab-dir "authors.txt" path+ ;
-
-: vocab-authors ( vocab -- authors )
- dup vocab-authors-path vocab-file-contents ;
-
-: set-vocab-authors ( authors vocab -- )
- dup vocab-authors-path set-vocab-file-contents ;
-
-: subdirs ( dir -- dirs )
- directory [ second ] subset keys natural-sort ;
-
-: (all-child-vocabs) ( root name -- vocabs )
- [ vocab-dir path+ ?resource-path subdirs ] keep
- dup empty? [
- drop
- ] [
- swap [ "." swap 3append ] with map
- ] if ;
-
-: vocabs-in-dir ( root name -- )
- dupd (all-child-vocabs) [
- 2dup vocab-dir? [ 2dup swap >vocab-link , ] when
- vocabs-in-dir
- ] with each ;
-
-: all-vocabs ( -- assoc )
- vocab-roots get [
- dup [ "" vocabs-in-dir ] { } make
- ] { } map>assoc ;
-
-MEMO: all-vocabs-seq ( -- seq )
- all-vocabs values concat ;
-
-: dangerous? ( name -- ? )
- #! Hack
- {
- { [ "cpu." ?head ] [ t ] }
- { [ "io.unix" ?head ] [ t ] }
- { [ "io.windows" ?head ] [ t ] }
- { [ "ui.x11" ?head ] [ t ] }
- { [ "ui.windows" ?head ] [ t ] }
- { [ "ui.cocoa" ?head ] [ t ] }
- { [ "cocoa" ?head ] [ t ] }
- { [ "core-foundation" ?head ] [ t ] }
- { [ "vocabs.loader.test" ?head ] [ t ] }
- { [ "editors." ?head ] [ t ] }
- { [ ".windows" ?tail ] [ t ] }
- { [ ".unix" ?tail ] [ t ] }
- { [ "unix." ?head ] [ t ] }
- { [ ".linux" ?tail ] [ t ] }
- { [ ".bsd" ?tail ] [ t ] }
- { [ ".macosx" ?tail ] [ t ] }
- { [ "windows." ?head ] [ t ] }
- { [ "cocoa" ?head ] [ t ] }
- { [ ".test" ?tail ] [ t ] }
- { [ "raptor" ?head ] [ t ] }
- { [ dup "tools.deploy.app" = ] [ t ] }
- { [ t ] [ f ] }
- } cond nip ;
-
-: filter-dangerous ( seq -- seq' )
- [ vocab-name dangerous? not ] subset ;
-
-: try-everything ( -- failures )
- all-vocabs-seq
- filter-dangerous
- require-all ;
-
-: load-everything ( -- )
- try-everything load-failures. ;
-
-: unrooted-child-vocabs ( prefix -- seq )
- dup empty? [ CHAR: . add ] unless
- vocabs
- [ vocab-root not ] subset
- [
- vocab-name swap ?head CHAR: . rot member? not and
- ] with subset
- [ vocab ] map ;
-
-: all-child-vocabs ( prefix -- assoc )
- vocab-roots get [
- over dupd dupd (all-child-vocabs)
- swap [ >vocab-link ] curry map
- ] { } map>assoc
- f rot unrooted-child-vocabs 2array add ;
-
-: load-children ( prefix -- )
- all-child-vocabs values concat
- filter-dangerous
- require-all
- load-failures. ;
-
-: vocab-status-string ( vocab -- string )
- {
- { [ dup not ] [ drop "" ] }
- { [ dup vocab-main ] [ drop "[Runnable]" ] }
- { [ t ] [ drop "[Loaded]" ] }
- } cond ;
-
-: write-status ( vocab -- )
- vocab vocab-status-string write ;
-
-: vocab. ( vocab -- )
- [
- dup [ write-status ] with-cell
- dup [ ($link) ] with-cell
- [ vocab-summary write ] with-cell
- ] with-row ;
-
-: vocab-headings. ( -- )
- [
- [ "State" write ] with-cell
- [ "Vocabulary" write ] with-cell
- [ "Summary" write ] with-cell
- ] with-row ;
-
-: root-heading. ( root -- )
- [ "Children from " swap append ] [ "Children" ] if*
- $heading ;
-
-: vocabs. ( assoc -- )
- [
- dup empty? [
- 2drop
- ] [
- swap root-heading.
- standard-table-style [
- vocab-headings. [ vocab. ] each
- ] ($grid)
- ] if
- ] assoc-each ;
-
-: describe-summary ( vocab -- )
- vocab-summary [
- "Summary" $heading print-element
- ] when* ;
-
-TUPLE: vocab-tag name ;
-
-C: <vocab-tag> vocab-tag
-
-: tags. ( seq -- ) [ <vocab-tag> ] map $links ;
-
-: describe-tags ( vocab -- )
- vocab-tags f like [
- "Tags" $heading tags.
- ] when* ;
-
-TUPLE: vocab-author name ;
-
-C: <vocab-author> vocab-author
-
-: authors. ( seq -- ) [ <vocab-author> ] map $links ;
-
-: describe-authors ( vocab -- )
- vocab-authors f like [
- "Authors" $heading authors.
- ] when* ;
-
-: describe-help ( vocab -- )
- vocab-help [
- "Documentation" $heading nl ($link)
- ] when* ;
-
-: describe-children ( vocab -- )
- vocab-name all-child-vocabs vocabs. ;
-
-: describe-files ( vocab -- )
- vocab-files [ <pathname> ] map [
- "Files" $heading
- [
- snippet-style get [
- code-style get [
- stack.
- ] with-nesting
- ] with-style
- ] ($block)
- ] when* ;
-
-: describe-words ( vocab -- )
- words dup empty? [
- "Words" $heading
- dup natural-sort $links
- ] unless drop ;
-
-: map>set ( seq quot -- )
- map concat prune natural-sort ; inline
-
-: vocab-xref ( vocab quot -- vocabs )
- >r dup vocab-name swap words r> map
- [ [ word? ] subset [ word-vocabulary ] map ] map>set
- remove [ ] subset [ vocab ] map ; inline
-
-: vocab-uses ( vocab -- vocabs ) [ uses ] vocab-xref ;
-
-: vocab-usage ( vocab -- vocabs ) [ usage ] vocab-xref ;
-
-: describe-uses ( vocab -- )
- vocab-uses dup empty? [
- "Uses" $heading
- dup $links
- ] unless drop ;
-
-: describe-usage ( vocab -- )
- vocab-usage dup empty? [
- "Used by" $heading
- dup $links
- ] unless drop ;
-
-: $describe-vocab ( element -- )
- first
- dup describe-children
- dup vocab-root over vocab-dir? [
- dup describe-summary
- dup describe-tags
- dup describe-authors
- dup describe-files
- ] when
- dup vocab [
- dup describe-help
- dup describe-words
- dup describe-uses
- dup describe-usage
- ] when drop ;
-
-: keyed-vocabs ( str quot -- seq )
- all-vocabs [
- swap >r
- [ >r 2dup r> swap call member? ] subset
- r> swap
- ] assoc-map 2nip ; inline
-
-: tagged ( tag -- assoc )
- [ vocab-tags ] keyed-vocabs ;
-
-: authored ( author -- assoc )
- [ vocab-authors ] keyed-vocabs ;
-
-: $tagged-vocabs ( element -- )
- first tagged vocabs. ;
-
-MEMO: all-tags ( -- seq )
- all-vocabs-seq [ vocab-tags ] map>set ;
-
-: $authored-vocabs ( element -- )
- first authored vocabs. ;
-
-MEMO: all-authors ( -- seq )
- all-vocabs-seq [ vocab-authors ] map>set ;
-
-: $tags ( element -- )
- drop "Tags" $heading all-tags tags. ;
-
-: $authors ( element -- )
- drop "Authors" $heading all-authors authors. ;
-
-M: vocab-spec article-title vocab-name " vocabulary" append ;
-
-M: vocab-spec article-name vocab-name ;
-
-M: vocab-spec article-content
- vocab-name \ $describe-vocab swap 2array ;
-
-M: vocab-spec article-parent drop "vocab-index" ;
-
-M: vocab-tag >link ;
-
-M: vocab-tag article-title
- vocab-tag-name "Vocabularies tagged ``" swap "''" 3append ;
-
-M: vocab-tag article-name vocab-tag-name ;
-
-M: vocab-tag article-content
- \ $tagged-vocabs swap vocab-tag-name 2array ;
-
-M: vocab-tag article-parent drop "vocab-index" ;
-
-M: vocab-tag summary article-title ;
-
-M: vocab-author >link ;
-
-M: vocab-author article-title
- vocab-author-name "Vocabularies by " swap append ;
-
-M: vocab-author article-name vocab-author-name ;
-
-M: vocab-author article-content
- \ $authored-vocabs swap vocab-author-name 2array ;
-
-M: vocab-author article-parent drop "vocab-index" ;
-
-M: vocab-author summary article-title ;
-
-: reset-cache ( -- )
- \ (vocab-file-contents) reset-memoized
- \ all-vocabs-seq reset-memoized
- \ all-authors reset-memoized
- \ all-tags reset-memoized ;
: ?, [ , ] [ drop ] if ;
-: bootstrap-profile ( config -- profile )
+: bootstrap-profile ( -- profile )
[
- [
- "math" deploy-math? get ?,
- "compiler" deploy-compiler? get ?,
- "ui" deploy-ui? get ?,
- "io" native-io? ?,
- ] { } make
- ] bind ;
+ "math" deploy-math? get ?,
+ "compiler" deploy-compiler? get ?,
+ "ui" deploy-ui? get ?,
+ "io" native-io? ?,
+ ] { } make ;
-: staging-image-name ( profile -- name )
- "staging." swap bootstrap-profile "-" join ".image" 3append ;
+: staging-image-name ( -- name )
+ "staging."
+ bootstrap-profile strip-word-names? [ "strip" add ] when
+ "-" join ".image" 3append ;
: staging-command-line ( config -- flags )
[
- "-i=" my-boot-image-name append ,
+ [
+ "-i=" my-boot-image-name append ,
- "-output-image=" over staging-image-name append ,
+ "-output-image=" staging-image-name append ,
- "-include=" swap bootstrap-profile " " join append ,
+ "-include=" bootstrap-profile " " join append ,
- "-no-stack-traces" ,
+ strip-word-names? [ "-no-stack-traces" , ] when
- "-no-user-init" ,
- ] { } make ;
+ "-no-user-init" ,
+ ] { } make
+ ] bind ;
: run-factor ( vm flags -- )
swap add* dup . run-with-output ; inline
: deploy-command-line ( image vocab config -- flags )
[
- "-i=" swap staging-image-name append ,
+ [
+ "-i=" staging-image-name append ,
- "-run=tools.deploy.shaker" ,
+ "-run=tools.deploy.shaker" ,
- "-deploy-vocab=" swap append ,
+ "-deploy-vocab=" swap append ,
- "-output-image=" swap append ,
+ "-output-image=" swap append ,
- "-no-stack-traces" ,
- ] { } make ;
+ strip-word-names? [ "-no-stack-traces" , ] when
+ ] { } make
+ ] bind ;
: make-deploy-image ( vm image vocab config -- )
make-boot-image
! See http://factorcode.org/license.txt for BSD license.
USING: vocabs.loader io.files io kernel sequences assocs
splitting parser prettyprint namespaces math vocabs
-hashtables tools.browser ;
+hashtables tools.vocabs ;
IN: tools.deploy.config
SYMBOL: deploy-name
IN: tools.deploy.tests\r
USING: tools.test system io.files kernel tools.deploy.config\r
-tools.deploy.backend math ;\r
+tools.deploy.backend math sequences io.launcher ;\r
\r
: shake-and-bake\r
"." resource-path [\r
vm\r
- "hello.image" temp-file\r
+ "test.image" temp-file\r
rot dup deploy-config make-deploy-image\r
] with-directory ;\r
\r
[ ] [ "hello-world" shake-and-bake ] unit-test\r
\r
[ t ] [\r
- "hello.image" temp-file file-length 500000 <=\r
+ "hello.image" temp-file file-info file-info-size 500000 <=\r
+] unit-test\r
+\r
+[ ] [ "sudoku" shake-and-bake ] unit-test\r
+\r
+[ t ] [\r
+ "hello.image" temp-file file-info file-info-size 1500000 <=\r
] unit-test\r
\r
[ ] [ "hello-ui" shake-and-bake ] unit-test\r
\r
[ t ] [\r
- "hello.image" temp-file file-length 2000000 <=\r
+ "hello.image" temp-file file-info file-info-size 2000000 <=\r
+] unit-test\r
+\r
+[ ] [ "bunny" shake-and-bake ] unit-test\r
+\r
+[ t ] [\r
+ "hello.image" temp-file file-info file-info-size 3000000 <=\r
+] unit-test\r
+\r
+[ ] [\r
+ "tools.deploy.test.1" shake-and-bake\r
+ vm "-i=" "test.image" temp-file append try-process\r
+] unit-test\r
+\r
+[ ] [\r
+ "tools.deploy.test.2" shake-and-bake\r
+ vm "-i=" "test.image" temp-file append try-process\r
] unit-test\r
-! Copyright (C) 2007 Slava Pestov.
+! Copyright (C) 2007, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces continuations.private kernel.private init
-assocs kernel vocabs words sequences memory io system arrays
-continuations math definitions mirrors splitting parser classes
-inspector layouts vocabs.loader prettyprint.config prettyprint
-debugger io.streams.c io.streams.duplex io.files io.backend
-quotations words.private tools.deploy.config compiler.units ;
+USING: qualified io.streams.c init fry namespaces assocs kernel
+parser tools.deploy.config vocabs sequences words words.private
+memory kernel.private continuations io prettyprint
+vocabs.loader debugger system strings ;
+QUALIFIED: bootstrap.stage2
+QUALIFIED: classes
+QUALIFIED: compiler.errors.private
+QUALIFIED: compiler.units
+QUALIFIED: continuations
+QUALIFIED: definitions
+QUALIFIED: init
+QUALIFIED: inspector
+QUALIFIED: io.backend
+QUALIFIED: io.nonblocking
+QUALIFIED: io.thread
+QUALIFIED: layouts
+QUALIFIED: libc.private
+QUALIFIED: libc.private
+QUALIFIED: listener
+QUALIFIED: prettyprint.config
+QUALIFIED: random.private
+QUALIFIED: source-files
+QUALIFIED: threads
+QUALIFIED: vocabs
IN: tools.deploy.shaker
: strip-init-hooks ( -- )
run-file
] when ;
-: strip-assoc ( retained-keys assoc -- newassoc )
- swap [ nip member? ] curry assoc-subset ;
-
: strip-word-names ( words -- )
"Stripping word names" show
[ f over set-word-name f swap set-word-vocabulary ] each ;
: strip-word-props ( retain-props words -- )
"Stripping word properties" show
[
- [ word-props strip-assoc f assoc-like ] keep
- set-word-props
+ [
+ word-props swap
+ '[ , nip member? ] assoc-subset
+ f assoc-like
+ ] keep set-word-props
] with each ;
: retained-props ( -- seq )
strip-word-names? [ dup strip-word-names ] when
2drop ;
-: strip-environment ( retain-globals -- )
+: strip-recompile-hook ( -- )
+ [ [ f ] { } map>assoc ]
+ compiler.units:recompile-hook
+ set-global ;
+
+: strip-vocab-globals ( except names -- words )
+ [ child-vocabs [ words ] map concat ] map concat seq-diff ;
+
+: stripped-globals ( -- seq )
+ [
+ random.private:mt ,
+
+ {
+ bootstrap.stage2:bootstrap-time
+ continuations:error
+ continuations:error-continuation
+ continuations:error-thread
+ continuations:restarts
+ error-hook
+ init:init-hooks
+ inspector:inspector-hook
+ io.thread:io-thread
+ libc.private:mallocs
+ source-files:source-files
+ stderr
+ stdio
+ } %
+
+ deploy-threads? [
+ threads:initial-thread ,
+ ] unless
+
+ strip-io? [ io.backend:io-backend , ] when
+
+ { io.backend:io-backend io.nonblocking:default-buffer-size }
+ { "alarms" "io" "tools" } strip-vocab-globals %
+
+ strip-dictionary? [
+ { } { "cpu" } strip-vocab-globals %
+
+ {
+ vocabs:dictionary
+ lexer-factory
+ vocabs:load-vocab-hook
+ layouts:num-tags
+ layouts:num-types
+ layouts:tag-mask
+ layouts:tag-numbers
+ layouts:type-numbers
+ classes:typemap
+ vocab-roots
+ definitions:crossref
+ compiled-crossref
+ interactive-vocabs
+ word
+ compiler.units:recompile-hook
+ listener:listener-hook
+ lexer-factory
+ classes:update-map
+ classes:class<map
+ } %
+ ] when
+
+ strip-prettyprint? [
+ {
+ prettyprint.config:margin
+ prettyprint.config:string-limit
+ prettyprint.config:tab-size
+ } %
+ ] when
+
+ strip-debugger? [
+ {
+ compiler.errors.private:compiler-errors
+ continuations:thread-error-hook
+ } %
+ ] when
+
+ deploy-c-types? get [
+ "c-types" "alien.c-types" lookup ,
+ ] unless
+
+ deploy-ui? get [
+ "ui-error-hook" "ui.gadgets.worlds" lookup ,
+ ] when
+ ] { } make ;
+
+: strip-globals ( stripped-globals -- )
strip-globals? [
- "Stripping environment" show
- global strip-assoc 21 setenv
+ "Stripping globals" show
+ global swap
+ '[ drop , member? not ] assoc-subset
+ [ drop string? not ] assoc-subset ! strip CLI args
+ dup keys .
+ 21 setenv
] [ drop ] if ;
: finish-deploy ( final-image -- )
] [ ] make "Boot quotation: " write dup . flush
set-boot-quot ;
-: retained-globals ( -- seq )
- [
- builtins ,
- strip-io? [ io-backend , ] unless
-
- strip-dictionary? [
- {
- dictionary
- inspector-hook
- lexer-factory
- load-vocab-hook
- num-tags
- num-types
- tag-bits
- tag-mask
- tag-numbers
- typemap
- vocab-roots
- } %
- ] unless
-
- strip-prettyprint? [
- {
- tab-size
- margin
- } %
- ] unless
-
- deploy-c-types? get [
- "c-types" "alien.c-types" lookup ,
- ] when
-
- native-io? [
- "default-buffer-size" "io.nonblocking" lookup ,
- ] when
-
- deploy-ui? get [
- "ui" child-vocabs
- "cocoa" child-vocabs
- deploy-vocab get child-vocabs 3append
- global keys [ word? ] subset
- swap [ >r word-vocabulary r> member? ] curry
- subset %
- ] when
- ] { } make dup . ;
-
-: strip-recompile-hook ( -- )
- [ [ f ] { } map>assoc ] recompile-hook set-global ;
-
: strip ( -- )
strip-libc
strip-cocoa
strip-init-hooks
deploy-vocab get vocab-main set-boot-quot*
retained-props >r
- retained-globals strip-environment
+ stripped-globals strip-globals
r> strip-words ;
: (deploy) ( final-image vocab config -- )
--- /dev/null
+IN: tools.deploy.test.1\r
+USING: threads ;\r
+\r
+: deploy-test-1 1000 sleep ;\r
+\r
+MAIN: deploy-test-1\r
--- /dev/null
+USING: tools.deploy.config ;
+H{
+ { deploy-c-types? f }
+ { deploy-io 2 }
+ { deploy-reflection 1 }
+ { deploy-threads? t }
+ { deploy-word-props? f }
+ { deploy-word-defs? f }
+ { deploy-name "tools.deploy.test.1" }
+ { deploy-math? t }
+ { deploy-compiler? t }
+ { "stop-after-last-window?" t }
+ { deploy-ui? f }
+}
--- /dev/null
+IN: tools.deploy.test.2\r
+USING: calendar calendar.format ;\r
+\r
+: deploy-test-2 now (timestamp>string) ;\r
+\r
+MAIN: deploy-test-2\r
--- /dev/null
+USING: tools.deploy.config ;
+H{
+ { deploy-c-types? f }
+ { deploy-io 2 }
+ { deploy-reflection 1 }
+ { deploy-threads? t }
+ { deploy-word-props? f }
+ { deploy-word-defs? f }
+ { deploy-name "tools.deploy.test.2" }
+ { deploy-math? t }
+ { deploy-compiler? t }
+ { "stop-after-last-window?" t }
+ { deploy-ui? f }
+}
--- /dev/null
+IN: tools.deploy.test.3\r
+USING: io.encodings.ascii io.files kernel ;\r
+\r
+: deploy-test-3\r
+ "resource:extra/tools/deploy/test/3/3.factor"\r
+ ?resource-path ascii file-contents drop ;\r
+\r
+MAIN: deploy-test-3\r
--- /dev/null
+USING: tools.deploy.config ;
+H{
+ { deploy-math? t }
+ { deploy-reflection 1 }
+ { deploy-name "tools.deploy.test.3" }
+ { deploy-threads? t }
+ { deploy-word-props? f }
+ { "stop-after-last-window?" t }
+ { deploy-ui? f }
+ { deploy-io 3 }
+ { deploy-compiler? t }
+ { deploy-word-defs? f }
+ { deploy-c-types? f }
+}
--- /dev/null
+IN: tools.disassembler.tests\r
+USING: math tuples prettyprint.backend tools.disassembler\r
+tools.test strings ;\r
+\r
+[ ] [ \ + disassemble ] unit-test\r
+[ ] [ { string pprint* } disassemble ] unit-test\r
! 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
-system math generator.fixup io.encodings.ascii accessors ;
+system math generator.fixup io.encodings.ascii accessors
+generic ;
IN: tools.disassembler
: in-file "gdb-in.txt" temp-file ;
[ number>string write bl ] each
] with-file-writer ;
+M: method-spec make-disassemble-cmd
+ first2 method make-disassemble-cmd ;
+
: run-gdb ( -- lines )
<process>
+closed+ >>stdin
vectors quotations words parser assocs combinators
continuations debugger io io.files vocabs tools.time
vocabs.loader source-files compiler.units inspector
-inference effects ;
+inference effects tools.vocabs ;
IN: tools.test
SYMBOL: failures
--- /dev/null
+Slava Pestov
--- /dev/null
+USING: help.markup help.syntax io strings ;
+IN: tools.vocabs.browser
+
+ARTICLE: "vocab-index" "Vocabulary index"
+{ $tags }
+{ $authors }
+{ $describe-vocab "" } ;
--- /dev/null
+IN: tools.vocabs.browser.tests
+USING: tools.vocabs.browser tools.test help.markup ;
+
+[ ] [ { $describe-vocab "scratchpad" } print-content ] unit-test
--- /dev/null
+! Copyright (C) 2007, 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel combinators vocabs vocabs.loader tools.vocabs io
+io.files io.styles help.markup help.stylesheet sequences assocs
+help.topics namespaces prettyprint words sorting definitions
+arrays inspector ;
+IN: tools.vocabs.browser
+
+: vocab-status-string ( vocab -- string )
+ {
+ { [ dup not ] [ drop "" ] }
+ { [ dup vocab-main ] [ drop "[Runnable]" ] }
+ { [ t ] [ drop "[Loaded]" ] }
+ } cond ;
+
+: write-status ( vocab -- )
+ vocab vocab-status-string write ;
+
+: vocab. ( vocab -- )
+ [
+ dup [ write-status ] with-cell
+ dup [ ($link) ] with-cell
+ [ vocab-summary write ] with-cell
+ ] with-row ;
+
+: vocab-headings. ( -- )
+ [
+ [ "State" write ] with-cell
+ [ "Vocabulary" write ] with-cell
+ [ "Summary" write ] with-cell
+ ] with-row ;
+
+: root-heading. ( root -- )
+ [ "Children from " swap append ] [ "Children" ] if*
+ $heading ;
+
+: vocabs. ( assoc -- )
+ [
+ dup empty? [
+ 2drop
+ ] [
+ swap root-heading.
+ standard-table-style [
+ vocab-headings. [ vocab. ] each
+ ] ($grid)
+ ] if
+ ] assoc-each ;
+
+: describe-summary ( vocab -- )
+ vocab-summary [
+ "Summary" $heading print-element
+ ] when* ;
+
+TUPLE: vocab-tag name ;
+
+INSTANCE: vocab-tag topic
+
+C: <vocab-tag> vocab-tag
+
+: tags. ( seq -- ) [ <vocab-tag> ] map $links ;
+
+: describe-tags ( vocab -- )
+ vocab-tags f like [
+ "Tags" $heading tags.
+ ] when* ;
+
+TUPLE: vocab-author name ;
+
+INSTANCE: vocab-author topic
+
+C: <vocab-author> vocab-author
+
+: authors. ( seq -- ) [ <vocab-author> ] map $links ;
+
+: describe-authors ( vocab -- )
+ vocab-authors f like [
+ "Authors" $heading authors.
+ ] when* ;
+
+: describe-help ( vocab -- )
+ vocab-help [
+ "Documentation" $heading nl ($link)
+ ] when* ;
+
+: describe-children ( vocab -- )
+ vocab-name all-child-vocabs vocabs. ;
+
+: describe-files ( vocab -- )
+ vocab-files [ <pathname> ] map [
+ "Files" $heading
+ [
+ snippet-style get [
+ code-style get [
+ stack.
+ ] with-nesting
+ ] with-style
+ ] ($block)
+ ] when* ;
+
+: describe-words ( vocab -- )
+ words dup empty? [
+ "Words" $heading
+ dup natural-sort $links
+ ] unless drop ;
+
+: vocab-xref ( vocab quot -- vocabs )
+ >r dup vocab-name swap words r> map
+ [ [ word? ] subset [ word-vocabulary ] map ] map>set
+ remove [ ] subset [ vocab ] map ; inline
+
+: vocab-uses ( vocab -- vocabs ) [ uses ] vocab-xref ;
+
+: vocab-usage ( vocab -- vocabs ) [ usage ] vocab-xref ;
+
+: describe-uses ( vocab -- )
+ vocab-uses dup empty? [
+ "Uses" $heading
+ dup $links
+ ] unless drop ;
+
+: describe-usage ( vocab -- )
+ vocab-usage dup empty? [
+ "Used by" $heading
+ dup $links
+ ] unless drop ;
+
+: $describe-vocab ( element -- )
+ first
+ dup describe-children
+ dup vocab-root over vocab-dir? [
+ dup describe-summary
+ dup describe-tags
+ dup describe-authors
+ dup describe-files
+ ] when
+ dup vocab [
+ dup describe-help
+ dup describe-words
+ dup describe-uses
+ dup describe-usage
+ ] when drop ;
+
+: keyed-vocabs ( str quot -- seq )
+ all-vocabs [
+ swap >r
+ [ >r 2dup r> swap call member? ] subset
+ r> swap
+ ] assoc-map 2nip ; inline
+
+: tagged ( tag -- assoc )
+ [ vocab-tags ] keyed-vocabs ;
+
+: authored ( author -- assoc )
+ [ vocab-authors ] keyed-vocabs ;
+
+: $tagged-vocabs ( element -- )
+ first tagged vocabs. ;
+
+: $authored-vocabs ( element -- )
+ first authored vocabs. ;
+
+: $tags ( element -- )
+ drop "Tags" $heading all-tags tags. ;
+
+: $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 \ $describe-vocab swap 2array ;
+
+M: vocab-spec article-parent drop "vocab-index" ;
+
+M: vocab-tag >link ;
+
+M: vocab-tag article-title
+ vocab-tag-name "Vocabularies tagged ``" swap "''" 3append ;
+
+M: vocab-tag article-name vocab-tag-name ;
+
+M: vocab-tag article-content
+ \ $tagged-vocabs swap vocab-tag-name 2array ;
+
+M: vocab-tag article-parent drop "vocab-index" ;
+
+M: vocab-tag summary article-title ;
+
+M: vocab-author >link ;
+
+M: vocab-author article-title
+ vocab-author-name "Vocabularies by " swap append ;
+
+M: vocab-author article-name vocab-author-name ;
+
+M: vocab-author article-content
+ \ $authored-vocabs swap vocab-author-name 2array ;
+
+M: vocab-author article-parent drop "vocab-index" ;
+
+M: vocab-author summary article-title ;
--- /dev/null
+Slava Pestov
--- /dev/null
+! Copyright (C) 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: threads io.files io.monitors init kernel\r
+vocabs.loader tools.vocabs namespaces continuations ;\r
+IN: tools.vocabs.monitor\r
+\r
+! Use file system change monitoring to flush the tags/authors\r
+! cache\r
+SYMBOL: vocab-monitor\r
+\r
+: monitor-thread ( -- )\r
+ vocab-monitor get-global\r
+ next-change 2drop\r
+ t sources-changed? set-global reset-cache ;\r
+\r
+: start-monitor-thread\r
+ #! Silently ignore errors during monitor creation since\r
+ #! monitors are not supported on all platforms.\r
+ [\r
+ "" resource-path t <monitor> vocab-monitor set-global\r
+ [ monitor-thread t ] "Vocabulary monitor" spawn-server drop\r
+ ] ignore-errors ;\r
+\r
+[ start-monitor-thread ] "tools.vocabs.monitor" add-init-hook\r
--- /dev/null
+Use io.monitors to clear tools.browser authors/tags/summary cache
--- /dev/null
+USING: help.markup help.syntax strings ;\r
+IN: tools.vocabs\r
+\r
+ARTICLE: "tools.vocabs" "Vocabulary tools"\r
+"Reloading source files changed on disk:"\r
+{ $subsection refresh }\r
+{ $subsection refresh-all }\r
+"Vocabulary summaries:"\r
+{ $subsection vocab-summary }\r
+{ $subsection set-vocab-summary }\r
+"Vocabulary tags:"\r
+{ $subsection vocab-tags }\r
+{ $subsection set-vocab-tags }\r
+{ $subsection add-vocab-tags }\r
+"Getting and setting vocabulary meta-data:"\r
+{ $subsection vocab-file-contents }\r
+{ $subsection set-vocab-file-contents }\r
+"Global meta-data:"\r
+{ $subsection all-vocabs }\r
+{ $subsection all-vocabs-seq }\r
+{ $subsection all-tags }\r
+{ $subsection all-authors }\r
+"Because loading the above data is expensive, it is cached. The cache is flushed by the " { $vocab-link "tools.vocabs.monitor" } " vocabulary. It can also be flushed manually when file system change monitors are not available:"\r
+{ $subsection reset-cache } ;\r
+\r
+ABOUT: "tools.vocabs"\r
+\r
+HELP: vocab-files\r
+{ $values { "vocab" "a vocabulary specifier" } { "seq" "a sequence of pathname strings" } }\r
+{ $description "Outputs a sequence of files comprising this vocabulary, or " { $link f } " if the vocabulary does not have a directory on disk." } ;\r
+\r
+HELP: vocab-tests\r
+{ $values { "vocab" "a vocabulary specifier" } { "tests" "a sequence of pathname strings" } }\r
+{ $description "Outputs a sequence of pathnames where the unit tests for " { $snippet "vocab" } " are located." } ;\r
+\r
+HELP: source-modified?\r
+{ $values { "path" "a pathname string" } { "?" "a boolean" } }\r
+{ $description "Tests if the source file has been modified since it was last loaded. This compares the file's CRC32 checksum of the file's contents against the previously-recorded value." } ;\r
+\r
+HELP: refresh\r
+{ $values { "prefix" string } }\r
+{ $description "Reloads source files and documentation belonging to loaded vocabularies whose names are prefixed by " { $snippet "prefix" } " which have been modified on disk." } ;\r
+\r
+HELP: refresh-all\r
+{ $description "Reloads source files and documentation for all loaded vocabularies which have been modified on disk." } ;\r
+\r
+{ refresh refresh-all } related-words\r
+\r
+HELP: vocab-file-contents\r
+{ $values { "vocab" "a vocabulary specifier" } { "name" string } { "seq" "a sequence of lines, or " { $link f } } }\r
+{ $description "Outputs the contents of the file named " { $snippet "name" } " from the vocabulary's directory, or " { $link f } " if the file does not exist." } ;\r
+\r
+HELP: set-vocab-file-contents\r
+{ $values { "seq" "a sequence of lines" } { "vocab" "a vocabulary specifier" } { "name" string } }\r
+{ $description "Stores a sequence of lines to the file named " { $snippet "name" } " from the vocabulary's directory." } ;\r
+\r
+HELP: vocab-summary\r
+{ $values { "vocab" "a vocabulary specifier" } { "summary" "a string or " { $link f } } }\r
+{ $description "Outputs a one-line string description of the vocabulary's intended purpose from the " { $snippet "summary.txt" } " file in the vocabulary's directory. Outputs " { $link f } " if the file does not exist." } ;\r
+\r
+HELP: set-vocab-summary\r
+{ $values { "string" "a string or " { $link f } } { "vocab" "a vocabulary specifier" } }\r
+{ $description "Stores a one-line string description of the vocabulary to the " { $snippet "summary.txt" } " file in the vocabulary's directory." } ;\r
+\r
+HELP: vocab-tags\r
+{ $values { "vocab" "a vocabulary specifier" } { "tags" "a sequence of strings" } }\r
+{ $description "Outputs a list of short tags classifying the vocabulary from the " { $snippet "tags.txt" } " file in the vocabulary's directory. Outputs " { $link f } " if the file does not exist." } ;\r
+\r
+HELP: set-vocab-tags\r
+{ $values { "tags" "a sequence of strings" } { "vocab" "a vocabulary specifier" } }\r
+{ $description "Stores a list of short tags classifying the vocabulary to the " { $snippet "tags.txt" } " file in the vocabulary's directory." } ;\r
+\r
+HELP: all-vocabs\r
+{ $values { "assoc" "an association list mapping vocabulary roots to sequences of vocabulary specifiers" } }\r
+{ $description "Outputs an association list of all vocabularies which have been loaded or are available for loading." } ;\r
--- /dev/null
+! Copyright (C) 2007, 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: io.files kernel io.encodings.utf8 vocabs.loader vocabs\r
+sequences namespaces math.parser arrays hashtables assocs\r
+memoize inspector sorting splitting combinators source-files\r
+io debugger continuations compiler.errors init io.crc32 ;\r
+IN: tools.vocabs\r
+\r
+: vocab-tests-file, ( vocab -- )\r
+ dup "-tests.factor" vocab-dir+ vocab-path+\r
+ dup resource-exists? [ , ] [ drop ] if ;\r
+\r
+: vocab-tests-dir, ( vocab -- )\r
+ dup vocab-dir "tests" path+ vocab-path+\r
+ dup resource-exists? [\r
+ dup ?resource-path directory keys\r
+ [ ".factor" tail? ] subset\r
+ [ path+ , ] with each\r
+ ] [ drop ] if ;\r
+\r
+: vocab-tests ( vocab -- tests )\r
+ dup vocab-root [\r
+ [\r
+ f >vocab-link dup\r
+ vocab-tests-file,\r
+ vocab-tests-dir,\r
+ ] { } make\r
+ ] [ drop f ] if ;\r
+\r
+: vocab-files ( vocab -- seq )\r
+ f >vocab-link [\r
+ dup vocab-source-path [ , ] when*\r
+ dup vocab-docs-path [ , ] when*\r
+ vocab-tests %\r
+ ] { } make ;\r
+\r
+: source-modified? ( path -- ? )\r
+ dup source-files get at [\r
+ dup source-file-path ?resource-path utf8 file-lines lines-crc32\r
+ swap source-file-checksum = not\r
+ ] [\r
+ resource-exists?\r
+ ] ?if ;\r
+\r
+: modified ( seq quot -- seq )\r
+ [ dup ] swap compose { } map>assoc\r
+ [ nip ] assoc-subset\r
+ [ nip source-modified? ] assoc-subset keys ; inline\r
+\r
+: modified-sources ( vocabs -- seq )\r
+ [ vocab-source-path ] modified ;\r
+\r
+: modified-docs ( vocabs -- seq )\r
+ [ vocab-docs-path ] modified ;\r
+\r
+: update-roots ( vocabs -- )\r
+ [ dup find-vocab-root swap vocab set-vocab-root ] each ;\r
+\r
+: to-refresh ( prefix -- modified-sources modified-docs )\r
+ child-vocabs\r
+ dup update-roots\r
+ dup modified-sources swap modified-docs ;\r
+\r
+: vocab-heading. ( vocab -- )\r
+ nl\r
+ "==== " write\r
+ dup vocab-name swap vocab write-object ":" print\r
+ nl ;\r
+\r
+: load-error. ( triple -- )\r
+ dup first vocab-heading.\r
+ dup second print-error\r
+ drop ;\r
+\r
+: load-failures. ( failures -- )\r
+ [ load-error. nl ] each ;\r
+\r
+SYMBOL: failures\r
+\r
+: require-all ( vocabs -- failures )\r
+ [\r
+ V{ } clone blacklist set\r
+ V{ } clone failures set\r
+ [\r
+ [ require ]\r
+ [ swap vocab-name failures get set-at ]\r
+ recover\r
+ ] each\r
+ failures get\r
+ ] with-compiler-errors ;\r
+\r
+: do-refresh ( modified-sources modified-docs -- )\r
+ 2dup\r
+ [ f swap set-vocab-docs-loaded? ] each\r
+ [ f swap set-vocab-source-loaded? ] each\r
+ append prune require-all load-failures. ;\r
+\r
+: refresh ( prefix -- ) to-refresh do-refresh ;\r
+\r
+SYMBOL: sources-changed?\r
+\r
+[ t sources-changed? set-global ] "tools.vocabs" add-init-hook\r
+\r
+: refresh-all ( -- )\r
+ "" refresh f sources-changed? set-global ;\r
+\r
+MEMO: (vocab-file-contents) ( path -- lines )\r
+ ?resource-path dup exists?\r
+ [ utf8 file-lines ] [ drop f ] if ;\r
+\r
+: vocab-file-contents ( vocab name -- seq )\r
+ vocab-path+ dup [ (vocab-file-contents) ] when ;\r
+\r
+: set-vocab-file-contents ( seq vocab name -- )\r
+ dupd vocab-path+ [\r
+ ?resource-path utf8 set-file-lines\r
+ ] [\r
+ "The " swap vocab-name\r
+ " vocabulary was not loaded from the file system"\r
+ 3append throw\r
+ ] ?if ;\r
+\r
+: vocab-summary-path ( vocab -- string )\r
+ vocab-dir "summary.txt" path+ ;\r
+\r
+: vocab-summary ( vocab -- summary )\r
+ dup dup vocab-summary-path vocab-file-contents\r
+ dup empty? [\r
+ drop vocab-name " vocabulary" append\r
+ ] [\r
+ nip first\r
+ ] if ;\r
+\r
+M: vocab summary\r
+ [\r
+ dup vocab-summary %\r
+ " (" %\r
+ vocab-words assoc-size #\r
+ " words)" %\r
+ ] "" make ;\r
+\r
+M: vocab-link summary vocab-summary ;\r
+\r
+: set-vocab-summary ( string vocab -- )\r
+ >r 1array r>\r
+ dup vocab-summary-path\r
+ set-vocab-file-contents ;\r
+\r
+: vocab-tags-path ( vocab -- string )\r
+ vocab-dir "tags.txt" path+ ;\r
+\r
+: vocab-tags ( vocab -- tags )\r
+ dup vocab-tags-path vocab-file-contents ;\r
+\r
+: set-vocab-tags ( tags vocab -- )\r
+ dup vocab-tags-path set-vocab-file-contents ;\r
+\r
+: add-vocab-tags ( tags vocab -- )\r
+ [ vocab-tags append prune ] keep set-vocab-tags ;\r
+\r
+: vocab-authors-path ( vocab -- string )\r
+ vocab-dir "authors.txt" path+ ;\r
+\r
+: vocab-authors ( vocab -- authors )\r
+ dup vocab-authors-path vocab-file-contents ;\r
+\r
+: set-vocab-authors ( authors vocab -- )\r
+ dup vocab-authors-path set-vocab-file-contents ;\r
+\r
+: subdirs ( dir -- dirs )\r
+ directory [ second ] subset keys natural-sort ;\r
+\r
+: (all-child-vocabs) ( root name -- vocabs )\r
+ [ vocab-dir path+ ?resource-path subdirs ] keep\r
+ dup empty? [\r
+ drop\r
+ ] [\r
+ swap [ "." swap 3append ] with map\r
+ ] if ;\r
+\r
+: vocabs-in-dir ( root name -- )\r
+ dupd (all-child-vocabs) [\r
+ 2dup vocab-dir? [ 2dup swap >vocab-link , ] when\r
+ vocabs-in-dir\r
+ ] with each ;\r
+\r
+: all-vocabs ( -- assoc )\r
+ vocab-roots get [\r
+ dup [ "" vocabs-in-dir ] { } make\r
+ ] { } map>assoc ;\r
+\r
+MEMO: all-vocabs-seq ( -- seq )\r
+ all-vocabs values concat ;\r
+\r
+: dangerous? ( name -- ? )\r
+ #! Hack\r
+ {\r
+ { [ "cpu." ?head ] [ t ] }\r
+ { [ "io.unix" ?head ] [ t ] }\r
+ { [ "io.windows" ?head ] [ t ] }\r
+ { [ "ui.x11" ?head ] [ t ] }\r
+ { [ "ui.windows" ?head ] [ t ] }\r
+ { [ "ui.cocoa" ?head ] [ t ] }\r
+ { [ "cocoa" ?head ] [ t ] }\r
+ { [ "core-foundation" ?head ] [ t ] }\r
+ { [ "vocabs.loader.test" ?head ] [ t ] }\r
+ { [ "editors." ?head ] [ t ] }\r
+ { [ ".windows" ?tail ] [ t ] }\r
+ { [ ".unix" ?tail ] [ t ] }\r
+ { [ "unix." ?head ] [ t ] }\r
+ { [ ".linux" ?tail ] [ t ] }\r
+ { [ ".bsd" ?tail ] [ t ] }\r
+ { [ ".macosx" ?tail ] [ t ] }\r
+ { [ "windows." ?head ] [ t ] }\r
+ { [ "cocoa" ?head ] [ t ] }\r
+ { [ ".test" ?tail ] [ t ] }\r
+ { [ "raptor" ?head ] [ t ] }\r
+ { [ dup "tools.deploy.app" = ] [ t ] }\r
+ { [ t ] [ f ] }\r
+ } cond nip ;\r
+\r
+: filter-dangerous ( seq -- seq' )\r
+ [ vocab-name dangerous? not ] subset ;\r
+\r
+: try-everything ( -- failures )\r
+ all-vocabs-seq\r
+ filter-dangerous\r
+ require-all ;\r
+\r
+: load-everything ( -- )\r
+ try-everything load-failures. ;\r
+\r
+: unrooted-child-vocabs ( prefix -- seq )\r
+ dup empty? [ CHAR: . add ] unless\r
+ vocabs\r
+ [ vocab-root not ] subset\r
+ [\r
+ vocab-name swap ?head CHAR: . rot member? not and\r
+ ] with subset\r
+ [ vocab ] map ;\r
+\r
+: all-child-vocabs ( prefix -- assoc )\r
+ vocab-roots get [\r
+ over dupd dupd (all-child-vocabs)\r
+ swap [ >vocab-link ] curry map\r
+ ] { } map>assoc\r
+ f rot unrooted-child-vocabs 2array add ;\r
+\r
+: all-child-vocabs-seq ( prefix -- assoc )\r
+ vocab-roots get swap [\r
+ dupd (all-child-vocabs)\r
+ [ vocab-dir? ] with subset\r
+ ] curry map concat ;\r
+\r
+: map>set ( seq quot -- )\r
+ map concat prune natural-sort ; inline\r
+\r
+MEMO: all-tags ( -- seq )\r
+ all-vocabs-seq [ vocab-tags ] map>set ;\r
+\r
+MEMO: all-authors ( -- seq )\r
+ all-vocabs-seq [ vocab-authors ] map>set ;\r
+\r
+: reset-cache ( -- )\r
+ \ (vocab-file-contents) reset-memoized\r
+ \ all-vocabs-seq reset-memoized\r
+ \ all-authors reset-memoized\r
+ \ all-tags reset-memoized ;\r
{ "updateFactorGadgetSize:" "void" { "id" "SEL" "id" }
[
[
- 2drop dup view-dim swap window set-gadget-dim
+ 2drop dup view-dim swap window set-gadget-dim yield
] ui-try
]
}
math math.vectors namespaces opengl opengl.gl prettyprint assocs
sequences io.files io.styles continuations freetype
ui.gadgets.worlds ui.render ui.backend byte-arrays ;
+
IN: ui.freetype
TUPLE: freetype-renderer ;
: open-face ( font style -- face )
ttf-name ttf-path
dup malloc-file-contents
- swap file-length
+ swap file-info file-info-size
(open-face) ;
SYMBOL: dpi
: stop-drag-timer ( -- )
hand-buttons get-global empty? [
- drag-timer get-global box> cancel-alarm
+ drag-timer get-global ?box
+ [ cancel-alarm ] [ drop ] if
] when ;
: fire-motion ( -- )
USING: ui.gadgets ui.gestures help.markup help.syntax
-kernel classes strings opengl.gl ;
+kernel classes strings opengl.gl models ;
IN: ui.render
HELP: gadget
{ { $link gadget-clipped? } " - a boolean indicating if clipping will be enabled when drawing this gadget's children." }
{ { $link gadget-interior } " - an object whose class implements the " { $link draw-interior } " generic word." }
{ { $link gadget-boundary } " - an object whose class implements the " { $link draw-boundary } " generic word." }
- { { $link gadget-model } " - XXX" }
+ { { $link gadget-model } " - a " { $link model } " or " { $link f } "; see " { $link "ui-control-impl" } }
}
"Gadgets delegate to " { $link rect } " instances holding their location and dimensions." }
{ $notes
editors tools.profiler tools.test tools.time tools.walker
ui.commands ui.gadgets.editors ui.gestures ui.operations
ui.tools.deploy vocabs vocabs.loader words sequences
-tools.browser classes compiler.units ;
+tools.vocabs classes compiler.units ;
IN: ui.tools.operations
V{ } clone operations set-global
{ +secondary+ t }
} define-operation
-[
- class
- { link word vocab vocab-link vocab-tag vocab-author }
- memq?
-] \ com-follow H{
+[ topic? ] \ com-follow H{
{ +keyboard+ T{ key-down f { C+ } "H" } }
{ +primary+ t }
} define-operation
tuples ui.commands ui.gadgets ui.gadgets.editors
ui.gadgets.lists ui.gadgets.scrollers ui.gadgets.tracks
ui.gestures ui.operations vocabs words vocabs.loader
-tools.browser unicode.case calendar ui ;
+tools.vocabs unicode.case calendar ui ;
IN: ui.tools.search
TUPLE: live-search field list ;
ui.gadgets.books ui.gadgets.buttons ui.gadgets.labelled
ui.gadgets.scrollers ui.gadgets.tracks ui.gadgets.worlds
ui.gadgets.presentations ui.gestures words vocabs.loader
-tools.test ui.gadgets.buttons ui.gadgets.status-bar mirrors ;
+tools.test tools.vocabs ui.gadgets.buttons ui.gadgets.status-bar
+mirrors ;
IN: ui.tools
: <workspace-tabs> ( -- tabs )
key-modifiers swap message>button
[ <button-down> ] [ <button-up> ] if ;
-: mouse-buttons ( -- seq ) WM_LBUTTONDOWN WM_RBUTTONDOWN 2array ;
-
-: capture-mouse? ( umsg -- ? )
- mouse-buttons member? ;
-
: prepare-mouse ( hWnd uMsg wParam lParam -- button coordinate world )
nip >r mouse-event>gesture r> >lo-hi rot window ;
mouse-captured off ;
: handle-wm-buttondown ( hWnd uMsg wParam lParam -- )
- >r >r dup capture-mouse? [ over set-capture ] when r> r>
- prepare-mouse send-button-down ;
+ >r >r
+ over set-capture
+ dup message>button drop nc-buttons get delete
+ r> r> prepare-mouse send-button-down ;
: handle-wm-buttonup ( hWnd uMsg wParam lParam -- )
mouse-captured get [ release-capture ] when
[ 4dup handle-wm-keydown DefWindowProc ] { WM_KEYDOWN WM_SYSKEYDOWN } add-wm-handler
[ 4dup handle-wm-char DefWindowProc ] { WM_CHAR WM_SYSCHAR } add-wm-handler
[ 4dup handle-wm-keyup DefWindowProc ] { WM_KEYUP WM_SYSKEYUP } add-wm-handler
-
+
[ handle-wm-syscommand ] WM_SYSCOMMAND add-wm-handler
[ handle-wm-set-focus 0 ] WM_SETFOCUS add-wm-handler
[ handle-wm-kill-focus 0 ] WM_KILLFOCUS add-wm-handler
-USING: system combinators vocabs.loader ;
+USING: layouts combinators vocabs.loader ;
IN: unix.stat
IN: unix.types
+! FreeBSD 7 x86.32
+
+! Need to verify on 64-bit
+
TYPEDEF: ushort __uint16_t
TYPEDEF: uint __uint32_t
TYPEDEF: int __int32_t
TYPEDEF: __int64_t off_t
TYPEDEF: __int64_t blkcnt_t
TYPEDEF: __uint32_t blksize_t
-TYPEDEF: __uint32_t fflags_t
\ No newline at end of file
+TYPEDEF: __uint32_t fflags_t
+TYPEDEF: int ssize_t
+TYPEDEF: int pid_t
+TYPEDEF: int time_t
\ No newline at end of file
+++ /dev/null
-Slava Pestov
+++ /dev/null
-! Copyright (C) 2008 Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: threads io.files io.monitors init kernel\r
-tools.browser namespaces continuations vocabs.loader ;\r
-IN: vocabs.monitor\r
-\r
-! Use file system change monitoring to flush the tags/authors\r
-! cache\r
-SYMBOL: vocab-monitor\r
-\r
-: monitor-thread ( -- )\r
- vocab-monitor get-global\r
- next-change 2drop\r
- t sources-changed? set-global reset-cache ;\r
-\r
-: start-monitor-thread\r
- #! Silently ignore errors during monitor creation since\r
- #! monitors are not supported on all platforms.\r
- [\r
- "" resource-path t <monitor> vocab-monitor set-global\r
- [ monitor-thread t ] "Vocabulary monitor" spawn-server drop\r
- ] ignore-errors ;\r
-\r
-[ start-monitor-thread ] "vocabs.monitor" add-init-hook\r
+++ /dev/null
-Use io.monitors to clear tools.browser authors/tags/summary cache
set iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
endif
-syn cluster factorCluster contains=factorComment,factorKeyword,factorRepeat,factorConditional,factorBoolean,factorString,factorSbuf,@factorNumber,@factorNumErr,factorDelimiter,factorChar,factorCharErr,factorBackslash,@factorWordOps,factorAlien,factorTuple
+syn cluster factorCluster contains=factorComment,factorKeyword,factorRepeat,factorConditional,factorBoolean,factorCompileDirective,factorString,factorSbuf,@factorNumber,@factorNumErr,factorDelimiter,factorChar,factorCharErr,factorBackslash,@factorWordOps,factorAlien,factorTuple
syn match factorTodo /\(TODO\|FIXME\|XXX\):\=/ contained
syn match factorComment /\<#! .*/ contains=factorTodo
syn match factorComment /\<! .*/ contains=factorTodo
-syn region None matchgroup=factorDefinition start=/\<\(C\|M\|G\|UNION\|PREDICATE\)\?:\>/ end=/\<;\>/ contains=@factorCluster,factorStackEffect,factorStackEffectErr,factorArray0,factorQuotation0
+syn cluster factorDefnContents contains=@factorCluster,factorStackEffect,factorArray0,factorQuotation0
+
+syn region factorDefn matchgroup=factorDefnDelims start=/\<\(MACRO\|MEMO\|:\)\?:\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents
+syn region factorMethod matchgroup=factorMethodDelims start=/\<M:\s\+\S\+\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents
+syn region factorGeneric matchgroup=factorGenericDelims start=/\<GENERIC:\s\+\S\+\>/ end=/$/ contains=factorStackEffect
+syn region factorGenericN matchgroup=factorGenericNDelims start=/\<GENERIC#\s\+\S\+\s\+\d\+\>/ end=/$/ contains=factorStackEffect
+
+syn region factorPrivateDefn matchgroup=factorPrivateDefnDelims start=/\<\(MACRO\|MEMO\|:\)\?:\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents contained
+syn region factorPrivateMethod matchgroup=factorPrivateMethodDelims start=/\<M:\s\+\S\+\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents contained
+syn region factorPGeneric matchgroup=factorPGenericDelims start=/\<GENERIC:\s\+\S\+\>/ end=/$/ contains=factorStackEffect contained
+syn region factorPGenericN matchgroup=factorPGenericNDelims start=/\<GENERIC#\s\+\S\+\s\+\d\+\>/ end=/$/ contains=factorStackEffect
+
+syn region None matchgroup=factorPrivate start=/\<<PRIVATE\>/ end=/\<PRIVATE>\>/ contains=@factorDefnContents,factorPrivateDefn,factorPrivateMethod,factorPGeneric,factorPGenericN
-syn region None matchgroup=factorGeneric start=/\<GENERIC:\>/ end=/$/ contains=factorStackEffect,factorStackEffectErr
syn keyword factorBoolean boolean f general-t t
syn keyword factorCompileDirective inline foldable parsing
" kernel vocab keywords
-syn keyword factorKeyword continuation-name set-datastack wrapper continuation-catch set-continuation-name slip pick 2slip 2nip tuple set-boot clone with-datastack cpu -roll tuck -rot (continue) set-continuation-retain swapd <continuation> >boolean wrapper? dupd 3dup dup ifcc callstack windows? os-env = over continuation alist>quot ? <wrapper> 2dup cond win64? <quotation> continue 3drop hashcode quotation xor when curry millis set-callstack unless >r die version callcc0 or os callcc1 get-walker-hook depth equal? 3keep no-cond? continue-with if exit tuple? set-retainstack unix? (continue-with) general-t continuation? 3slip <no-cond> macosx? r> rot win32? retainstack 2apply >quotation >continuation< type continuation-call clear call drop continuation-data set-continuation-call 2drop no-cond unit set-continuation-data keep-datastack and when* quotation? ?if literalize datastack swap unless* 2swap set-continuation-catch eq? not roll set-walker-hook continuation-retain with make-dip wrapped keep 2keep <=> if* nip
-syn keyword factorKeyword sin integer? log2 cot oct> number>string integer first-bignum sech abs repeat tanh real? vmin norm-sq neg between? asech >rect bignum? atanh -i * + fp-nan? - small / sqrt infimum fix-float cosech even? v*n < bits>double > most-positive-fixnum ^theta numerator digit+ >base (random-int) acosech cosh min pi number vmax zero? sum digit> rem bitor supremum string>integer most-negative-fixnum >polar >fraction ceiling acos acot ^ asin acosh /f ratio e fixnum? /i ^n cis coth 1+ 1- conjugate sinh acosec i number= number? double>bits epsilon float product string>number n/v norm max tan acoth absq float? asinh denominator rational? fixnum rect> >fixnum imaginary recip exp sec bitxor w>h/h >bin align base> times log <= [-] init-random sq odd? (repeat) [v-] ^mag bitnot ratio? random-int >digit (next-power-of-2) v* v+ v- v. v/ >float [-1,1]? arg small? bitand set-axis >oct v/n complex rational shift (^) polar> (gcd) cosec next-power-of-2 >float-rect atan sgn >= float>bits normalize real bin> complex? gcd d>w/w hex> mod string>ratio asec floor n*v >hex truncate bits>float vneg >bignum bignum power-of-2? integer, /mod (string>integer) cos
-syn keyword factorKeyword second sort-values all-eq? pop* find slice-error-reason inject-with prune remove (group) split1-slice slice-error (slice*) split* head-slice* find* split, first remove-nth hash-prune push-if ?push reverse subseq split1 diff subset split new padding column? copy-into-check column@ <column> peek last/first add find-last ?nth add* slice-from cache-nth subseq? <reversed> <slice-error> (3append) replace-slice reversed-seq find-last-with empty? ((append)) reversed? reversed@ map-with find-last-with* set-slice-error-reason set-column-col natural-sort (subst) set-slice-seq index* concat push binsearch slice-seq 3append nsort length tail-slice* reversed ?head sequence= ?tail sequence? memq? join split-next, delete set-nth subst monotonic? group map flip unclip set-reversed-seq find-last* start* max-length assoc min-length all-equal? all? pad-left contains? inject slice <slice> first2 first3 first4 exchange bounds-check? column-seq check-slice pad-right each subset-with unpair tail head interleave (delete) copy-into sort sequence reduce set-slice-from set-slice-to 2map (cut) member? cut rassoc (append) last-index* sort-keys change-nth 2each >sequence nth tail* head* third tail-slice set-length collapse-slice column (mismatch) contains-with? push-new pop tail? head? slice? slice@ delete-all binsearch* move find-with* 2reduce slice-to find-with like slice-error? set-column-seq nappend column-col cut* (split) index each-with last-index fourth append accumulate drop-prefix mismatch head-slice all-with? start
-syn keyword factorKeyword namespace-error-object inc dec make off bind get-global init-namespaces set-global namespace on ndrop namespace-error? namestack namespace-error +@ # % make-hash global , set-namestack with-scope building <namespace-error> change nest set-namespace-error-object get set counter
-syn keyword factorKeyword array <array> pair byte-array pair? 1array 2array resize-array 4array 3array byte-array? <byte-array> array? >array
-syn keyword factorKeyword cwd duplex-stream pathname? set-pathname-string with-log-file directory duplex-stream-out format <nested-style-stream> (readln) duplex-stream? read1 with-stream-style c-stream-error? <file-reader> stream-write1 with-stream line-reader? set-duplex-stream-out server? cr> <check-closed> directory? log-message flush format-column stream-readln nested-style-stream? <line-reader> <file-r/w> set-timeout write-pathname file-modified duplex-stream-closed? print set-duplex-stream-closed? pathname line-reader ?resource-path terpri write-object le> string-out stream-terpri log-client do-nested-style path+ <c-stream-error> set-client-stream-host plain-writer? server-stream resource-path >be parent-dir with-stream* <file-writer> server-loop string-in nested-style-stream stream-close stream-copy c-stream-error <client-stream> with-style client-stream-host stat plain-writer file-length contents <string-reader> stream-read stream-format check-closed? set-client-stream-port <duplex-stream> <server> write1 bl write-outliner map-last (with-stream-style) set-line-reader-cr tabular-output (lines) stream-write log-stream server-client (stream-copy) with-nested-stream lines readln cd client-stream nth-byte with-logging stream-read1 nested-style-stream-style accept check-closed client-stream-port do-nested-quot pathname-string set-nested-style-stream-style read home close with-stream-table stdio be> log-error duplex-stream-out+ server stream-flush set-duplex-stream-in line-reader-cr >le with-client <client> <pathname> <string-writer> (directory) set-server-client stream-print with-server exists? <plain-writer> with-nesting string-lines write duplex-stream-in client-stream? duplex-stream-in+
-syn keyword factorKeyword sbuf ch>upper string? LETTER? >sbuf >lower quotable? string>sbuf blank? string sbuf? printable? >string letter? resize-string control? alpha? <string> >upper Letter? ch>lower digit? <sbuf> ch>string
-syn keyword factorKeyword <vector> >vector array>vector vector? vector
-syn keyword factorKeyword set-restart-continuation cleanup error-hook restart-name restarts. stack-underflow. expired-error. restart restart? word-xt. (:help-none) set-catchstack c-string-error. condition <assert> debug-help :get datastack-overflow. set-condition-restarts condition? error. objc-error. print-error assert :res catchstack rethrow assert= kernel-error restart-obj assert? undefined-symbol-error. retainstack-overflow. restarts error-help divide-by-zero-error. ffi-error. signal-error. (:help-multi) set-restart-obj xt. memory-error. retainstack-underflow. set-condition-continuation datastack-underflow. try assert-depth error-continuation error-stack-trace assert-expect recover :edit kernel-error? error callstack-overflow. stack-overflow. callstack-underflow. set-assert-got set-restart-name restart-continuation condition-restarts heap-scan-error. :help type-check-error. <condition> assert-got throw negative-array-size-error. :c condition-continuation :trace undefined-word-error. io-error. parse-dump <restart> set-assert-expect :r :s compute-restarts catch restart.
+syn keyword factorKeyword or construct-delegate set-slots tuck while wrapper nip hashcode wrapper? both? callstack>array die dupd set-delegate callstack callstack? 3dup pick curry build >boolean ?if clone eq? = ? swapd call-clear 2over 2keep 3keep construct general-t clear 2dup when not tuple? 3compose dup call object wrapped unless* if* 2apply >r curry-quot drop when* retainstack -rot delegate with 3slip construct-boa slip compose-first compose-second 3drop construct-empty either? curry? datastack compare curry-obj over 3curry roll throw swap and 2nip set-retainstack (clone) hashcode* get-slots compose spin if <=> unless compose? tuple keep 2curry object? equal? set-datastack 2slip 2drop most <wrapper> null r> set-callstack dip xor rot -roll
+syn keyword factorKeyword assoc? assoc-clone-like delete-any assoc= delete-at* new-assoc subassoc? assoc-size map>assoc union search-alist assoc-like key? update at* assoc-empty? at+ set-at assoc-all? assoc-hashcode intersect change-at assoc-each assoc-subset values rename-at value-at (assoc-stack) at cache assoc>map assoc-contains? assoc assoc-map assoc-pusher diff (assoc>map) assoc-push-if remove-all >alist (substitute) substitute-here clear-assoc assoc-stack substitute delete-at assoc-find keys
+syn keyword factorKeyword case dispatch-case-quot with-datastack alist>quot dispatch-case hash-case-table <buckets> hash-case-quot no-cond no-case? cond distribute-buckets (distribute-buckets) contiguous-range? cond>quot no-cond? no-case recursive-hashcode linear-case-quot hash-dispatch-quot case>quot
+syn keyword factorKeyword byte-array>bignum sgn >bignum number= each-integer next-power-of-2 before? imaginary-part mod recip float>bits rational >float number? 2^ bignum? integer fixnum? after? fixnum before=? bignum sq neg denominator [-] (all-integers?) times find-last-integer (each-integer) bit? * + - / >= bitand find-integer complex < real > log2 integer? max number bits>double double>bits bitor 2/ zero? rem all-integers? (find-integer) real-part align bits>float float? shift between? float 1+ 1- min fp-nan? ratio? bitxor even? ratio <= /mod >integer odd? rational? bitnot real? >fixnum complex? (next-power-of-2) /i numerator after=? /f
+syn keyword factorKeyword slice-to append left-trim clone-like 3sequence set-column-seq map-as reversed pad-left cut* nth sequence slice? <slice> tail-slice empty? tail* member? unclip virtual-sequence? set-length last-index* <column> drop-prefix bounds-error? set-slice-seq set-column-col seq-diff map start open-slice midpoint@ add* set-immutable-seq move-forward fourth delete set-slice-to all-eq? monotonic? set-reversed-seq like delete-nth first4 repetition-len (open-slice) column? reverse slice padding virtual@ repetition? index 4sequence max-length set-second first2 first3 (3append) supremum unclip-slice index* move-backward tail 3append sequence-hashcode-step right-trim reversed-seq pad-right concat find* set-slice-from flip sum find-last* immutable? 2sequence delete-all start* immutable-sequence? (append) check-slice column-seq sequence? head set-slice-error-reason reduce set-bounds-error-index reverse-here sequence= halves collapse-slice interleave 2map binary-reduce virtual-seq slice-error? product bounds-check? bounds-check immutable find column remove ((append)) set-fourth peek contains? reversed? shorter? push-new find-last head-slice pop* immutable-seq tail-slice* accumulate each pusher all-equal? new-resizable cut-slice head-slice* 2reverse-each pop memq? set-nth ?nth <flat-slice> second change-each join set-repetition-len <reversed> all? virtual-sequence set-repetition-elt subseq? immutable-sequence slice-error-reason new-like length last-index seq-intersect push-if 2all? lengthen column-col joined-length copy set-bounds-error-seq cache-nth move third first slice-from repetition-elt tail? set-first bounds-error add bounds-error-seq bounds-error-index <repetition> unfold exchange slice-seq cut 2reduce change-nth min-length set-third (delete) push-all head? delete-slice sum-lengths new 2each head* infimum subset slice-error subseq replace-slice repetition push trim sequence-hashcode mismatch
+syn keyword factorKeyword global +@ set-namestack with-variable on set bind dec namestack get get-global change init-namespaces with-scope off set-global namespace % make , inc counter building make-assoc
+syn keyword factorKeyword <array> 3array >array 4array pair? array pair 2array 1array resize-array array?
+syn keyword factorKeyword readln stream-read-until stream-read-partial stderr with-stream read with-stream* print contents make-span-stream write1 stream-write1 stream-format make-block-stream stream-copy with-cell stream-write format with-row stream-print stream-read with-nesting (stream-copy) bl write-object nl stream-nl write stdio flush read-until tabular-output make-cell-stream write-cell stream-flush read1 lines stream-read1 stream-write-table with-style stream-readln
+syn keyword factorKeyword resize-string >string <string> 1string string string?
+syn keyword factorKeyword vector? <vector> ?push vector >vector 1vector
+syn keyword factorKeyword rethrow-restarts restarts recover set-restart-name set-continuation-name condition-continuation <restart> ifcc continuation-name set-restart-continuation ignore-errors continuation-retain continue <continuation> restart-continuation with-disposal set-continuation-catch restart-obj error thread-error-hook set-continuation-retain continuation rethrow callcc1 callcc0 condition continuation? continuation-call continuation-data set-condition-restarts set-catchstack >continuation< error-continuation cleanup restart? compute-restarts condition? error-thread set-continuation-call set-condition-continuation <condition> set-restart-obj dispose set-continuation-data throw-restarts catchstack continue-with attempt-all restart restart-name continuation-catch condition-restarts
syn cluster factorReal contains=factorInt,factorFloat,factorRatio,factorBinary,factorHex,factorOctal
syn region factorUsing start=/\<USING:\>/ end=/;/
syn region factorRequires start=/\<REQUIRES:\>/ end=/;/
-syn cluster factorWordOps contains=factorSymbol,factorPostpone,factorDefer,factorForget
+syn cluster factorWordOps contains=factorSymbol,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
syn match factorSymbol /\<SYMBOL:\s\+\S\+\>/
syn match factorPostpone /\<POSTPONE:\s\+\S\+\>/
syn match factorDefer /\<DEFER:\s\+\S\+\>/
syn match factorForget /\<FORGET:\s\+\S\+\>/
+syn match factorMixin /\<MIXIN:\s\+\S\+\>/
+syn match factorInstance /\<INSTANCE:\s\+\S\+\s\+\S\+\>/
+syn match factorHook /\<HOOK:\s\+\S\+\s\+\S\+\>/
+syn match factorMain /\<MAIN:\s\+\S\+\>/
+syn match factorConstructor /\<C:\s\+\S\+\s\+\S\+\>/
syn match factorAlien /\<ALIEN:\s\+\d\+\>/
"misc:
" HELP:
" ARTICLE:
-" PROVIDE:
-" MAIN:
"literals:
" PRIMITIVE:
syn region factorString start=/"/ skip=/\\"/ end=/"/ oneline
syn region factorSbuf start=/SBUF" / skip=/\\"/ end=/"/ oneline
-syn match factorStackEffectErr /\<)\>/
-syn region factorStackEffectErr start=/\<(\>/ end=/\<)\>/
+syn region factorMultiString matchgroup=factorMultiStringDelims start=/\<STRING:\s\+\S\+\>/ end=/^;$/ contains=factorMultiStringContents
+syn match factorMultiStringContents /.*/ contained
+
+"syn match factorStackEffectErr /\<)\>/
+"syn region factorStackEffectErr start=/\<(\>/ end=/\<)\>/
syn region factorStackEffect start=/\<(\>/ end=/\<)\>/ contained
"adapted from lisp.vim
endif
if exists("g:factor_norainbow")
- syn region factorArray matchgroup=factorDelimiter start=/\<\(V\|H\|T\|W\)\?{\>/ matchgroup=factorDelimiter end=/\<}\>/ contains=ALL
+ syn region factorArray matchgroup=factorDelimiter start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ matchgroup=factorDelimiter end=/\<}\>/ contains=ALL
else
- syn region factorArray0 matchgroup=hlLevel0 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray1,factorQuotation1
- syn region factorArray1 contained matchgroup=hlLevel1 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray2,factorQuotation2
- syn region factorArray2 contained matchgroup=hlLevel2 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray3,factorQuotation3
- syn region factorArray3 contained matchgroup=hlLevel3 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray4,factorQuotation4
- syn region factorArray4 contained matchgroup=hlLevel4 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray5,factorQuotation5
- syn region factorArray5 contained matchgroup=hlLevel5 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray6,factorQuotation6
- syn region factorArray6 contained matchgroup=hlLevel6 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray7,factorQuotation7
- syn region factorArray7 contained matchgroup=hlLevel7 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray8,factorQuotation8
- syn region factorArray8 contained matchgroup=hlLevel8 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray9,factorQuotation9
- syn region factorArray9 contained matchgroup=hlLevel9 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray0,factorQuotation0
+ syn region factorArray0 matchgroup=hlLevel0 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray1,factorQuotation1
+ syn region factorArray1 contained matchgroup=hlLevel1 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray2,factorQuotation2
+ syn region factorArray2 contained matchgroup=hlLevel2 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray3,factorQuotation3
+ syn region factorArray3 contained matchgroup=hlLevel3 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray4,factorQuotation4
+ syn region factorArray4 contained matchgroup=hlLevel4 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray5,factorQuotation5
+ syn region factorArray5 contained matchgroup=hlLevel5 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray6,factorQuotation6
+ syn region factorArray6 contained matchgroup=hlLevel6 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray7,factorQuotation7
+ syn region factorArray7 contained matchgroup=hlLevel7 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray8,factorQuotation8
+ syn region factorArray8 contained matchgroup=hlLevel8 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray9,factorQuotation9
+ syn region factorArray9 contained matchgroup=hlLevel9 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray0,factorQuotation0
endif
syn match factorBracketErr /\<\]\>/
HiLink factorKeyword Keyword
HiLink factorOperator Operator
HiLink factorBoolean Boolean
- HiLink factorDefinition Typedef
+ HiLink factorDefnDelims Typedef
+ HiLink factorMethodDelims Typedef
+ HiLink factorGenericDelims Typedef
+ HiLink factorGenericNDelims Typedef
+ HiLink factorConstructor Typedef
+ HiLink factorPrivate Special
+ HiLink factorPrivateDefnDelims Special
+ HiLink factorPrivateMethodDelims Special
+ HiLink factorPGenericDelims Special
+ HiLink factorPGenericNDelims Special
HiLink factorString String
HiLink factorSbuf String
+ HiLink factorMultiStringContents String
+ HiLink factorMultiStringDelims Typedef
HiLink factorBracketErr Error
- HiLink factorStackEffectErr Error
HiLink factorComplex Number
HiLink factorRatio Number
HiLink factorBinary Number
HiLink factorCharErr Error
HiLink factorDelimiter Delimiter
HiLink factorBackslash Special
- HiLink factorCompileDirective Keyword
+ HiLink factorCompileDirective Typedef
HiLink factorSymbol Define
+ HiLink factorMixin Typedef
+ HiLink factorInstance Typedef
+ HiLink factorHook Typedef
+ HiLink factorMain Define
HiLink factorPostpone Define
HiLink factorDefer Define
HiLink factorForget Define
HiLink factorAlien Define
HiLink factorTuple Typedef
- HiLink factorGeneric Define
if &bg == "dark"
hi hlLevel0 ctermfg=red guifg=red1
set autoindent " annoying?
" vim: syntax=vim
+
-<% USING: kernel io prettyprint words sequences ;
+<% USING: kernel io prettyprint vocabs sequences ;
%>" Vim syntax file
" Language: factor
" Maintainer: Alex Chapman <chapman.alex@gmail.com>
set iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
endif
-syn cluster factorCluster contains=factorComment,factorKeyword,factorRepeat,factorConditional,factorBoolean,factorString,factorSbuf,@factorNumber,@factorNumErr,factorDelimiter,factorChar,factorCharErr,factorBackslash,@factorWordOps,factorAlien,factorTuple
+syn cluster factorCluster contains=factorComment,factorKeyword,factorRepeat,factorConditional,factorBoolean,factorCompileDirective,factorString,factorSbuf,@factorNumber,@factorNumErr,factorDelimiter,factorChar,factorCharErr,factorBackslash,@factorWordOps,factorAlien,factorTuple
syn match factorTodo /\(TODO\|FIXME\|XXX\):\=/ contained
syn match factorComment /\<#! .*/ contains=factorTodo
syn match factorComment /\<! .*/ contains=factorTodo
-syn region None matchgroup=factorDefinition start=/\<\(C\|M\|G\|UNION\|PREDICATE\)\?:\>/ end=/\<;\>/ contains=@factorCluster,factorStackEffect,factorStackEffectErr,factorArray0,factorQuotation0
+syn cluster factorDefnContents contains=@factorCluster,factorStackEffect,factorArray0,factorQuotation0
+
+syn region factorDefn matchgroup=factorDefnDelims start=/\<\(MACRO\|MEMO\|:\)\?:\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents
+syn region factorMethod matchgroup=factorMethodDelims start=/\<M:\s\+\S\+\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents
+syn region factorGeneric matchgroup=factorGenericDelims start=/\<GENERIC:\s\+\S\+\>/ end=/$/ contains=factorStackEffect
+syn region factorGenericN matchgroup=factorGenericNDelims start=/\<GENERIC#\s\+\S\+\s\+\d\+\>/ end=/$/ contains=factorStackEffect
+
+syn region factorPrivateDefn matchgroup=factorPrivateDefnDelims start=/\<\(MACRO\|MEMO\|:\)\?:\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents contained
+syn region factorPrivateMethod matchgroup=factorPrivateMethodDelims start=/\<M:\s\+\S\+\s\+\S\+\>/ end=/\<;\>/ contains=@factorDefnContents contained
+syn region factorPGeneric matchgroup=factorPGenericDelims start=/\<GENERIC:\s\+\S\+\>/ end=/$/ contains=factorStackEffect contained
+syn region factorPGenericN matchgroup=factorPGenericNDelims start=/\<GENERIC#\s\+\S\+\s\+\d\+\>/ end=/$/ contains=factorStackEffect
+
+syn region None matchgroup=factorPrivate start=/\<<PRIVATE\>/ end=/\<PRIVATE>\>/ contains=@factorDefnContents,factorPrivateDefn,factorPrivateMethod,factorPGeneric,factorPGenericN
-syn region None matchgroup=factorGeneric start=/\<GENERIC:\>/ end=/$/ contains=factorStackEffect,factorStackEffectErr
syn keyword factorBoolean boolean f general-t t
syn keyword factorCompileDirective inline foldable parsing
! that this changes factor.vim from around 8k to around 100k (and is a bit
! broken)
-! vocabs [ words [ "syn keyword factorKeyword " write [ pprint " " write ] each "\n" write ] when* ] each %>
+! vocabs [ words [ "syn keyword factorKeyword " write [ pprint " " write ] each "\n" write ] when* ] each
+%>
" kernel vocab keywords
-<% { "kernel" "math" "sequences" "namespaces" "arrays" "io" "strings" "vectors" "errors" } [ words "syn keyword factorKeyword " write [ pprint " " write ] each "\n" write ] each %>
+<% { "kernel" "assocs" "combinators" "math" "sequences" "namespaces" "arrays" "io" "strings" "vectors" "continuations" } [
+ words "syn keyword factorKeyword " write [ pprint " " write ] each "\n" write
+ ] each %>
syn cluster factorReal contains=factorInt,factorFloat,factorRatio,factorBinary,factorHex,factorOctal
syn cluster factorNumber contains=@factorReal,factorComplex
syn region factorUsing start=/\<USING:\>/ end=/;/
syn region factorRequires start=/\<REQUIRES:\>/ end=/;/
-syn cluster factorWordOps contains=factorSymbol,factorPostpone,factorDefer,factorForget
+syn cluster factorWordOps contains=factorSymbol,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
syn match factorSymbol /\<SYMBOL:\s\+\S\+\>/
syn match factorPostpone /\<POSTPONE:\s\+\S\+\>/
syn match factorDefer /\<DEFER:\s\+\S\+\>/
syn match factorForget /\<FORGET:\s\+\S\+\>/
+syn match factorMixin /\<MIXIN:\s\+\S\+\>/
+syn match factorInstance /\<INSTANCE:\s\+\S\+\s\+\S\+\>/
+syn match factorHook /\<HOOK:\s\+\S\+\s\+\S\+\>/
+syn match factorMain /\<MAIN:\s\+\S\+\>/
+syn match factorConstructor /\<C:\s\+\S\+\s\+\S\+\>/
syn match factorAlien /\<ALIEN:\s\+\d\+\>/
"misc:
" HELP:
" ARTICLE:
-" PROVIDE:
-" MAIN:
"literals:
" PRIMITIVE:
syn region factorString start=/"/ skip=/\\"/ end=/"/ oneline
syn region factorSbuf start=/SBUF" / skip=/\\"/ end=/"/ oneline
-syn match factorStackEffectErr /\<)\>/
-syn region factorStackEffectErr start=/\<(\>/ end=/\<)\>/
+syn region factorMultiString matchgroup=factorMultiStringDelims start=/\<STRING:\s\+\S\+\>/ end=/^;$/ contains=factorMultiStringContents
+syn match factorMultiStringContents /.*/ contained
+
+"syn match factorStackEffectErr /\<)\>/
+"syn region factorStackEffectErr start=/\<(\>/ end=/\<)\>/
syn region factorStackEffect start=/\<(\>/ end=/\<)\>/ contained
"adapted from lisp.vim
endif
if exists("g:factor_norainbow")
- syn region factorArray matchgroup=factorDelimiter start=/\<\(V\|H\|T\|W\)\?{\>/ matchgroup=factorDelimiter end=/\<}\>/ contains=ALL
+ syn region factorArray matchgroup=factorDelimiter start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ matchgroup=factorDelimiter end=/\<}\>/ contains=ALL
else
- syn region factorArray0 matchgroup=hlLevel0 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray1,factorQuotation1
- syn region factorArray1 contained matchgroup=hlLevel1 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray2,factorQuotation2
- syn region factorArray2 contained matchgroup=hlLevel2 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray3,factorQuotation3
- syn region factorArray3 contained matchgroup=hlLevel3 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray4,factorQuotation4
- syn region factorArray4 contained matchgroup=hlLevel4 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray5,factorQuotation5
- syn region factorArray5 contained matchgroup=hlLevel5 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray6,factorQuotation6
- syn region factorArray6 contained matchgroup=hlLevel6 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray7,factorQuotation7
- syn region factorArray7 contained matchgroup=hlLevel7 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray8,factorQuotation8
- syn region factorArray8 contained matchgroup=hlLevel8 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray9,factorQuotation9
- syn region factorArray9 contained matchgroup=hlLevel9 start=/\<\(V\|H\|T\|W\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray0,factorQuotation0
+ syn region factorArray0 matchgroup=hlLevel0 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray1,factorQuotation1
+ syn region factorArray1 contained matchgroup=hlLevel1 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray2,factorQuotation2
+ syn region factorArray2 contained matchgroup=hlLevel2 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray3,factorQuotation3
+ syn region factorArray3 contained matchgroup=hlLevel3 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray4,factorQuotation4
+ syn region factorArray4 contained matchgroup=hlLevel4 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray5,factorQuotation5
+ syn region factorArray5 contained matchgroup=hlLevel5 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray6,factorQuotation6
+ syn region factorArray6 contained matchgroup=hlLevel6 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray7,factorQuotation7
+ syn region factorArray7 contained matchgroup=hlLevel7 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray8,factorQuotation8
+ syn region factorArray8 contained matchgroup=hlLevel8 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray9,factorQuotation9
+ syn region factorArray9 contained matchgroup=hlLevel9 start=/\<\(V\|H\|T\|W\|F\|B\)\?{\>/ end=/\<}\>/ contains=@factorCluster,factorArray0,factorQuotation0
endif
syn match factorBracketErr /\<\]\>/
HiLink factorKeyword Keyword
HiLink factorOperator Operator
HiLink factorBoolean Boolean
- HiLink factorDefinition Typedef
+ HiLink factorDefnDelims Typedef
+ HiLink factorMethodDelims Typedef
+ HiLink factorGenericDelims Typedef
+ HiLink factorGenericNDelims Typedef
+ HiLink factorConstructor Typedef
+ HiLink factorPrivate Special
+ HiLink factorPrivateDefnDelims Special
+ HiLink factorPrivateMethodDelims Special
+ HiLink factorPGenericDelims Special
+ HiLink factorPGenericNDelims Special
HiLink factorString String
HiLink factorSbuf String
+ HiLink factorMultiStringContents String
+ HiLink factorMultiStringDelims Typedef
HiLink factorBracketErr Error
- HiLink factorStackEffectErr Error
HiLink factorComplex Number
HiLink factorRatio Number
HiLink factorBinary Number
HiLink factorCharErr Error
HiLink factorDelimiter Delimiter
HiLink factorBackslash Special
- HiLink factorCompileDirective Keyword
+ HiLink factorCompileDirective Typedef
HiLink factorSymbol Define
+ HiLink factorMixin Typedef
+ HiLink factorInstance Typedef
+ HiLink factorHook Typedef
+ HiLink factorMain Define
HiLink factorPostpone Define
HiLink factorDefer Define
HiLink factorForget Define
HiLink factorAlien Define
HiLink factorTuple Typedef
- HiLink factorGeneric Define
if &bg == "dark"
hi hlLevel0 ctermfg=red guifg=red1