$nl
"In " { $link POSTPONE: TYPEDEF: } ", " { $link POSTPONE: FUNCTION: } ", " { $link POSTPONE: CALLBACK: } ", and " { $link POSTPONE: STRUCT: } " definitions, pointer types can be created by suffixing " { $snippet "*" } " to a C type name. Outside of FFI definitions, a pointer C type can be created using the " { $link POSTPONE: pointer: } " syntax word:"
{ $unchecked-example "FUNCTION: int* foo ( char* bar ) ;" }
-{ $unchecked-example """: foo ( bar -- int* )
- pointer: int f \"foo\" { pointer: char } alien-invoke ;""" } } ;
+{ $unchecked-example ": foo ( bar -- int* )
+ pointer: int f \"foo\" { pointer: char } alien-invoke ;" } } ;
ARTICLE: "byte-arrays-gc" "Byte arrays and the garbage collector"
"The Factor garbage collector can move byte arrays around, and it is only safe to pass byte arrays to C functions if the garbage collector will not run while C code still has a reference to the data."
{ t } [ void* lookup-c-type pointer: opaque lookup-c-type = ] unit-test
[ opaque lookup-c-type ] [ no-c-type? ] must-fail-with
-[ """
+[ "
USING: alien.syntax ;
IN: alien.c-types.tests
FUNCTION: opaque return_opaque ( ) ;
-""" eval( -- ) ] [ no-c-type? ] must-fail-with
+" eval( -- ) ] [ no-c-type? ] must-fail-with
C-TYPE: forward
STRUCT: backward { x forward* } ;
{ f }
[
- """
+ "
USING: alien.c-types classes.struct ;
IN: alien.c-types.tests
STRUCT: struct-redefined { x int } ;
- """ eval( -- )
+ " eval( -- )
- """
+ "
USING: alien.syntax ;
IN: alien.c-types.tests
C-TYPE: struct-redefined
- """ eval( -- )
+ " eval( -- )
\ struct-redefined class?
] unit-test
{ $values { "type" "a new C type" } }
{ $description "Defines a new, opaque C type. Since it is opaque, " { $snippet "type" } " will not be directly usable as a parameter or return type of a " { $link POSTPONE: FUNCTION: } " or as a slot of a " { $link POSTPONE: STRUCT: } ". However, it can be used as the type of a " { $link pointer } "." $nl
{ $snippet "C-TYPE:" } " can also be used to forward declare C types, allowing circular dependencies to occur between types. For example:"
-{ $code """C-TYPE: forward
+{ $code "C-TYPE: forward
STRUCT: backward { x forward* } ;
-STRUCT: forward { x backward* } ; """ } }
+STRUCT: forward { x backward* } ;" } }
{ $notes "Primitive C types are displayed using " { $snippet "C-TYPE:" } " syntax when they are " { $link see } "n." } ;
HELP: CALLBACK:
{ $description "Outputs a quotation that, when called, will have the effect of dropping the number of inputs to the original quotation." }
{ $examples
{ $example
- """USING: combinators.smart math prettyprint ;
-[ + + ] dropping ."""
-"""[ 3 ndrop ]"""
+ "USING: combinators.smart math prettyprint ;
+[ + + ] dropping ."
+"[ 3 ndrop ]"
}
} ;
{ $description "Infers the number of outputs from " { $snippet "quot" } " and, treating those outputs as a sequence, calls " { $link map-reduce } " on them." }
{ $examples
{ $example
-"""USING: math combinators.smart prettyprint ;
-[ 1 2 3 ] [ sq ] [ + ] map-reduce-outputs ."""
+"USING: math combinators.smart prettyprint ;
+[ 1 2 3 ] [ sq ] [ + ] map-reduce-outputs ."
"14"
}
} ;
{ $description "Infers the number of inputs to a quotation and drops them from the stack." }
{ $examples
{ $code
- """USING: combinators.smart kernel math ;
-1 2 [ + ] nullary"""
+ "USING: combinators.smart kernel math ;
+1 2 [ + ] nullary"
}
} ;
{ $description "Calls a quotation and leaves any consumed inputs on the stack beneath the quotation's outputs." }
{ $examples
{ $example
- """USING: combinators.smart kernel math prettyprint ;
-1 2 [ + ] preserving [ . ] tri@"""
-"""1
+ "USING: combinators.smart kernel math prettyprint ;
+1 2 [ + ] preserving [ . ] tri@"
+"1
2
-3"""
+3"
}
} ;
{ $description "Applies a quotation to the datastack " { $snippet "n" } " times, starting lower on the stack and working up in increments of the number of inferred inputs to the quotation." }
{ $examples
{ $example
- """USING: combinators.smart prettyprint math kernel ;
-1 2 3 4 [ + ] 2 smart-apply [ . ] bi@"""
-"""3
-7"""
+ "USING: combinators.smart prettyprint math kernel ;
+1 2 3 4 [ + ] 2 smart-apply [ . ] bi@"
+"3
+7"
}
} ;
IN: command-line.startup
: cli-usage ( -- )
-"""
-Usage: """ write vm-path file-name write """ [Factor arguments] [script] [script arguments]
+"
+Usage: " write vm-path file-name write " [Factor arguments] [script] [script arguments]
Common arguments:
-help print this message and exit
- -i=<image> load Factor image file <image> (default """ write vm-path file-stem write """.image)
+ -i=<image> load Factor image file <image> (default " write vm-path file-stem write " .image)
-run=<vocab> run the MAIN: entry point of <vocab>
-run=listener run terminal listener
-run=ui.tools run Factor development UI
-no-user-init suppress loading of .factor-rc
Enter
- "command-line" help
+ \"command-line\" help
from within Factor for more information.
-""" write ;
+" write ;
: help? ( -- ? )
"help" get "-help" get or "h" get or
ascii <process-reader> stream-lines ;
[ ] [
- """USING: alien alien.c-types alien.syntax kernel ;
+ " USING: alien alien.c-types alien.syntax kernel ;
IN: scratchpad
: callback-death ( -- callback )
- void { } cdecl [ "Error!" throw ] alien-callback ;
+ void { } cdecl [ \"Error!\" throw ] alien-callback ;
: callback-invoke ( callback -- )
void { } cdecl alien-indirect ;
- callback-death callback-invoke"""
+ callback-death callback-invoke"
callback-error-script ascii set-file-contents
] unit-test
[ t ] [ run-vm-with-script "\"Error!\"" swap member? ] unit-test
[ ] [
- """USING: alien alien.c-types alien.syntax kernel threads ;
+ "USING: alien alien.c-types alien.syntax kernel threads ;
IN: scratchpad
: callback-death ( -- callback )
- void { } cdecl [ "Error!" throw ] alien-callback ;
+ void { } cdecl [ \"Error!\" throw ] alien-callback ;
: callback-invoke ( callback -- )
void { } cdecl alien-indirect ;
[ callback-death callback-invoke ] in-thread
- stop"""
+ stop"
callback-error-script ascii set-file-contents
] unit-test
}
"Here is a concrete example which fetches content from 5 different web sites, making no more than 3 requests at a time:"
{ $code
- """USING: concurrency.combinators concurrency.semaphores
+ "USING: concurrency.combinators concurrency.semaphores
fry http.client kernel urls ;
{
- URL" http://www.apple.com"
- URL" http://www.google.com"
- URL" http://www.ibm.com"
- URL" http://www.hp.com"
- URL" http://www.oracle.com"
+ URL\" http://www.apple.com\"
+ URL\" http://www.google.com\"
+ URL\" http://www.ibm.com\"
+ URL\" http://www.hp.com\"
+ URL\" http://www.oracle.com\"
}
2 <semaphore> '[
_ [ http-get nip ] with-semaphore
-] parallel-map"""
+] parallel-map"
} ;
ARTICLE: "concurrency.semaphores" "Counting semaphores"
{ $subsections sql-query }
"Here's an example usage where we'll make a book table, insert some objects, and query them." $nl
"First, let's set up a custom combinator for using our database. See " { $link "db-custom-database-combinators" } " for more details."
-{ $code """USING: db.sqlite db io.files io.files.temp ;
+{ $code "USING: db.sqlite db io.files io.files.temp ;
: with-book-db ( quot -- )
- "book.db" temp-file <sqlite-db> swap with-db ; inline""" }
+ \"book.db\" temp-file <sqlite-db> swap with-db ; inline" }
"Now let's create the table manually:"
-{ $code """"create table books
+{ $code "\"create table books
(id integer primary key, title text, author text, date_published timestamp,
- edition integer, cover_price double, condition text)"
- [ sql-command ] with-book-db""" }
+ edition integer, cover_price double, condition text)\"
+ [ sql-command ] with-book-db" }
"Time to insert some books:"
-{ $code """"insert into books
+{ $code "\"insert into books
(title, author, date_published, edition, cover_price, condition)
- values('Factor for Sheeple', 'Mister Stacky Pants', date('now'), 1, 13.37, 'mint')"
-[ sql-command ] with-book-db""" }
+ values('Factor for Sheeple', 'Mister Stacky Pants', date('now'), 1, 13.37, 'mint')\"
+[ sql-command ] with-book-db" }
"Now let's select the book:"
-{ $code """"select id, title, cover_price from books;" [ sql-query ] with-book-db""" }
+{ $code "\"select id, title, cover_price from books;\" [ sql-query ] with-book-db" }
"Notice that the result of this query is a Factor array containing the database rows as arrays of strings. We would have to convert the " { $snippet "cover_price" } " from a string to a number in order to use it in a calculation." $nl
"In conclusion, this method of accessing a database is supported, but it is fairly low-level and generally specific to a single database. The " { $vocab-link "db.tuples" } " vocabulary is a good alternative to writing SQL by hand." ;
"Make a " { $snippet "with-" } " combinator to open and close a database so that resources are not leaked." $nl
"SQLite example combinator:"
-{ $code """USING: db.sqlite db io.files io.files.temp ;
+{ $code "USING: db.sqlite db io.files io.files.temp ;
: with-sqlite-db ( quot -- )
- "my-database.db" temp-file <sqlite-db> swap with-db ; inline""" }
+ \"my-database.db\" temp-file <sqlite-db> swap with-db ; inline" }
"PostgreSQL example combinator:"
-{ $code """USING: db.postgresql db ;
+{ $code "USING: db.postgresql db ;
: with-postgresql-db ( quot -- )
<postgresql-db>
- "localhost" >>host
+ \"localhost\" >>host
5432 >>port
- "erg" >>username
- "secrets?" >>password
- "factor-test" >>database
- swap with-db ; inline"""
+ \"erg\" >>username
+ \"secrets?\" >>password
+ \"factor-test\" >>database
+ swap with-db ; inline"
} ;
ABOUT: "db"
} ;
: insert-trigger ( -- string )
- """
+ "
CREATE TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id
BEFORE INSERT ON ${table-name}
FOR EACH ROW BEGIN
- SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fki_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"')
+ SELECT RAISE(ROLLBACK, 'insert on table \"${table-name}\" violates foreign key constraint \"fki_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id\"')
WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
END;
- """ interpolate>string ;
+ " interpolate>string ;
: insert-trigger-not-null ( -- string )
- """
+ "
CREATE TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id
BEFORE INSERT ON ${table-name}
FOR EACH ROW BEGIN
- SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fki_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"')
+ SELECT RAISE(ROLLBACK, 'insert on table \"${table-name}\" violates foreign key constraint \"fki_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id\"')
WHERE NEW.${table-id} IS NOT NULL
AND (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
END;
- """ interpolate>string ;
+ " interpolate>string ;
: update-trigger ( -- string )
- """
+ "
CREATE TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id
BEFORE UPDATE ON ${table-name}
FOR EACH ROW BEGIN
- SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fku_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"')
+ SELECT RAISE(ROLLBACK, 'update on table \"${table-name}\" violates foreign key constraint \"fku_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id\"')
WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
END;
- """ interpolate>string ;
+ " interpolate>string ;
: update-trigger-not-null ( -- string )
- """
+ "
CREATE TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id
BEFORE UPDATE ON ${table-name}
FOR EACH ROW BEGIN
- SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fku_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"')
+ SELECT RAISE(ROLLBACK, 'update on table \"${table-name}\" violates foreign key constraint \"fku_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id\"')
WHERE NEW.${table-id} IS NOT NULL
AND (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL;
END;
- """ interpolate>string ;
+ " interpolate>string ;
: delete-trigger-restrict ( -- string )
- """
+ "
CREATE TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id
BEFORE DELETE ON ${foreign-table-name}
FOR EACH ROW BEGIN
- SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table-name}" violates foreign key constraint "fkd_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"')
+ SELECT RAISE(ROLLBACK, 'delete on table \"${foreign-table-name}\" violates foreign key constraint \"fkd_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id\"')
WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = OLD.${foreign-table-id}) IS NOT NULL;
END;
- """ interpolate>string ;
+ " interpolate>string ;
: delete-trigger-cascade ( -- string )
- """
+ "
CREATE TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id
BEFORE DELETE ON ${foreign-table-name}
FOR EACH ROW BEGIN
DELETE from ${table-name} WHERE ${table-id} = OLD.${foreign-table-id};
END;
- """ interpolate>string ;
+ " interpolate>string ;
: can-be-null? ( -- ? )
"sql-spec" get modifiers>> [ +not-null+ = ] any? not ;
"The title, author, and publisher should be strings; the date-published a timestamp; the edition an integer; the cover-price a float. These are the Factor types for which we will need to look up the corresponding " { $link "db.types" } ". " $nl
"To actually bind the tuple slots to the database types, we'll use " { $link define-persistent } "."
{ $code
-"""USING: db.tuples db.types ;
-book "BOOK"
+"USING: db.tuples db.types ;
+book \"BOOK\"
{
- { "id" "ID" +db-assigned-id+ }
- { "title" "TITLE" VARCHAR }
- { "author" "AUTHOR" VARCHAR }
- { "date-published" "DATE_PUBLISHED" TIMESTAMP }
- { "edition" "EDITION" INTEGER }
- { "cover-price" "COVER_PRICE" DOUBLE }
- { "condition" "CONDITION" VARCHAR }
-} define-persistent""" }
+ { \"id\" \"ID\" +db-assigned-id+ }
+ { \"title\" \"TITLE\" VARCHAR }
+ { \"author\" \"AUTHOR\" VARCHAR }
+ { \"date-published\" \"DATE_PUBLISHED\" TIMESTAMP }
+ { \"edition\" \"EDITION\" INTEGER }
+ { \"cover-price\" \"COVER_PRICE\" DOUBLE }
+ { \"condition\" \"CONDITION\" VARCHAR }
+} define-persistent" }
"That's all we'll have to do with the database for this tutorial. Now let's make a book."
-{ $code """USING: calendar namespaces ;
+{ $code "USING: calendar namespaces ;
T{ book
- { title "Factor for Sheeple" }
- { author "Mister Stacky Pants" }
+ { title \"Factor for Sheeple\" }
+ { author \"Mister Stacky Pants\" }
{ date-published T{ timestamp { year 2009 } { month 3 } { day 3 } } }
{ edition 1 }
{ cover-price 13.37 }
-} book set""" }
+} book set" }
"Now we've created a book. Let's save it to the database."
-{ $code """USING: db db.sqlite fry io.files.temp ;
+{ $code "USING: db db.sqlite fry io.files.temp ;
: with-book-tutorial ( quot -- )
- '[ "book-tutorial.db" temp-file <sqlite-db> _ with-db ] call ; inline
+ '[ \"book-tutorial.db\" temp-file <sqlite-db> _ with-db ] call ; inline
[
book recreate-table
book get insert-tuple
-] with-book-tutorial""" }
+] with-book-tutorial" }
"Is it really there?"
-{ $code """[
- T{ book { title "Factor for Sheeple" } } select-tuples .
-] with-book-tutorial""" }
+{ $code "[
+ T{ book { title \"Factor for Sheeple\" } } select-tuples .
+] with-book-tutorial" }
"Oops, we spilled some orange juice on the book cover."
-{ $code """book get "Small orange juice stain on cover" >>condition""" }
+{ $code "book get \"Small orange juice stain on cover\" >>condition" }
"Now let's save the modified book."
-{ $code """[
+{ $code "[
book get update-tuple
-] with-book-tutorial""" }
+] with-book-tutorial" }
"And select it again. You can query the database by any field -- just set it in the exemplar tuple you pass to " { $link select-tuples } "."
-{ $code """[
- T{ book { title "Factor for Sheeple" } } select-tuples
-] with-book-tutorial""" }
+{ $code "[
+ T{ book { title \"Factor for Sheeple\" } } select-tuples
+] with-book-tutorial" }
"Let's drop the table because we're done."
-{ $code """[
+{ $code "[
book drop-table
-] with-book-tutorial""" }
+] with-book-tutorial" }
"To summarize, the steps for using Factor's tuple database are:"
{ $list
"Make a new tuple to represent your data"
{ $notes "Usually, " { $link POSTPONE: CONSULT: } " should be used instead. This is only for runtime use." } ;
HELP: CONSULT:
-{ $syntax """CONSULT: group class
- code ;""" }
+{ $syntax "CONSULT: group class
+ code ;" }
{ $values { "group" "a protocol, generic word or tuple class" } { "class" "a class" } { "code" "code to get the object to which the method should be forwarded" } }
{ $description "Declares that objects of " { $snippet "class" } " will delegate the generic words contained in " { $snippet "group" } " to the object returned by executing " { $snippet "code" } " with the original object as an input." { $snippet "CONSULT:" } " will overwrite any existing methods on " { $snippet "class" } " for the members of " { $snippet "group" } ", but new methods can be added after the " { $snippet "CONSULT:" } " to override the delegation." } ;
HELP: BROADCAST:
-{ $syntax """BROADCAST: group class
- code ;""" }
+{ $syntax "BROADCAST: group class
+ code ;" }
{ $values { "group" "a protocol, generic word or tuple class" } { "class" "a class" } { "code" "code to get the object to which the method should be forwarded" } }
{ $description "Declares that objects of " { $snippet "class" } " will delegate the generic words contained in " { $snippet "group" } " to every object in the sequence returned by executing " { $snippet "code" } " with the original object as an input." { $snippet "BROADCAST:" } " will overwrite any existing methods on " { $snippet "class" } " for the members of " { $snippet "group" } ", but new methods can be added after the " { $snippet "BROADCAST:" } " to override the delegation. Every generic word in " { $snippet "group" } " must return no outputs; otherwise, a " { $link broadcast-words-must-have-no-outputs } " error will be raised." } ;
{ $heading "Example" }
"In this example, a string is evaluated with a fictional " { $snippet "cad.objects" } " vocabulary in the search path by default, together with the listener's " { $link interactive-vocabs } "; the quotation is expected to produce a sequence on the stack:"
{ $code
- """USING: eval listener vocabs.parser ;
+ "USING: eval listener vocabs.parser ;
[
- "cad.objects" use-vocab
+ \"cad.objects\" use-vocab
( -- seq ) (eval)
-] with-interactive-vocabs"""
+] with-interactive-vocabs"
}
"Note that the search path in the outer code (set by the " { $link POSTPONE: USING: } " form) has no relation to the search path used when parsing the string parameter (this is determined by " { $link with-interactive-vocabs } " and " { $link use-vocab } ")." ;
;FUNCTOR
[ [ ] ] [
- """IN: functors.tests
- << "some" redefine-test >>""" <string-reader> "functors-test" parse-stream
+ "IN: functors.tests
+ << \"some\" redefine-test >>" <string-reader> "functors-test" parse-stream
] unit-test
test-redefinition
{ $examples
"A simple validator from " { $vocab-link "webapps.todo" } "; this word is invoked from the " { $slot "validate" } " quotation of action for editing a todo list item:"
{ $code
- """: validate-todo ( -- )
+ ": validate-todo ( -- )
{
- { "summary" [ v-one-line ] }
- { "priority" [ v-integer 0 v-min-value 10 v-max-value ] }
- { "description" [ v-required ] }
- } validate-params ;"""
+ { \"summary\" [ v-one-line ] }
+ { \"priority\" [ v-integer 0 v-min-value 10 v-max-value ] }
+ { \"description\" [ v-required ] }
+ } validate-params ;"
}
} ;
{ $examples
"The " { $vocab-link "webapps.counter" } " vocabulary uses an alloy to configure the counter:"
{ $code
- """: counter-db ( -- db ) "counter.db" <sqlite-db> ;
+ ": counter-db ( -- db ) \"counter.db\" <sqlite-db> ;
: run-counter ( -- )
<counter-app>
counter-db <alloy>
main-responder set-global
- 8080 httpd ;"""
+ 8080 httpd ;"
}
} ;
ARTICLE: "furnace.auth.example" "Furnace authentication example"
"The " { $vocab-link "webapps.todo" } " vocabulary wraps all of its responders in a protected responder. The " { $slot "description" } " slot is set so that the login page contains the message “You must log in to view your todo list”:"
{ $code
- """<protected>
- "view your todo list" >>description"""
+ "<protected>
+ \"view your todo list\" >>description"
}
"The " { $vocab-link "webapps.wiki" } " vocabulary defines a mix of protected and unprotected actions. One example of a protected action is that for deleting wiki pages, an action normally reserved for administrators. This action is protected with the following code:"
{ $code
- """<protected>
- "delete wiki articles" >>description
- { can-delete-wiki-articles? } >>capabilities"""
+ "<protected>
+ \"delete wiki articles\" >>description
+ { can-delete-wiki-articles? } >>capabilities"
}
"The " { $vocab-link "websites.concatenative" } " vocabulary wraps all of its responders, including the wiki, in a login authentication realm:"
{ $code
-""": <login-config> ( responder -- responder' )
- "Factor website" <login-realm>
- "Factor website" >>name
+": <login-config> ( responder -- responder' )
+ \"Factor website\" <login-realm>
+ \"Factor website\" >>name
allow-registration
allow-password-recovery
allow-edit-profile
- allow-deactivation ;"""
+ allow-deactivation ;"
} ;
ARTICLE: "furnace.auth" "Furnace authentication"
{ $heading "Example: ls" }
"Here is an example implementing a simplified version of the Unix " { $snippet "ls" } " command in Factor:"
{ $code
- """USING: command-line namespaces io io.files
+ "USING: command-line namespaces io io.files
io.pathnames tools.files sequences kernel ;
command-line get [
current-directory get directory.
] [
dup length 1 = [ first directory. ] [
- [ [ nl write ":" print ] [ directory. ] bi ] each
+ [ [ nl write \":\" print ] [ directory. ] bi ] each
] if
-] if-empty"""
+] if-empty"
}
"You can put it in a file named " { $snippet "ls.factor" } ", and then run it, to list the " { $snippet "/usr/bin" } " directory for example:"
{ $code "./factor ls.factor /usr/bin" }
{ $heading "Example: grep" }
"The following is a more complicated example, implementing something like the Unix " { $snippet "grep" } " command:"
-{ $code """USING: kernel fry io io.files io.encodings.ascii sequences
+{ $code "USING: kernel fry io io.files io.encodings.ascii sequences
regexp command-line namespaces ;
IN: grep
ascii [ grep-lines ] with-file-reader ;
: grep-usage ( -- )
- "Usage: factor grep.factor <pattern> [<file>...]" print ;
+ \"Usage: factor grep.factor <pattern> [<file>...]\" print ;
command-line get [
grep-usage
] [
[ grep-file ] with each
] if-empty
-] if-empty""" }
+] if-empty" }
"You can run it like so,"
{ $code "./factor grep.factor '.*hello.*' myfile.txt" }
"You'll notice this script takes a while to start. This is because it is loading and compiling the " { $vocab-link "regexp" } " vocabulary every time. To speed up startup, load the vocabulary into your image, and save the image:"
[
[ ] [
- """<%
+ "<%
IN: html.templates.fhtml.tests
: test-word ( -- ) ;
- %>""" parse-template drop
+ %>" parse-template drop
] unit-test
] with-file-vocabs
{ $description "Enables the responder to serve " { $snippet ".cgi" } " scripts by executing them as per the CGI specification." }
{ $examples
{ $code
- """<dispatcher>
- "/var/www/cgi/" <static> enable-cgi "cgi-bin" add-responder"""
+ "<dispatcher>
+ \"/var/www/cgi/\" <static> enable-cgi \"cgi-bin\" add-responder"
}
}
{ $side-effects "responder" } ;
ARTICLE: "http.server.dispatchers.example" "HTTP dispatcher examples"
{ $heading "Simple pathname dispatcher" }
{ $code
- """<dispatcher>
- <new-action> "new" add-responder
- <edit-action> "edit" add-responder
- <delete-action> "delete" add-responder
- <list-action> "" add-responder
-main-responder set-global"""
+ "<dispatcher>
+ <new-action> \"new\" add-responder
+ <edit-action> \"edit\" add-responder
+ <delete-action> \"delete\" add-responder
+ <list-action> \"\" add-responder
+main-responder set-global"
}
"In the above example, visiting any URL other than " { $snippet "/new" } ", " { $snippet "/edit" } ", " { $snippet "/delete" } ", or " { $snippet "/" } " will result in a 404 error."
{ $heading "Another pathname dispatcher" }
"On the other hand, suppose we wanted to route all unrecognized paths to a “view” action:"
{ $code
- """<dispatcher>
- <new-action> "new" add-responder
- <edit-action> "edit" add-responder
- <delete-action> "delete" add-responder
+ "<dispatcher>
+ <new-action> \"new\" add-responder
+ <edit-action> \"edit\" add-responder
+ <delete-action> \"delete\" add-responder
<view-action> >>default
-main-responder set-global"""
+main-responder set-global"
}
"The " { $slot "default" } " slot holds a responder to which all unrecognized paths are sent to."
{ $heading "Dispatcher subclassing example" }
{ $code
- """TUPLE: golf-courses < dispatcher ;
+ "TUPLE: golf-courses < dispatcher ;
: <golf-courses> ( -- golf-courses )
golf-courses new-dispatcher ;
<golf-courses>
- <new-action> "new" add-responder
- <edit-action> "edit" add-responder
- <delete-action> "delete" add-responder
- <list-action> "" add-responder
-main-responder set-global"""
+ <new-action> \"new\" add-responder
+ <edit-action> \"edit\" add-responder
+ <delete-action> \"delete\" add-responder
+ <list-action> \"\" add-responder
+main-responder set-global"
}
"The action templates can now emit links to responder-relative URLs prefixed by " { $snippet "$golf-courses/" } "."
{ $heading "Virtual hosting example" }
{ $code
- """<vhost-dispatcher>
- <casino> "concatenative-casino.com" add-responder
- <dating> "raptor-dating.com" add-responder
-main-responder set-global"""
+ "<vhost-dispatcher>
+ <casino> \"concatenative-casino.com\" add-responder
+ <dating> \"raptor-dating.com\" add-responder
+main-responder set-global"
}
"Note that the virtual host dispatcher strips off a " { $snippet "www." } " prefix, so " { $snippet "www.concatenative-casino.com" } " would be routed to the " { $snippet "<casino>" } " responder instead of receiving a 404." ;
{ $examples
"Print all files in your home directory which are larger than a megabyte:"
{ $code
- """USING: io.directories io.files.info io.pathnames ;
+ "USING: io.directories io.files.info io.pathnames ;
home [
[
dup link-info size>> 20 2^ >
[ print ] [ drop ] if
] each
-] with-directory-files"""
+] with-directory-files"
}
} ;
{ "string" string } }
{ $description "Converts an array of bytes to a string, interpreting that array of bytes as a string with the given encoding." }
{ $examples
- { $example """USING: io.encodings.string io.encodings.utf8 prettyprint ;
-B{ 230 136 145 231 136 177 228 189 160 } utf8 decode ."""
-""""我爱你""""
+ { $example "USING: io.encodings.string io.encodings.utf8 prettyprint ;
+B{ 230 136 145 231 136 177 228 189 160 } utf8 decode ."
+"\"我爱你\""
}
} ;
{ $values { "string" string } { "encoding" "an encoding descriptor" } { "byte-array" byte-array } }
{ $description "Converts a string into a byte array, interpreting that string with the given encoding." }
{ $examples
- { $example """USING: io.encodings.string io.encodings.utf8 prettyprint ;
-"我爱你" utf8 encode ."""
+ { $example "USING: io.encodings.string io.encodings.utf8 prettyprint ;
+\"我爱你\" utf8 encode ."
"B{ 230 136 145 231 136 177 228 189 160 }"
}
} ;
{ $unchecked-example
"USING: alien.c-types io.mmap prettyprint specialized-arrays ;"
"SPECIALIZED-ARRAY: uint"
-""""resource:license.txt" uint [
+"resource:license.txt\" uint [
[ . ] each
-] with-mapped-array"""
+] with-mapped-array"
""
}
}
}
{ $description "Wraps a stream in a " { $link <throws-on-eof-stream> } " tuple and calls the quotation with this stream as the " { $link input-stream } " variable. Causes a " { $link stream-exhausted } " exception to be thrown upon stream exhaustion. The stream is left open after this combinator returns." }
"This example will throw a " { $link stream-exhausted } " exception:"
-{ $unchecked-example """USING: io.streams.throwing prettyprint ;
-"abc" <string-reader> [ 4 read ] stream-throw-on-eof"""
+{ $unchecked-example "USING: io.streams.throwing prettyprint ;
+\"abc\" <string-reader> [ 4 read ] stream-throw-on-eof"
""
} ;
}
{ $description "Wraps the value stored in the " { $link input-stream } " variable and causes a stream read that exhausts the input stream to throw a " { $link stream-exhausted } " exception. The stream is left open after this combinator returns." } $nl
"This example will throw a " { $link stream-exhausted } " exception:"
-{ $unchecked-example """USING: io.streams.throwing prettyprint ;
-"abc" [ [ 4 read ] throw-on-eof ] with-string-reader"""
+{ $unchecked-example "USING: io.streams.throwing prettyprint ;
+\"abc\" [ [ 4 read ] throw-on-eof ] with-string-reader"
""
} ;
! feature to get
{ -0.0 } [ "-0.0" json> ] unit-test
-{ " fuzzy pickles " } [ """ " fuzzy pickles " """ json> ] unit-test
-{ "while 1:\n\tpass" } [ """ "while 1:\n\tpass" """ json> ] unit-test
+{ " fuzzy pickles " } [ " \" fuzzy pickles \" " json> ] unit-test
+{ "while 1:\n\tpass" } [ " \"while 1:\n\tpass\" " json> ] unit-test
! unicode is allowed in json
-{ "ß∂¬ƒ˚∆" } [ """ "ß∂¬ƒ˚∆"""" json> ] unit-test
-${ { 8 9 10 12 13 34 47 92 } >string } [ """ "\\b\\t\\n\\f\\r\\"\\/\\\\" """ json> ] unit-test
-${ { 0xabcd } >string } [ """ "\\uaBCd" """ json> ] unit-test
+{ "ß∂¬ƒ˚∆" } [ " \"ß∂¬ƒ˚∆\"" json> ] unit-test
+${ { 8 9 10 12 13 34 47 92 } >string } [ " \"\\b\\t\\n\\f\\r\\\"\\/\\\\\" " json> ] unit-test
+${ { 0xabcd } >string } [ " \"\\uaBCd\" " json> ] unit-test
{ "𝄞" } [ "\"\\ud834\\udd1e\"" json> ] unit-test
{ H{ { "a" { } } { "b" 123 } } } [ "{\"a\":[],\"b\":123}" json> ] unit-test
{ { } } [ "[]" json> ] unit-test
-{ { 1 "two" 3.0 } } [ """ [1, "two", 3.0] """ json> ] unit-test
+{ { 1 "two" 3.0 } } [ " [1, \"two\", 3.0] " json> ] unit-test
{ H{ } } [ "{}" json> ] unit-test
! the returned hashtable should be different every time
{ H{ } } [ "key" "value" "{}" json> ?set-at "{}" json> nip ] unit-test
-{ H{ { "US$" 1.0 } { "EU€" 1.5 } } } [ """ { "US$":1.00, "EU\\u20AC":1.50 } """ json> ] unit-test
+{ H{ { "US$" 1.0 } { "EU€" 1.5 } } } [ " { \"US$\":1.00, \"EU\\u20AC\":1.50 } " json> ] unit-test
{ H{
{ "fib" { 1 1 2 3 5 8 H{ { "etc" "etc" } } } }
{ "prime" { 2 3 5 7 11 13 } }
-} } [ """ {
- "fib": [1, 1, 2, 3, 5, 8,
- { "etc":"etc" } ],
- "prime":
+} } [ " {
+ \"fib\": [1, 1, 2, 3, 5, 8,
+ { \"etc\":\"etc\" } ],
+ \"prime\":
[ 2,3, 5,7,
11,
13
] }
-""" json> ] unit-test
+" json> ] unit-test
{ 0 } [ " 0" json> ] unit-test
{ 0 } [ "0 " json> ] unit-test
{ 0 } [ " 0 " json> ] unit-test
{ V{ H{ { "a" "b" } } H{ { "c" "d" } } } }
-[ """{"a": "b"} {"c": "d"}""" [ read-jsons ] with-string-reader ] unit-test
+[ "{\"a\": \"b\"} {\"c\": \"d\"}" [ read-jsons ] with-string-reader ] unit-test
! empty objects are allowed as values in objects
{ H{ { "foo" H{ } } } } [ "{ \"foo\" : {}}" json> ] unit-test
{ "102.0" } [ 102.0 >json ] unit-test
{ "102.5" } [ 102.5 >json ] unit-test
{ "0.5" } [ 1/2 >json ] unit-test
-{ """\"hello world\"""" } [ "hello world" >json ] unit-test
+{ "\"hello world\"" } [ "hello world" >json ] unit-test
{ "[1,\"two\",3.0]" } [ { 1 "two" 3.0 } >json ] unit-test
-{ """{"US$":1.0,"EU€":1.5}""" } [ H{ { "US$" 1.0 } { "EU€" 1.5 } } >json ] unit-test
+{ "{\"US$\":1.0,\"EU€\":1.5}" } [ H{ { "US$" 1.0 } { "EU€" 1.5 } } >json ] unit-test
-{ """">json"""" } [ \ >json >json ] unit-test
+{ "\">json\"" } [ \ >json >json ] unit-test
{ { 0.5 } } [ { 1/2 } >json json> ] unit-test
with-variable
] unit-test
-{ """{"1":2,"3":4}""" }
+{ "{\"1\":2,\"3\":4}" }
[ H{ { "1" 2 } { "3" 4 } } >json ] unit-test
-{ """{"1":2,"3":4}""" }
+{ "{\"1\":2,\"3\":4}" }
[ H{ { 1 2 } { 3 4 } } >json ] unit-test
-{ """{"":4}""" }
+{ "{\"\":4}" }
[ H{ { "" 2 } { "" 4 } } >json ] unit-test
-{ """{"true":4,"false":2,"":5}""" }
+{ "{\"true\":4,\"false\":2,\"\":5}" }
[ H{ { f 2 } { t 4 } { "" 5 } } >json ] unit-test
-{ """{"3.1":3}""" }
+{ "{\"3.1\":3}" }
[ H{ { 3.1 3 } } >json ] unit-test
-{ """{"null":1}""" }
+{ "{\"null\":1}" }
[ H{ { json-null 1 } } >json ] unit-test
-{ """{"Infinity":1}""" }
+{ "{\"Infinity\":1}" }
[ t json-allow-fp-special? [ H{ { 1/0. 1 } } >json ] with-variable ] unit-test
-{ """{"-Infinity":1}""" }
+{ "{\"-Infinity\":1}" }
[ t json-allow-fp-special? [ H{ { -1/0. 1 } } >json ] with-variable ] unit-test
-{ """{"NaN":1}""" }
+{ "{\"NaN\":1}" }
[ t json-allow-fp-special? [ H{ { NAN: 333 1 } } >json ] with-variable ] unit-test
{
ARTICLE: "locals-examples" "Examples of lexical variables"
{ $heading "Definitions with lexical variables" }
"The following example demonstrates lexical variable bindings in word definitions. The " { $snippet "quadratic-roots" } " word is defined with " { $link POSTPONE: :: } ", so it takes its inputs from the top three elements of the datastack and binds them to the variables " { $snippet "a" } ", " { $snippet "b" } ", and " { $snippet "c" } ". In the body, the " { $snippet "disc" } " variable is bound using " { $link POSTPONE: :> } " and then used in the following line of code."
-{ $example """USING: locals math math.functions kernel ;
+{ $example "USING: locals math math.functions kernel ;
IN: scratchpad
:: quadratic-roots ( a b c -- x y )
b sq 4 a c * * - sqrt :> disc
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ;
-1.0 1.0 -6.0 quadratic-roots [ . ] bi@"""
-"""2.0
--3.0"""
+1.0 1.0 -6.0 quadratic-roots [ . ] bi@"
+"2.0
+-3.0"
}
"If you wanted to perform the quadratic formula interactively from the listener, you could use " { $link POSTPONE: [let } " to provide a scope for the variables:"
-{ $example """USING: locals math math.functions kernel ;
+{ $example "USING: locals math math.functions kernel ;
IN: scratchpad
[let 1.0 :> a 1.0 :> b -6.0 :> c
b sq 4 a c * * - sqrt :> disc
b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@
-] [ . ] bi@"""
-"""2.0
--3.0"""
+] [ . ] bi@"
+"2.0
+-3.0"
}
$nl
{ $heading "Mutable bindings" }
"This next example demonstrates closures and mutable variable bindings. The " { $snippet "<counter>" } " word outputs a tuple containing a pair of quotations that respectively increment and decrement an internal counter in the mutable " { $snippet "value" } " variable and then return the new value. The quotations close over the counter, so each invocation of the word gives new quotations with a new internal counter."
{ $example
-"""USING: locals kernel math ;
+"USING: locals kernel math ;
IN: scratchpad
TUPLE: counter adder subtractor ;
<counter>
[ adder>> call . ]
[ adder>> call . ]
-[ subtractor>> call . ] tri"""
-"""1
+[ subtractor>> call . ] tri"
+"1
2
-1"""
+1"
}
$nl
"The same variable name can be bound multiple times in the same scope. This is different from reassigning the value of a mutable variable. The most recent binding for a variable name will mask previous bindings for that name. However, the old binding referring to the previous value can still persist in closures. The following contrived example demonstrates this:"
{ $example
-"""USING: kernel locals prettyprint ;
+"USING: kernel locals prettyprint ;
IN: scratchpad
:: rebinding-example ( -- quot1 quot2 )
5 :> a [ a ]
5 :> a! [ a ]
6 a! [ a ] ;
rebinding-example [ call . ] bi@
-mutable-example [ call . ] bi@"""
-"""5
+mutable-example [ call . ] bi@"
+"5
6
6
-6"""
+6"
}
"In " { $snippet "rebinding-example" } ", the binding of " { $snippet "a" } " to " { $snippet "5" } " is closed over in the first quotation, and the binding of " { $snippet "a" } " to " { $snippet "6" } " is closed over in the second, so calling both quotations results in " { $snippet "5" } " and " { $snippet "6" } " respectively. By contrast, in " { $snippet "mutable-example" } ", both quotations close over a single binding of " { $snippet "a" } ". Even though " { $snippet "a" } " is assigned to " { $snippet "6" } " after the first quotation is made, calling either quotation will output the new value of " { $snippet "a" } "."
{ $heading "Lexical variables in literals" }
"Some kinds of literals can include references to lexical variables as described in " { $link "locals-literals" } ". For example, the " { $link 3array } " word could be implemented as follows:"
{ $example
-"""USING: locals prettyprint ;
+"USING: locals prettyprint ;
IN: scratchpad
:: my-3array ( x y z -- array ) { x y z } ;
-1 "two" 3.0 my-3array ."""
-"""{ 1 "two" 3.0 }"""
+1 \"two\" 3.0 my-3array ."
+"{ 1 \"two\" 3.0 }"
} ;
ARTICLE: "locals-literals" "Lexical variables in literals"
{ $examples
{ $example "USING: math.combinatorics prettyprint ;"
"{ \"a\" \"b\" \"c\" \"d\" } 2 all-combinations ."
-"""{
- { "a" "b" }
- { "a" "c" }
- { "a" "d" }
- { "b" "c" }
- { "b" "d" }
- { "c" "d" }
-}""" } } ;
+"{
+ { \"a\" \"b\" }
+ { \"a\" \"c\" }
+ { \"a\" \"d\" }
+ { \"b\" \"c\" }
+ { \"b\" \"d\" }
+ { \"c\" \"d\" }
+}" } } ;
HELP: each-combination
{ $values { "seq" sequence } { "k" "a non-negative integer" } { "quot" { $quotation ( ... elt -- ... ) } } }
{ $description "Outputs a " { $link histogram } " of a sequence sorted by number of occurrences from lowest to highest." }
{ $examples
{ $example "USING: prettyprint math.statistics ;"
- """"abababbbbbbc" sorted-histogram ."""
+ "\"abababbbbbbc\" sorted-histogram ."
"{ { 99 1 } { 97 3 } { 98 8 } }"
}
} ;
}
{ $examples
"Conversion between integer and float vectors:"
-{ $example """USING: alien.c-types math.vectors.conversion math.vectors.simd
+{ $example "USING: alien.c-types math.vectors.conversion math.vectors.simd
prettyprint ;
int-4{ 0 1 2 3 } int-4 float-4 vconvert .
-double-2{ 1.25 3.75 } double-2 longlong-2 vconvert ."""
-"""float-4{ 0.0 1.0 2.0 3.0 }
-longlong-2{ 1 3 }""" }
+double-2{ 1.25 3.75 } double-2 longlong-2 vconvert ."
+"float-4{ 0.0 1.0 2.0 3.0 }
+longlong-2{ 1 3 }" }
"Packing conversions:"
-{ $example """USING: alien.c-types math.vectors.conversion math.vectors.simd
+{ $example "USING: alien.c-types math.vectors.conversion math.vectors.simd
prettyprint ;
int-4{ -8 70000 6000 50 } int-4{ 4 3 2 -1 } int-4 ushort-8 vconvert .
double-2{ 0.0 1.0e100 }
-double-2{ -1.0e100 0.0 } double-2 float-4 vconvert ."""
-"""ushort-8{ 0 65535 6000 50 4 3 2 0 }
-float-4{ 0.0 1/0. -1/0. 0.0 }""" }
+double-2{ -1.0e100 0.0 } double-2 float-4 vconvert ."
+"ushort-8{ 0 65535 6000 50 4 3 2 0 }
+float-4{ 0.0 1/0. -1/0. 0.0 }" }
"Unpacking conversions:"
-{ $example """USING: alien.c-types kernel math.vectors.conversion
+{ $example "USING: alien.c-types kernel math.vectors.conversion
math.vectors.simd prettyprint ;
uchar-16{ 8 70 60 50 4 30 200 1 9 10 110 102 133 143 115 0 }
-uchar-16 short-8 vconvert [ . ] bi@"""
-"""short-8{ 8 70 60 50 4 30 200 1 }
-short-8{ 9 10 110 102 133 143 115 0 }""" }
+uchar-16 short-8 vconvert [ . ] bi@"
+"short-8{ 8 70 60 50 4 30 200 1 }
+short-8{ 9 10 110 102 133 143 115 0 }" }
} ;
ARTICLE: "math.vectors.conversion" "SIMD vector conversion"
$nl
"For example, in the following, no SIMD operations are used at all, because the compiler's propagation pass does not consider dynamic variable usage:"
{ $code
-"""USING: compiler.tree.debugger math.vectors
+"USING: compiler.tree.debugger math.vectors
math.vectors.simd ;
SYMBOLS: x y ;
float-4{ 1.5 2.0 3.7 0.4 } x set
float-4{ 1.5 2.0 3.7 0.4 } y set
x get y get v+
-] optimizer-report.""" }
+] optimizer-report." }
"The following word benefits from SIMD optimization, because it begins with an unsafe declaration:"
{ $code
-"""USING: compiler.tree.debugger kernel.private
+"USING: compiler.tree.debugger kernel.private
math.vectors math.vectors.simd ;
IN: simd-demo
{ float-4 float-4 float-4 } declare
[ v* ] [ [ 1.0 ] dip n-v v* ] bi-curry* bi v+ ;
-\\ interpolate optimizer-report.""" }
+\\ interpolate optimizer-report." }
"Note that using " { $link declare } " is not recommended. Safer ways of getting type information for the input parameters to a word include defining methods on a generic word (the value being dispatched upon has a statically known type in the method body), as well as using " { $link "hints" } " and " { $link POSTPONE: inline } " declarations."
$nl
"Here is a better version of the " { $snippet "interpolate" } " words above that uses hints:"
{ $code
-"""USING: compiler.tree.debugger hints
+"USING: compiler.tree.debugger hints
math.vectors math.vectors.simd ;
IN: simd-demo
HINTS: interpolate float-4 float-4 float-4 ;
-\\ interpolate optimizer-report. """ }
+\\ interpolate optimizer-report. " }
"This time, the optimizer report lists calls to both SIMD primitives and high-level vector words, because hints cause two code paths to be generated. The " { $snippet "optimized." } " word can be used to make sure that the fast code path consists entirely of calls to primitives."
$nl
"If the " { $snippet "interpolate" } " word was to be used in several places with different types of vectors, it would be best to declare it " { $link POSTPONE: inline } "."
$nl
"In the " { $snippet "interpolate" } " word, there is still a call to the " { $link <tuple-boa> } " primitive, because the return value at the end is being boxed on the heap. In the next example, no memory allocation occurs at all because the SIMD vectors are stored inside a struct class (see " { $link "classes.struct" } "); also note the use of inlining:"
{ $code
-"""USING: compiler.tree.debugger math.vectors math.vectors.simd ;
+"USING: compiler.tree.debugger math.vectors math.vectors.simd ;
IN: simd-demo
STRUCT: actor
[ >float ] dip
[ update-velocity ] [ update-position ] 2bi ;
-M\\ actor advance optimized."""
+M\\ actor advance optimized."
}
"The " { $vocab-link "compiler.cfg.debugger" } " vocabulary can give a lower-level picture of the generated code, that includes register assignments and other low-level details. To look at low-level optimizer output, call " { $snippet "regs." } " on a word or quotation:"
{ $code
-"""USE: compiler.tree.debugger
+"USE: compiler.tree.debugger
-M\\ actor advance regs.""" }
+M\\ actor advance regs." }
"Example of a high-performance algorithms that use SIMD primitives can be found in the following vocabularies:"
{ $list
{ $vocab-link "benchmark.nbody-simd" }
}
"For an integer vector, false will manifest as " { $snippet "0" } " and true as " { $snippet "-1" } " (for signed vectors) or the largest representable value of the element type (for unsigned vectors):"
{ $example
-"""USING: math.vectors math.vectors.simd prettyprint alien.c-types ;
+"USING: math.vectors math.vectors.simd prettyprint alien.c-types ;
int-4{ 1 2 3 0 } int-4{ 1 -2 3 4 } v=
uchar-16{ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 }
uchar-16{ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 } v<
-[ . ] bi@"""
-"""int-4{ -1 0 -1 0 }
-uchar-16{ 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 }"""
+[ . ] bi@"
+"int-4{ -1 0 -1 0 }
+uchar-16{ 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 }"
}
"This differs from Factor's native representation of boolean values, where " { $link f } " is false and every other value (including " { $snippet "0" } " and " { $snippet "0.0" } ") is true. To make it easy to construct literal SIMD masks, " { $link t } " and " { $link f } " are accepted inside SIMD literal syntax and expand to the proper true or false representation for the underlying type:"
{ $example
-"""USING: math.vectors math.vectors.simd prettyprint alien.c-types ;
+"USING: math.vectors math.vectors.simd prettyprint alien.c-types ;
-int-4{ f f t f } ."""
-"""int-4{ 0 0 -1 0 }""" }
+int-4{ f f t f } ."
+"int-4{ 0 0 -1 0 }" }
"However, extracting an element from a boolean SIMD vector with " { $link nth } " will not yield a valid Factor boolean. This is not generally a problem, since the results of vector comparisons are meant to be consumed by subsequent vector logical and test operations, which will accept SIMD values in the native boolean format."
$nl
"Providing a SIMD boolean vector with element values other than the proper true and false representations as an input to the vector logical or test operations is undefined. Do not count on operations such as " { $link vall? } " or " { $link v? } " using bitwise operations to construct their results."
{ $values { "u" sequence } { "v" sequence } { "w" sequence } }
{ $description "Creates a new sequence of the same type as and twice the length of " { $snippet "u" } " and " { $snippet "v" } " by interleaving the elements of " { $snippet "u" } " and " { $snippet "v" } "." }
{ $examples
-{ $example """USING: kernel math.vectors prettyprint ;
+{ $example "USING: kernel math.vectors prettyprint ;
-{ "A" "B" "C" "D" } { "1" "2" "3" "4" } vmerge ."""
-"""{ "A" "1" "B" "2" "C" "3" "D" "4" }"""
+{ \"A\" \"B\" \"C\" \"D\" } { \"1\" \"2\" \"3\" \"4\" } vmerge ."
+"{ \"A\" \"1\" \"B\" \"2\" \"C\" \"3\" \"D\" \"4\" }"
} } ;
HELP: (vmerge)
{ $description "Creates two new sequences of the same type and size as " { $snippet "u" } " and " { $snippet "v" } " by interleaving the elements of " { $snippet "u" } " and " { $snippet "v" } "." }
{ $notes "For hardware-supported SIMD vector types this word compiles to a single instruction per output value." }
{ $examples
-{ $example """USING: kernel math.vectors prettyprint ;
+{ $example "USING: kernel math.vectors prettyprint ;
-{ "A" "B" "C" "D" } { "1" "2" "3" "4" } (vmerge) [ . ] bi@"""
-"""{ "A" "1" "B" "2" }
-{ "C" "3" "D" "4" }"""
+{ \"A\" \"B\" \"C\" \"D\" } { \"1\" \"2\" \"3\" \"4\" } (vmerge) [ . ] bi@"
+"{ \"A\" \"1\" \"B\" \"2\" }
+{ \"C\" \"3\" \"D\" \"4\" }"
} } ;
HELP: (vmerge-head)
{ $description "Creates a new sequence of the same type and size as " { $snippet "u" } " and " { $snippet "v" } " by interleaving the elements from the first half of " { $snippet "u" } " and " { $snippet "v" } "." }
{ $notes "For hardware-supported SIMD vector types this word compiles to a single instruction." }
{ $examples
-{ $example """USING: kernel math.vectors prettyprint ;
+{ $example "USING: kernel math.vectors prettyprint ;
-{ "A" "B" "C" "D" } { "1" "2" "3" "4" } (vmerge-head) ."""
-"""{ "A" "1" "B" "2" }"""
+{ \"A\" \"B\" \"C\" \"D\" } { \"1\" \"2\" \"3\" \"4\" } (vmerge-head) ."
+"{ \"A\" \"1\" \"B\" \"2\" }"
} } ;
HELP: (vmerge-tail)
{ $description "Creates a new sequence of the same type and size as " { $snippet "u" } " and " { $snippet "v" } " by interleaving the elements from the tail half of " { $snippet "u" } " and " { $snippet "v" } "." }
{ $notes "For hardware-supported SIMD vector types this word compiles to a single instruction." }
{ $examples
-{ $example """USING: kernel math.vectors prettyprint ;
+{ $example "USING: kernel math.vectors prettyprint ;
-{ "A" "B" "C" "D" } { "1" "2" "3" "4" } (vmerge-tail) ."""
-"""{ "C" "3" "D" "4" }"""
+{ \"A\" \"B\" \"C\" \"D\" } { \"1\" \"2\" \"3\" \"4\" } (vmerge-tail) ."
+"{ \"C\" \"3\" \"D\" \"4\" }"
} } ;
{ vmerge (vmerge) (vmerge-head) (vmerge-tail) } related-words
{ $values { "extensions" "A sequence of extension name strings" } { "?" boolean } }
{ $description "Returns true if the set of " { $snippet "extensions" } " is a subset of the implementation-supported extensions returned by " { $link gl-extensions } ". Elements of " { $snippet "extensions" } " can be sequences, in which case true will be returned if any one of the extensions in the subsequence are available." }
{ $examples "Testing for framebuffer object and pixel buffer support:"
- { $code """{
- { "GL_EXT_framebuffer_object" "GL_ARB_framebuffer_object" }
- "GL_ARB_pixel_buffer_object"
-} has-gl-extensions?""" }
+ { $code "{
+ { \"GL_EXT_framebuffer_object\" \"GL_ARB_framebuffer_object\" }
+ \"GL_ARB_pixel_buffer_object\"
+} has-gl-extensions?" }
} ;
HELP: has-gl-version-or-extensions?
HELP: G
{ $description "Makes the OpenGL context associated with " { $link G-world } " active for subsequent OpenGL calls. This is intended to be used from the listener, where interactively entered OpenGL calls can be directed to any window. Note that the Factor UI resets the OpenGL context every time a window is updated, so every code snippet entered in the listener must be prefixed with " { $snippet "G" } " in this use case." }
-{ $examples { $code """USING: opengl.debug ui ;
+{ $examples { $code "USING: opengl.debug ui ;
[ drop t ] find-window G-world set
G 0.0 0.0 1.0 1.0 glClearColor
-G GL_COLOR_BUFFER_BIT glClear""" } } ;
+G GL_COLOR_BUFFER_BIT glClear" } } ;
HELP: F
{ $description "Flushes the OpenGL context associated with " { $link G-world } ", thereby committing any outstanding drawing operations." } ;
[ "USE: peg.ebnf [EBNF EBNF]" eval( -- ) ] must-fail
-[ """USE: peg.ebnf [EBNF
+[ "USE: peg.ebnf [EBNF
lol = a
lol = b
- EBNF]""" eval( -- )
+ EBNF]" eval( -- )
] [
error>> [ redefined-rule? ] [ name>> "lol" = ] bi and
] must-fail-with
M: maybe{ har } harhar ;
M: integer harhar M\ integer harhar drop ;
{
-"""USING: prettyprint.tests ;
+"USING: prettyprint.tests ;
M: maybe{ har } harhar ;
USING: kernel math prettyprint.tests ;
-M: integer harhar M\\ integer harhar drop ;\n"""
+M: integer harhar M\\ integer harhar drop ;\n"
} [
[ \ harhar see-methods ] with-string-writer
] unit-test
TUPLE: fo { a intersection{ fixnum integer } } ;
{
-"""USING: math ;
+"USING: math ;
IN: prettyprint.tests
TUPLE: mo { a union{ integer float } initial: 0 } ;
-"""
+"
} [
[ \ mo see ] with-string-writer
] unit-test
{
-"""USING: math ;
+"USING: math ;
IN: prettyprint.tests
TUPLE: fo { a intersection{ integer fixnum } initial: 0 } ;
-"""
+"
} [
[ \ fo see ] with-string-writer
] unit-test
{
-"""union{ intersection{ string hashtable } union{ integer float } }\n"""
+"union{ intersection{ string hashtable } union{ integer float } }\n"
} [ [ union{ union{ float integer } intersection{ string hashtable } } . ] with-string-writer ] unit-test
{
-"""intersection{
+"intersection{
intersection{ string hashtable }
union{ integer float }
}
-"""
+"
} [ [ intersection{ union{ float integer } intersection{ string hashtable } } . ] with-string-writer ] unit-test
{
-"""maybe{ union{ integer float } }\n"""
+"maybe{ union{ integer float } }\n"
} [
[ maybe{ union{ float integer } } . ] with-string-writer
] unit-test
{
-"""maybe{ maybe{ integer } }\n"""
+"maybe{ maybe{ integer } }\n"
} [
[ maybe{ maybe{ integer } } . ] with-string-writer
] unit-test
] with-string-writer ;
{
-"""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b"""
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b"
} [ margin get 3 - margin-test ] unit-test
{
-"""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b"""
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b"
} [ margin get 2 - margin-test ] unit-test
{
-"""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-b"""
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+b"
} [ margin get 1 - margin-test ] unit-test
sequences splitting kernel io.encodings.8-bit.latin2 ;
IN: quoted-printable.tests
-{ """José was the
+{ "José was the
person who knew how to write the letters:
ő and ü
-and we didn't know hów tö do thât""" }
-[ """Jos=E9 was the
+and we didn't know hów tö do thât" }
+[ "Jos=E9 was the
person who knew how to write the letters:
=F5 and =FC=20
and w=
-e didn't know h=F3w t=F6 do th=E2t""" quoted> latin2 decode ] unit-test
+e didn't know h=F3w t=F6 do th=E2t" quoted> latin2 decode ] unit-test
-{ """Jos=E9 was the=0Aperson who knew how to write the letters:=0A =F5 and =FC=0Aand we didn't know h=F3w t=F6 do th=E2t""" }
-[ """José was the
+{ "Jos=E9 was the=0Aperson who knew how to write the letters:=0A =F5 and =FC=0Aand we didn't know h=F3w t=F6 do th=E2t" }
+[ "José was the
person who knew how to write the letters:
ő and ü
-and we didn't know hów tö do thât""" latin2 encode >quoted ] unit-test
+and we didn't know hów tö do thât" latin2 encode >quoted ] unit-test
: message ( -- str )
55 [ "hello" ] replicate concat ;
"The " { $snippet "+" } " operator matches one or more occurrences of the previous expression; in this case " { $snippet "o" } ". Another useful feature is alternation. Say we want to do this replacement with fooooo or boooo. Then we could use the code"
{ $code "R/ (f|b)oo+/ \"bar\" re-replace" }
"To search a file for all lines that match a given regular expression, you could use code like this:"
-{ $code """"file.txt" ascii file-lines [ R/ (f|b)oo+/ re-contains? ] filter""" }
+{ $code "\"file.txt\" ascii file-lines [ R/ (f|b)oo+/ re-contains? ] filter" }
"To test if a string in its entirety matches a regular expression, the following can be used:"
-{ $example """USE: regexp "fooo" R/ (b|f)oo+/ matches? .""" "t" }
+{ $example "USE: regexp \"fooo\" R/ (b|f)oo+/ matches? ." "t" }
"Regular expressions can't be used for all parsing tasks. For example, they are not powerful enough to match balancing parentheses." ;
ARTICLE: "regexp-construction" "Constructing regular expressions"
HELP: complex-components
{ $class-description "Sequence wrapper class that transforms a sequence of " { $link complex } " number values into a sequence of " { $link real } " values, interleaving the real and imaginary parts of the complex values in the original sequence." }
-{ $examples { $example """USING: prettyprint sequences arrays sequences.complex-components ;
-{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> >array ."""
+{ $examples { $example "USING: prettyprint sequences arrays sequences.complex-components ;
+{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> >array ."
"{ 1.0 -1.0 -2.0 0 3.0 1.0 }" } } ;
HELP: <complex-components>
{ $values { "sequence" sequence } { "complex-components" complex-components } }
{ $description "Wraps " { $snippet "sequence" } " in a " { $link complex-components } " wrapper." }
{ $examples
-{ $example """USING: prettyprint sequences arrays
+{ $example "USING: prettyprint sequences arrays
sequences.complex-components ;
-{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> third ."""
+{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> third ."
"-2.0" }
-{ $example """USING: prettyprint sequences arrays
+{ $example "USING: prettyprint sequences arrays
sequences.complex-components ;
-{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> fourth ."""
+{ C{ 1.0 -1.0 } -2.0 C{ 3.0 1.0 } } <complex-components> fourth ."
"0" }
} ;
HELP: complex-sequence
{ $class-description "Sequence wrapper class that transforms a sequence of " { $link real } " number values into a sequence of " { $link complex } " values, treating the underlying sequence as pairs of alternating real and imaginary values." }
-{ $examples { $example """USING: prettyprint specialized-arrays
+{ $examples { $example "USING: prettyprint specialized-arrays
sequences.complex sequences alien.c-types arrays ;
SPECIALIZED-ARRAY: double
-double-array{ 1.0 -1.0 -2.0 2.0 3.0 0.0 } <complex-sequence> >array ."""
+double-array{ 1.0 -1.0 -2.0 2.0 3.0 0.0 } <complex-sequence> >array ."
"{ C{ 1.0 -1.0 } C{ -2.0 2.0 } C{ 3.0 0.0 } }" } } ;
HELP: <complex-sequence>
{ $values { "sequence" sequence } { "complex-sequence" complex-sequence } }
{ $description "Wraps " { $snippet "sequence" } " in a " { $link complex-sequence } "." }
-{ $examples { $example """USING: prettyprint specialized-arrays
+{ $examples { $example "USING: prettyprint specialized-arrays
sequences.complex sequences alien.c-types arrays ;
SPECIALIZED-ARRAY: double
-double-array{ 1.0 -1.0 -2.0 2.0 3.0 0.0 } <complex-sequence> second ."""
+double-array{ 1.0 -1.0 -2.0 2.0 3.0 0.0 } <complex-sequence> second ."
"C{ -2.0 2.0 }" } } ;
{ complex-sequence <complex-sequence> } related-words
[ [ 2 - ] [ ] [ 1 - ] tri ] 2 nproduce
[ drop ] 2dip ;
-{ """A1a!
+{ "A1a!
B2b@
C3c#
D4d$
-""" } [
+" } [
{ "A" "B" "C" "D" }
{ "1" "2" "3" "4" }
{ "a" "b" "c" "d" }
mnmap-1-test
] unit-test
-{ """A1a!
+{ "A1a!
B2b@
C3c#
D4d$
-""" } [
+" } [
{ "A" "B" "C" "D" }
{ "1" "2" "3" "4" }
{ "a" "b" "c" "d" }
HELP: product-sequence
{ $class-description "A class of virtual sequences that present the cartesian product of their underlying set of sequences. Product sequences are constructed with the " { $link <product-sequence> } " word." }
{ $examples
-{ $example """USING: arrays prettyprint sequences.product ;
-{ { 1 2 3 } { "a" "b" "c" } } <product-sequence> >array .
-""" """{
- { 1 "a" }
- { 2 "a" }
- { 3 "a" }
- { 1 "b" }
- { 2 "b" }
- { 3 "b" }
- { 1 "c" }
- { 2 "c" }
- { 3 "c" }
-}""" } } ;
+{ $example "USING: arrays prettyprint sequences.product ;
+{ { 1 2 3 } { \"a\" \"b\" \"c\" } } <product-sequence> >array .
+" "{
+ { 1 \"a\" }
+ { 2 \"a\" }
+ { 3 \"a\" }
+ { 1 \"b\" }
+ { 2 \"b\" }
+ { 3 \"b\" }
+ { 1 \"c\" }
+ { 2 \"c\" }
+ { 3 \"c\" }
+}" } } ;
HELP: <product-sequence>
{ $values { "sequences" sequence } { "product-sequence" product-sequence } }
{ $description "Constructs a " { $link product-sequence } " over " { $snippet "sequences" } "." }
{ $examples
-{ $example """USING: arrays prettyprint sequences.product ;
-{ { 1 2 3 } { "a" "b" "c" } } <product-sequence> >array ."""
-"""{
- { 1 "a" }
- { 2 "a" }
- { 3 "a" }
- { 1 "b" }
- { 2 "b" }
- { 3 "b" }
- { 1 "c" }
- { 2 "c" }
- { 3 "c" }
-}""" } } ;
+{ $example "USING: arrays prettyprint sequences.product ;
+{ { 1 2 3 } { \"a\" \"b\" \"c\" } } <product-sequence> >array ."
+"{
+ { 1 \"a\" }
+ { 2 \"a\" }
+ { 3 \"a\" }
+ { 1 \"b\" }
+ { 2 \"b\" }
+ { 3 \"b\" }
+ { 1 \"c\" }
+ { 2 \"c\" }
+ { 3 \"c\" }
+}" } } ;
{ product-sequence <product-sequence> } related-words
{ $code
"USING: smtp namespaces io.sockets ;"
""
- """default-smtp-config
- "smtp.gmail.com" 587 <inet> >>server
+ "default-smtp-config
+ \"smtp.gmail.com\" 587 <inet> >>server
t >>tls?
- "my.gmail.address@gmail.com" "qwertyuiasdfghjk" <plain-auth> >>auth
- \\ smtp-config set-global"""
+ \"my.gmail.address@gmail.com\" \"qwertyuiasdfghjk\" <plain-auth> >>auth
+ \\ smtp-config set-global"
} ;
SYMBOL: __does_not_exist__
[
- """
+ "
IN: specialized-arrays.tests
USING: specialized-arrays ;
-SPECIALIZED-ARRAY: __does_not_exist__ """ eval( -- )
+SPECIALIZED-ARRAY: __does_not_exist__ " eval( -- )
] must-fail
{ } [
- """
+ "
IN: specialized-arrays.tests
USING: alien.c-types classes.struct specialized-arrays ;
STRUCT: __does_not_exist__ { x int } ;
SPECIALIZED-ARRAY: __does_not_exist__
-""" eval( -- )
+" eval( -- )
] unit-test
{ f } [
{ $values { "vector" "a specialized vector of structs" } { "new" "a new value of the specialized vector's type" } }
{ $description "Grows " { $snippet "vector" } ", increasing its length by one, and outputs a " { $link struct } " object wrapping the newly allocated storage." }
{ $notes "This word allows struct objects to be streamed into a struct vector efficiently without excessive copying. The typical Factor idiom for pushing a new object onto a vector, when used with struct vectors, will allocate and copy a temporary struct object:"
-{ $code """foo <struct>
+{ $code "foo <struct>
5 >>a
6 >>b
-foo-vector{ } clone push""" }
+foo-vector{ } clone push" }
"By using " { $snippet "push-new" } ", the new struct can be allocated directly from the vector and the intermediate copy can be avoided:"
-{ $code """foo-vector{ } clone push-new
+{ $code "foo-vector{ } clone push-new
5 >>a
6 >>b
- drop""" } } ;
+ drop" } } ;
ARTICLE: "specialized-vector-c" "Passing specialized vectors to C functions"
"Each specialized vector has a " { $slot "underlying" } " slot holding a specialized array, which in turn has an " { $slot "underlying" } " slot holding a " { $link byte-array } " with the raw data. Passing a specialized vector as a parameter to a C function call will automatically extract the underlying data. To get at the underlying data directly, call the " { $link >c-ptr } " word on a specialized vector." ;
{ $example
"USING: splitting.monotonic math prettyprint ;"
"{ 1 2 3 2 3 4 } [ < ] monotonic-split-slice ."
- """{
+ "{
T{ slice { to 3 } { seq { 1 2 3 2 3 4 } } }
T{ slice { from 3 } { to 6 } { seq { 1 2 3 2 3 4 } } }
-}"""
+}"
}
} ;
{ $example
"USING: splitting.monotonic math prettyprint ;"
"{ 1 2 3 3 2 1 } trends ."
- """{
+ "{
T{ upward-slice { to 3 } { seq { 1 2 3 3 2 1 } } }
T{ stable-slice
{ from 2 }
{ to 6 }
{ seq { 1 2 3 3 2 1 } }
}
-}"""
+}"
}
} ;
{ $examples
{ $code
"USING: timers io calendar ;"
- """[ "Hi Buddy." print flush ] 10 seconds every drop"""
+ "[ \"Hi Buddy.\" print flush ] 10 seconds every drop"
}
} ;
{ $examples
{ $code
"USING: timers io calendar ;"
- """[ "Break's over!" print flush ] 15 minutes later drop"""
+ "[ \"Break's over!\" print flush ] 15 minutes later drop"
}
} ;
{ $examples
{ $code
"USING: timers io calendar ;"
- """[ "Hi Buddy." print flush ] 10 seconds every drop"""
+ "[ \"Hi Buddy.\" print flush ] 10 seconds every drop"
}
} ;
"Profile data can be saved for future reporting:"
{ $subsections most-recent-profile-data top-down* top-down-max-depth* cross-section* flat* }
"For example, the following will profile a call to the foo word, and generate and display a top-down tree profile from the results:"
-{ $code """[ foo ] profile
-top-down profile.""" }
+{ $code "[ foo ] profile
+top-down profile." }
;
ABOUT: "tools.profiler.sampling"
"Create docs for the + word:"
{ $example "USING: math tools.scaffold prettyprint ;"
"\\ + scaffold-examples"
- """{ $examples
- "Example:"
- { $example "USING: math prettyprint ;"
- ""
- ""
+ "{ $examples
+ \"Example:\"
+ { $example \"USING: math prettyprint ;\"
+ \"\"
+ \"\"
}
- "Example:"
- { $example "USING: math prettyprint ;"
- ""
- ""
+ \"Example:\"
+ { $example \"USING: math prettyprint ;\"
+ \"\"
+ \"\"
}
-}"""
+}"
}
} ;
[ >lower ] [ >upper ] bi* ;
{
-"""HELP: undocumented-word
+"HELP: undocumented-word
{ $values
- { "obj1" object } { "obj2" object }
- { "obj3" object } { "obj4" object }
+ { \"obj1\" object } { \"obj2\" object }
+ { \"obj3\" object } { \"obj4\" object }
}
-{ $description "" } ;
-"""
+{ $description \"\" } ;
+"
}
[
[ \ undocumented-word (help.) ] with-string-writer
: example-using ( using -- )
" " join "example-using" [
nested-examples get 4 0 ? CHAR: \s <string> "example-indent" [
- """${example-indent}"Example:"
-${example-indent}{ $example "USING: ${example-using} ;"
-${example-indent} ""
-${example-indent} ""
+ "${example-indent}\"Example:\"
+${example-indent}{ $example \"USING: ${example-using} ;\"
+${example-indent} \"\"
+${example-indent} \"\"
${example-indent}}
-"""
+"
interpolate
] with-variable
] with-variable ;
HELP: TYPED:
{ $syntax
-"""TYPED: word ( a b: class ... -- x: class y ... )
- body ;""" }
+"TYPED: word ( a b: class ... -- x: class y ... )
+ body ;" }
{ $description "Like " { $link POSTPONE: : } ", defines a new word with a given stack effect in the current vocabulary. The inputs and outputs of the stack effect can additionally be given type annotations in the form " { $snippet "a: class" } ". When invoked, the word will attempt to coerce its input values to the declared input types before executing the body, throwing an " { $link input-mismatch-error } " if the types cannot be made to match. The word will likewise attempt to coerce its outputs to their declared types and throw an " { $link output-mismatch-error } " if the types cannot be made to match." }
{ $notes "The aforementioned type conversions and checks are structured in such a way that they will be eliminated by the compiler if it can statically determine that the types of the inputs at a call site or of the outputs in the word definition are always correct." }
{ $examples
"A version of " { $link + } " specialized for floats, converting other real number types:"
{ $example
-"""USING: math prettyprint typed ;
+"USING: math prettyprint typed ;
IN: scratchpad
TYPED: add-floats ( a: float b: float -- c: float )
+ ;
-1 2+1/2 add-floats ."""
+1 2+1/2 add-floats ."
"3.5" } } ;
HELP: TYPED::
{ $syntax
-"""TYPED:: word ( a b: class ... -- x: class y ... )
- body ;""" }
+"TYPED:: word ( a b: class ... -- x: class y ... )
+ body ;" }
{ $description "Like " { $link POSTPONE: :: } ", defines a new word with named inputs in the current vocabulary. The inputs and outputs of the stack effect can additionally be given type annotations in the form " { $snippet "a: class" } ". When invoked, the word will attempt to coerce its input values to the declared input types before executing the body, throwing an " { $link input-mismatch-error } " if the types cannot be made to match. The word will likewise attempt to coerce its outputs to their declared types and throw an " { $link output-mismatch-error } " if the types cannot be made to match." }
{ $notes "The aforementioned type conversions and checks are structured in such a way that they will be eliminated by the compiler if it can statically determine that the types of the inputs at a call site or of the outputs in the word definition are always correct." }
{ $examples
"A version of the quadratic formula specialized for floats, converting other real number types:"
{ $example
-"""USING: kernel math math.libm prettyprint typed ;
+"USING: kernel math math.libm prettyprint typed ;
IN: scratchpad
TYPED:: quadratic-roots ( a: float b: float c: float -- q1: float q2: float )
[ + ] [ - ] 2bi
[ 2.0 a * / ] bi@ ;
-1 0 -9/4 quadratic-roots [ . ] bi@"""
-"""1.5
--1.5""" } } ;
+1 0 -9/4 quadratic-roots [ . ] bi@"
+"1.5
+-1.5" } } ;
HELP: define-typed
{ $values { "word" word } { "def" quotation } { "effect" effect } }
{ 9 }
[
-"""
+"
USING: kernel math ;
IN: typed.tests
{ x fixnum read-only }
{ y fixnum read-only }
{ z float read-only } ; final
-""" eval( -- )
+" eval( -- )
-"""
+"
USING: accessors kernel math ;
IN: typed.tests
T{ unboxable f 12 3 4.0 } unboxy xy>>
-""" eval( -- xy )
+" eval( -- xy )
] unit-test
TYPED: no-inputs ( -- out: integer )
[ 0 typed-intersection ] [ input-mismatch-error? ] must-fail-with
[
- """IN: test123 USE: typed TYPED: foo ( x -- y ) ;""" eval( -- )
+ "IN: test123 USE: typed TYPED: foo ( x -- y ) ;" eval( -- )
] [ error>> no-types-specified? ] must-fail-with
}
{ $examples
"The following " { $link world } " subclass will request a double-buffered window with minimum 24-bit color and depth buffers, and will throw an error if the requirements aren't met:"
-{ $code """USING: kernel ui.gadgets.worlds ui.pixel-formats ;
+{ $code "USING: kernel ui.gadgets.worlds ui.pixel-formats ;
IN: ui.pixel-formats.examples
TUPLE: picky-depth-buffered-world < world ;
M: picky-depth-buffered-world check-world-pixel-format
nip
- [ double-buffered pixel-format-attribute 0 = [ "Not double buffered!" throw ] when ]
- [ color-bits pixel-format-attribute 24 < [ "Not enough color bits!" throw ] when ]
- [ depth-bits pixel-format-attribute 24 < [ "Not enough depth bits!" throw ] when ]
- tri ;""" } }
+ [ double-buffered pixel-format-attribute 0 = [ \"Not double buffered!\" throw ] when ]
+ [ color-bits pixel-format-attribute 24 < [ \"Not enough color bits!\" throw ] when ]
+ [ depth-bits pixel-format-attribute 24 < [ \"Not enough depth bits!\" throw ] when ]
+ tri ;" } }
;
HELP: double-buffered
"Then you can run the following code, or add it to your " { $link ".factor-rc" } "."
$nl
{ $code
- """USING: accessors assocs kernel sequences sets ui.commands
+ "USING: accessors assocs kernel sequences sets ui.commands
ui.gadgets.editors ui.gestures ui.tools.listener ;
-"multiline" multiline-editor get-command-at [
+\"multiline\" multiline-editor get-command-at [
{
- { T{ key-down f { C+ } "k" } delete-to-end-of-line }
- { T{ key-down f { C+ } "a" } start-of-line }
- { T{ key-down f { C+ } "e" } end-of-line }
+ { T{ key-down f { C+ } \"k\" } delete-to-end-of-line }
+ { T{ key-down f { C+ } \"a\" } start-of-line }
+ { T{ key-down f { C+ } \"e\" } end-of-line }
} append members
] change-commands drop multiline-editor update-gestures
-"interactor" interactor get-command-at [
- [ drop T{ key-down f { C+ } "k" } = ] assoc-reject
-] change-commands drop interactor update-gestures"""
+\"interactor\" interactor get-command-at [
+ [ drop T{ key-down f { C+ } \"k\" } = ] assoc-reject
+] change-commands drop interactor update-gestures"
}
$nl
{ $heading "Implementation" }
{ $examples
"From the " { $vocab-link "hello-ui" } " vocabulary. Creates a window with the title \"Hi\" containing a label reading \"Hello world\":"
{ $code
-"""USING: accessors ui ui.gadgets.labels ;
+"USING: accessors ui ui.gadgets.labels ;
IN: hello-ui
-MAIN-WINDOW: hello { { title "Hi" } }
- "Hello world" <label> >>gadgets ;"""
+MAIN-WINDOW: hello { { title \"Hi\" } }
+ \"Hello world\" <label> >>gadgets ;"
} } ;
ARTICLE: "ui.gadgets.worlds-window-controls" "Window controls"
"USING: prettyprint urls.encoding ;"
"\"gender=female&agefrom=22&ageto=28&location=Omaha+NE\""
"query>assoc ."
- """H{
- { "gender" "female" }
- { "agefrom" "22" }
- { "ageto" "28" }
- { "location" "Omaha NE" }
-}"""
+ "H{
+ { \"gender\" \"female\" }
+ { \"agefrom\" \"22\" }
+ { \"ageto\" \"28\" }
+ { \"location\" \"Omaha NE\" }
+}"
}
} ;
}
{ $examples
{ $code
- """USING: kernel http.client urls ;
-URL" http://search.yahooapis.com/WebSearchService/V1/webSearch" clone
- "concatenative programming (NSFW)" "query" set-query-param
- "1" "adult_ok" set-query-param
-http-get"""
+ "USING: kernel http.client urls ;
+URL\" http://search.yahooapis.com/WebSearchService/V1/webSearch\" clone
+ \"concatenative programming (NSFW)\" \"query\" set-query-param
+ \"1\" \"adult_ok\" set-query-param
+http-get"
}
"(For a complete Yahoo! search web service implementation, see the " { $vocab-link "yahoo" } " vocabulary.)"
}
IN: vocabs.prettyprint.tests
: manifest-test-1 ( -- string )
- """USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
+ "USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
- << manifest get pprint-manifest >>""" ;
+ << manifest get pprint-manifest >>" ;
{
-"""USING: kernel namespaces vocabs.parser vocabs.prettyprint ;"""
+"USING: kernel namespaces vocabs.parser vocabs.prettyprint ;"
}
[ [ manifest-test-1 eval( -- ) ] with-string-writer ] unit-test
: manifest-test-2 ( -- string )
- """USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
+ "USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
IN: vocabs.prettyprint.tests
- << manifest get pprint-manifest >>""" ;
+ << manifest get pprint-manifest >>" ;
{
-"""USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
-IN: vocabs.prettyprint.tests"""
+"USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
+IN: vocabs.prettyprint.tests"
}
[ [ manifest-test-2 eval( -- ) ] with-string-writer ] unit-test
: manifest-test-3 ( -- string )
- """USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
+ "USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
FROM: math => + - ;
QUALIFIED: system
QUALIFIED-WITH: assocs a
EXCLUDE: parser => run-file ;
IN: vocabs.prettyprint.tests
- << manifest get pprint-manifest >>""" ;
+ << manifest get pprint-manifest >>" ;
{
-"""USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
+"USING: kernel namespaces vocabs.parser vocabs.prettyprint ;
FROM: math => + - ;
QUALIFIED: system
QUALIFIED-WITH: assocs a
EXCLUDE: parser => run-file ;
-IN: vocabs.prettyprint.tests"""
+IN: vocabs.prettyprint.tests"
}
[ [ manifest-test-3 eval( -- ) ] with-string-writer ] unit-test
{
-"""USING: alien.c-types alien.syntax byte-arrays io
+"USING: alien.c-types alien.syntax byte-arrays io
io.encodings.binary io.encodings.string io.encodings.utf8
-io.streams.byte-array kernel sequences system system-info unix ;"""
+io.streams.byte-array kernel sequences system system-info unix ;"
} [
[
{
{ $description "\nCreate a COM globally-unique identifier (GUID) literal at parse time, and push it onto the data stack." } ;
HELP: COM-INTERFACE:
-{ $syntax """COM-INTERFACE: <interface> <parent> <iid>
+{ $syntax "COM-INTERFACE: <interface> <parent> <iid>
<function-1> ( <params1> )
<function-2> ( <params2> )
... ;
-""" }
+" }
{ $description "\nFor the interface " { $snippet "<interface>" } ", a word " { $snippet "<interface>-iid ( -- iid )" } " is defined to push the interface GUID (IID) onto the stack. Words of the form " { $snippet "<interface>::<function>" } " are also defined to invoke each method, as well as the methods inherited from " { $snippet "<parent>" } ". A " { $snippet "<parent>" } " of " { $snippet "f" } " indicates that the interface is a root interface. (Note that COM conventions demand that all interfaces at least inherit from " { $snippet "IUnknown" } ".)\n\nExample:" }
-{ $code """
+{ $code "
COM-INTERFACE: IUnknown f {00000000-0000-0000-C000-000000000046}
HRESULT QueryInterface ( REFGUID iid, void** ppvObject )
ULONG AddRef ( )
COM-INTERFACE: IInherited ISimple {9620ecec-8438-423b-bb14-86f835aa40dd}
int getX ( )
void setX ( int newX ) ;
-""" } ;
+" } ;
HELP: <com-wrapper>
{ $values { "implementations" "an assoc relating COM interface names to arrays of quotations implementing that interface" } { "wrapper" "a " { $link com-wrapper } " tuple" } }
{ $description "Constructs a " { $link com-wrapper } " tuple. Each key in the " { $snippet "implementations" } " assoc must be the name of an interface defined with " { $link POSTPONE: COM-INTERFACE: } ". The corresponding value must be an array of quotations implementing the methods of that interface in order, including those of its parent interfaces. The " { $snippet "IUnknown" } " methods (" { $link IUnknown::QueryInterface } ", " { $link IUnknown::AddRef } ", and " { $link IUnknown::Release } ") will be defined automatically and must not be specified in the array. These quotations should have stack effects mirroring those of the interface methods being implemented; for example, a method " { $snippet "void foobar ( int foo, int bar )" } " should be implemented with a quotation of effect " { $snippet "( this foo bar -- )" } ". The " { $snippet "this" } " parameter (that is, the leftmost parameter of any COM method) will be automatically converted from an alien pointer to the underlying Factor object before the quotation is invoked.\n\nThe resulting wrapper can be applied to a Factor object using the " { $link com-wrap } " word. The COM interface pointer returned by " { $snippet "com-wrap" } " can then be passed to C functions requiring a COM object as a parameter. The vtables constructed by " { $snippet "<com-wrapper>" } " are stored on the non-GC heap in order to be accessible to C functions; when the wrapper object and its vtables are no longer needed, the object's resources must be freed using " { $link dispose } ".\n\nExample:" }
-{ $code """
+{ $code "
COM-INTERFACE: ISimple IUnknown {216fb341-0eb2-44b1-8edb-60b76e353abc}
HRESULT returnOK ( )
HRESULT returnError ( ) ;
int xMulAdd ( int mul, int add ) ;
{
- { "IInherited" {
+ { \"IInherited\" {
[ drop S_OK ] ! ISimple::returnOK
[ drop E_FAIL ] ! ISimple::returnError
[ x>> ] ! IInherited::getX
[ >>x drop ] ! IInherited::setX
} }
- { "IUnrelated" {
+ { \"IUnrelated\" {
[ [ x>> ] [ + ] bi* ] ! IUnrelated::xPlus
[ [ x>> ] [ * ] [ + ] tri* ] ! IUnrealted::xMulAdd
} }
-} <com-wrapper>""" } ;
+} <com-wrapper>" } ;
HELP: com-wrap
{ $values { "object" "The factor object to wrap" } { "wrapper" "A " { $link com-wrapper } " object" } { "wrapped-object" "A COM object referencing " { $snippet "object" } } }
IN: wrap.strings.tests
{
- """This is a
+ "This is a
long piece
of text
that we
wish to
-word wrap."""
+word wrap."
} [
- """This is a long piece of text that we wish to word wrap.""" 10
+ "This is a long piece of text that we wish to word wrap." 10
wrap-string
] unit-test
{
- """ This is a
+ " This is a
long piece
of text
that we
wish to
- word wrap."""
+ word wrap."
} [
- """This is a long piece of text that we wish to word wrap.""" 12
+ "This is a long piece of text that we wish to word wrap." 12
" " wrap-indented-string
] unit-test
{ t } [
- """This is a long piece of text that we wish to word wrap.""" 12
+ "This is a long piece of text that we wish to word wrap." 12
[ " " wrap-indented-string ] [ 2 wrap-indented-string ] 2bi =
] unit-test
$nl
"These forms can be used where a tag might go, as in " { $snippet "[XML <foo><-></foo> XML]" } " or where an attribute might go, as in " { $snippet "[XML <foo bar=<->/> XML]" } ". When an attribute is spliced in, it is not included if the value is " { $snippet "f" } " and if the value is not a string, the value is put through " { $link present } ". Here is an example of the fry style of XML interpolation:"
{ $example
-"""USING: splitting xml.writer xml.syntax ;
-"one two three" " " split
+"USING: splitting xml.writer xml.syntax ;
+\"one two three\" \" \" split
[ [XML <item><-></item> XML] ] map
-<XML <doc><-></doc> XML> pprint-xml"""
+<XML <doc><-></doc> XML> pprint-xml"
-"""<?xml version="1.0" encoding="UTF-8"?>
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<doc>
<item>
one
<item>
three
</item>
-</doc>""" }
+</doc>" }
"Here is an example of the locals version:"
{ $example
-"""USING: locals urls xml.syntax xml.writer ;
+"USING: locals urls xml.syntax xml.writer ;
[let
3 :> number
f :> false
- URL" http://factorcode.org/" :> url
- "hello" :> string
+ URL\" http://factorcode.org/\" :> url
+ \"hello\" :> string
\\ drop :> word
<XML
<x
string=<-string->
word=<-word-> />
XML> pprint-xml
-]"""
+]"
-"""<?xml version="1.0" encoding="UTF-8"?>
-<x number="3" url="http://factorcode.org/" string="hello" word="drop"/>""" }
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<x number=\"3\" url=\"http://factorcode.org/\" string=\"hello\" word=\"drop\"/>" }
"XML interpolation can also be used, in conjunction with " { $vocab-link "inverse" } " in pattern matching. For example:"
-{ $example """USING: xml.syntax inverse ;
+{ $example "USING: xml.syntax inverse ;
: dispatch ( xml -- string )
{
- { [ [XML <a><-></a> XML] ] [ "a" prepend ] }
- { [ [XML <b><-></b> XML] ] [ "b" prepend ] }
- { [ [XML <b val='yes'/> XML] ] [ "yes" ] }
- { [ [XML <b val=<->/> XML] ] [ "no" prepend ] }
+ { [ [XML <a><-></a> XML] ] [ \"a\" prepend ] }
+ { [ [XML <b><-></b> XML] ] [ \"b\" prepend ] }
+ { [ [XML <b val='yes'/> XML] ] [ \"yes\" ] }
+ { [ [XML <b val=<->/> XML] ] [ \"no\" prepend ] }
} switch ;
-[XML <a>pple</a> XML] dispatch write"""
+[XML <a>pple</a> XML] dispatch write"
"apple" } ;
HELP: XML-NS:
[ extract-variables ] tri
] unit-test
-{ """<?xml version="1.0" encoding="UTF-8"?>
+{ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<x>
one
- <b val="two"/>
+ <b val=\"two\"/>
y
<foo/>
-</x>""" } [
+</x>" } [
[let "one" :> a "two" :> c "y" :> x [XML <-x-> <foo/> XML] :> d
<XML
<x> <-a-> <b val=<-c->/> <-d-> </x>
]
] unit-test
-{ """<?xml version="1.0" encoding="UTF-8"?>
+{ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<doc>
<item>
one
<item>
three
</item>
-</doc>""" } [
+</doc>" } [
"one two three" " " split
[ [XML <item><-></item> XML] ] map
<XML <doc><-></doc> XML> pprint-xml>string
] unit-test
-{ """<?xml version="1.0" encoding="UTF-8"?>
-<x number="3" url="http://factorcode.org/" string="hello" word="drop"/>""" }
+{ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<x number=\"3\" url=\"http://factorcode.org/\" string=\"hello\" word=\"drop\"/>" }
[ 3 f "http://factorcode.org/" "hello" \ drop
<XML <x number=<-> false=<-> url=<-> string=<-> word=<->/> XML>
pprint-xml>string ] unit-test
! Make sure nested XML documents interpolate correctly
{
- """<?xml version="1.0" encoding="UTF-8"?><color><blue>it's blue!</blue></color>"""
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><color><blue>it's blue!</blue></color>"
} [
"it's blue!" <XML <blue><-></blue> XML>
<XML <color><-></color> XML> xml>string
] unit-test
{
- """<?xml version="1.0" encoding="UTF-8"?><a>asdf<asdf/>asdf2</a>"""
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a>asdf<asdf/>asdf2</a"
} [
default-prolog
"asdf"
IN: xml.tests
{
-"""<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0">
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<rss version=\"2.0\">
<channel>
<item>
<description>Python has a n class property in [&#8230;]</description>
</item>
</channel>
-</rss>"""
+</rss>"
} [
-"""<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0">
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<rss version=\"2.0\">
<channel>
<item>
<description><![CDATA[Python has a n class property in […]]]></description>
</item>
</channel>
-</rss>""" string>xml xml>string
+</rss>" string>xml xml>string
] unit-test
ARTICLE: { "xml.traversal" "intro" } "An example of XML processing"
"To illustrate how to use the XML library, we develop a simple Atom parser in Factor. Atom is an XML-based syndication format, like RSS. To see the full version of what we develop here, look at " { $snippet "basis/syndication" } " at the " { $snippet "atom1.0" } " word. First, we want to load a file and get a DOM tree for it."
-{ $code """"file.xml" file>xml""" }
+{ $code "\"file.xml\" file>xml" }
"No encoding descriptor is needed, because XML files contain sufficient information to auto-detect the encoding. Next, we want to extract information from the tree. To get the title, we can use the following:"
-{ $code """"title" tag-named children>string""" }
+{ $code "\"title\" tag-named children>string" }
"The " { $link tag-named } " word finds the first tag named " { $snippet "title" } " in the top level (just under the main tag). Then, with a tag on the stack, its children are asserted to be a string, and the string is returned." $nl
"For a slightly more complicated example, we can look at how entries are parsed. To get a sequence of tags with the name " { $snippet "entry" } ":"
-{ $code """"entry" tags-named""" }
+{ $code "\"entry\" tags-named" }
"Imagine that, for each of these, we want to get the URL of the entry. In Atom, the URLs are in a " { $snippet "link" } " tag which is contained in the " { $snippet "entry" } " tag. There are multiple " { $snippet "link" } " tags, but one of them contains the attribute " { $snippet "rel=alternate" } ", and the " { $snippet "href" } " attribute has the URL. So, given an element of the sequence produced in the above quotation, we run the code:"
-{ $code """"link" tags-named [ "rel" attr "alternate" = ] find nip """ }
+{ $code "\"link\" tags-named [ \"rel\" attr \"alternate\" = ] find nip " }
"to get the link tag on the stack, and"
-{ $code """"href" attr >url """ }
+{ $code "\"href\" attr >url " }
"to extract the URL from it." ;
HELP: deep-tag-named
HELP: indenter
{ $var-description "Contains the string which is used for indenting in the XML prettyprinter. For example, to print an XML document using " { $snippet "%%%%" } " for indentation, you can use the following:" }
-{ $example """USING: xml.syntax xml.writer namespaces ;
-[XML <foo>bar</foo> XML] "%%%%" indenter [ pprint-xml ] with-variable """ """
+{ $example "USING: xml.syntax xml.writer namespaces ;
+[XML <foo>bar</foo> XML] \"%%%%\" indenter [ pprint-xml ] with-variable " "
<foo>
%%%%bar
-</foo>""" } ;
+</foo>" } ;
HELP: sensitive-tags
{ $var-description "Contains a sequence of " { $link name } "s where whitespace should be considered significant for prettyprinting purposes. The sequence can contain " { $link string } "s in place of names. For example, to preserve whitespace inside a " { $snippet "pre" } " tag:" }
-{ $example """USING: xml.syntax xml.writer namespaces ;
+{ $example "USING: xml.syntax xml.writer namespaces ;
[XML <html> <head> <title> something</title></head><body><pre>bing
bang
- bong</pre></body></html> XML] { "pre" } sensitive-tags [ pprint-xml ] with-variable"""
-"""
+ bong</pre></body></html> XML] { \"pre\" } sensitive-tags [ pprint-xml ] with-variable"
+"
<html>
<head>
<title>
bang
bong</pre>
</body>
-</html>""" } ;
+</html>" } ;
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><x/>" reprints-same
-"""<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE foo [<!ENTITY foo "bar">]>
-<x>bar</x>"""
-"""<?xml version="1.0" encoding="UTF-8"?>
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE foo [<!ENTITY foo \"bar\">]>
+<x>bar</x>"
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE foo [<!ENTITY foo 'bar'>]>
-<x>&foo;</x>""" reprints-as
+<x>&foo;</x>" reprints-as
-"""<?xml version="1.0" encoding="UTF-8"?>
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE foo [
- <!ENTITY foo "bar">
+ <!ENTITY foo \"bar\">
<!ELEMENT br EMPTY>
- <!ATTLIST list type (bullets|ordered|glossary) "ordered">
+ <!ATTLIST list type (bullets|ordered|glossary) \"ordered\">
<!NOTATION foo bar>
<?baz bing bang bong?>
<!--wtf-->
]>
<x>
bar
-</x>"""
-"""<?xml version="1.0" encoding="UTF-8"?>
+</x>"
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE foo [ <!ENTITY foo 'bar'> <!ELEMENT br EMPTY>
<!ATTLIST list
- type (bullets|ordered|glossary) "ordered">
+ type (bullets|ordered|glossary) \"ordered\">
<!NOTATION foo bar> <?baz bing bang bong?>
<!--wtf-->
]>
-<x>&foo;</x>""" pprint-reprints-as
+<x>&foo;</x>" pprint-reprints-as
{ t } [ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\" >" dup string>xml-chunk xml>string = ] unit-test
{ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a b=\"c\"/>" }
{ } [ \ (load-mode) reset-memoized ] unit-test
{ } [
- """<style type="text/css" media="screen" >
- * {margin:0; padding:0; border:0;}"""
+ "<style type=\"text/css\" media=\"screen\" >
+ * {margin:0; padding:0; border:0;}"
string-lines "html" htmlize-lines drop
] unit-test
{ } [
"test.c"
- """int x = "hi";
-/* a comment */""" <string-reader> htmlize-stream
+ "int x = \"hi\";
+/* a comment */" <string-reader> htmlize-stream
write-xml
] unit-test
{ $examples
{ $example
"USING: checksums checksums.crc32 prettyprint ;"
-"""{
- "Take me out to the ball game"
- "Take me out with the crowd"
-} crc32 checksum-lines ."""
+"{
+ \"Take me out to the ball game\"
+ \"Take me out with the crowd\"
+} crc32 checksum-lines ."
"B{ 111 205 9 27 }"
}
} ;
{ $examples
{ $example
"USING: checksums checksums.crc32 prettyprint ;"
- """"resource:license.txt" crc32 checksum-file ."""
+ "\"resource:license.txt\" crc32 checksum-file ."
"B{ 100 139 199 92 }"
}
} ;
! So the user has some code...
{ } [
- """IN: classes.test.a
+ "IN: classes.test.a
GENERIC: g ( a -- b )
TUPLE: x ;
M: x g ;
- TUPLE: z < x ;""" <string-reader>
+ TUPLE: z < x ;" <string-reader>
"class-intersect-no-method-a" parse-stream drop
] unit-test
! Note that q inlines M: x g ;
{ } [
- """IN: classes.test.b
+ "IN: classes.test.b
USE: classes.test.a
USE: kernel
- : q ( -- b ) z new g ;""" <string-reader>
+ : q ( -- b ) z new g ;" <string-reader>
"class-intersect-no-method-b" parse-stream drop
] unit-test
! Now, the user removes the z class and adds a method,
{ } [
- """IN: classes.test.a
+ "IN: classes.test.a
GENERIC: g ( a -- b )
TUPLE: x ;
M: x g ;
TUPLE: j ;
- M: j g ;""" <string-reader>
+ M: j g ;" <string-reader>
"class-intersect-no-method-a" parse-stream drop
] unit-test
! And changes the definition of q
{ } [
- """IN: classes.test.b
+ "IN: classes.test.b
USE: classes.test.a
USE: kernel
- : q ( -- b ) j new g ;""" <string-reader>
+ : q ( -- b ) j new g ;" <string-reader>
"class-intersect-no-method-b" parse-stream drop
] unit-test
! Similar problem, but with anonymous classes
{ } [
- """IN: classes.test.c
+ "IN: classes.test.c
USE: kernel
GENERIC: g ( a -- b )
M: object g ;
- TUPLE: z ;""" <string-reader>
+ TUPLE: z ;" <string-reader>
"class-intersect-no-method-c" parse-stream drop
] unit-test
{ } [
- """IN: classes.test.d
+ "IN: classes.test.d
USE: classes.test.c
USE: kernel
- : q ( a -- b ) dup z? [ g ] unless ;""" <string-reader>
+ : q ( a -- b ) dup z? [ g ] unless ;" <string-reader>
"class-intersect-no-method-d" parse-stream drop
] unit-test
! Now, the user removes the z class and adds a method,
{ } [
- """IN: classes.test.c
+ "IN: classes.test.c
USE: kernel
GENERIC: g ( a -- b )
M: object g ;
TUPLE: j ;
- M: j g ;""" <string-reader>
+ M: j g ;" <string-reader>
"class-intersect-no-method-c" parse-stream drop
] unit-test
{ $description "Constructs an " { $link effect } " object. Each element of " { $snippet "in" } " and " { $snippet "out" } " must be either a string, which is equivalent to a " { $snippet "name" } " in literal stack effect syntax, or a " { $link pair } " where the first element is a string and the second is either a " { $link class } " or effect, which is equivalent to " { $snippet "name: class" } " or " { $snippet "name: ( nested -- effect )" } " in the literal syntax. If the " { $snippet "out" } " array consists of a single string element " { $snippet "\"*\"" } ", a terminating stack effect will be constructed." }
{ $notes "This word cannot construct effects with " { $link "effects-variables" } ". Use " { $link <variable-effect> } " to construct variable stack effects." }
{ $examples
-{ $example """USING: effects prettyprint ;
-{ "a" "b" } { "c" } <effect> .""" """( a b -- c )""" }
-{ $example """USING: arrays effects prettyprint ;
-{ "a" { "b" array } } { "c" } <effect> .""" """( a b: array -- c )""" }
-{ $example """USING: effects prettyprint ;
-{ "a" { "b" ( x y -- z ) } } { "c" } <effect> .""" """( a b: ( x y -- z ) -- c )""" }
-{ $example """USING: effects prettyprint ;
-{ "a" { "b" ( x y -- z ) } } { "*" } <effect> .""" """( a b: ( x y -- z ) -- * )""" }
+{ $example "USING: effects prettyprint ;
+{ \"a\" \"b\" } { \"c\" } <effect> ." "( a b -- c )" }
+{ $example "USING: arrays effects prettyprint ;
+{ \"a\" { \"b\" array } } { \"c\" } <effect> ." "( a b: array -- c )" }
+{ $example "USING: effects prettyprint ;
+{ \"a\" { \"b\" ( x y -- z ) } } { \"c\" } <effect> ." "( a b: ( x y -- z ) -- c )" }
+{ $example "USING: effects prettyprint ;
+{ \"a\" { \"b\" ( x y -- z ) } } { \"*\" } <effect> ." "( a b: ( x y -- z ) -- * )" }
} ;
HELP: <terminated-effect>
{ $description "Constructs an " { $link effect } " object like " { $link <effect> } ". If " { $snippet "terminated?" } " is true, the value of " { $snippet "out" } " is ignored, and a terminating stack effect is constructed." }
{ $notes "This word cannot construct effects with " { $link "effects-variables" } ". Use " { $link <variable-effect> } " to construct variable stack effects." }
{ $examples
-{ $example """USING: effects prettyprint ;
-{ "a" { "b" ( x y -- z ) } } { "c" } f <terminated-effect> .""" """( a b: ( x y -- z ) -- c )""" }
-{ $example """USING: effects prettyprint ;
-{ "a" { "b" ( x y -- z ) } } { } t <terminated-effect> .""" """( a b: ( x y -- z ) -- * )""" }
+{ $example "USING: effects prettyprint ;
+{ \"a\" { \"b\" ( x y -- z ) } } { \"c\" } f <terminated-effect> ." "( a b: ( x y -- z ) -- c )" }
+{ $example "USING: effects prettyprint ;
+{ \"a\" { \"b\" ( x y -- z ) } } { } t <terminated-effect> ." "( a b: ( x y -- z ) -- * )" }
} ;
HELP: <variable-effect>
}
{ $description "Constructs an " { $link effect } " object like " { $link <effect> } ". If " { $snippet "in-var" } " or " { $snippet "out-var" } " are not " { $link f } ", they are used as the names of the " { $link "effects-variables" } " for the inputs and outputs of the effect object." }
{ $examples
-{ $example """USING: effects prettyprint ;
-f { "a" "b" } f { "c" } <variable-effect> .""" """( a b -- c )""" }
-{ $example """USING: effects prettyprint ;
-"x" { "a" "b" } "y" { "c" } <variable-effect> .""" """( ..x a b -- ..y c )""" }
-{ $example """USING: arrays effects prettyprint ;
-"y" { "a" { "b" ( ..x -- ..y ) } } "x" { "c" } <variable-effect> .""" """( ..y a b: ( ..x -- ..y ) -- ..x c )""" }
-{ $example """USING: effects prettyprint ;
-"." { "a" "b" } f { "*" } <variable-effect> .""" """( ... a b -- * )""" }
+{ $example "USING: effects prettyprint ;
+f { \"a\" \"b\" } f { \"c\" } <variable-effect> ." "( a b -- c )" }
+{ $example "USING: effects prettyprint ;
+\"x\" { \"a\" \"b\" } \"y\" { \"c\" } <variable-effect> ." "( ..x a b -- ..y c )" }
+{ $example "USING: arrays effects prettyprint ;
+\"y\" { \"a\" { \"b\" ( ..x -- ..y ) } } \"x\" { \"c\" } <variable-effect> ." "( ..y a b: ( ..x -- ..y ) -- ..x c )" }
+{ $example "USING: effects prettyprint ;
+\".\" { \"a\" \"b\" } f { \"*\" } <variable-effect> ." "( ... a b -- * )" }
} ;
ARTICLE: "effects-variables" "Stack effect row variables"
"The stack effect of many " { $link POSTPONE: inline } " combinators can have variable stack effects, depending on the effect of the quotation they call. For example, the quotation parameter to " { $link each } " receives an element from the input sequence each time it is called, but it can also manipulate values on the stack below the element as long as it leaves the same number of elements on the stack. (This is how " { $link reduce } " is implemented in terms of " { $snippet "each" } ".) The stack effect of an " { $snippet "each" } " expression thus depends on the stack effect of its input quotation:"
{ $example
- """USING: io sequences stack-checker ;
-[ [ write ] each ] infer."""
-"""( x -- )""" }
+ "USING: io sequences stack-checker ;
+[ [ write ] each ] infer."
+"( x -- )" }
{ $example
-"""USING: sequences stack-checker ;
-[ [ append ] each ] infer."""
-"""( x x -- x )""" }
+"USING: sequences stack-checker ;
+[ [ append ] each ] infer."
+"( x x -- x )" }
"This feature is referred to as row polymorphism. Row-polymorphic combinators are declared by including row variables in their stack effect, which are indicated by names starting with " { $snippet ".." } ":"
{ $synopsis each }
"Using the same variable name in both the inputs and outputs (in the above case of " { $snippet "each" } ", " { $snippet "..." } ") indicates that the number of additional inputs and outputs must be the same. Using different variable names indicates that they can be independent. In combinators with multiple quotation inputs, the number of inputs or outputs represented by a particular " { $snippet ".." } " name must match among all of the quotations. For example, the branches of " { $link if* } " can take a different number of inputs from outputs, as long as they both have the same stack height. The true branch receives the test value as an added input. This is declared as follows:"
! erg's regression
{ } [
- """IN: generic.standard.tests
+ "IN: generic.standard.tests
GENERIC: jeah ( a -- b )
TUPLE: boii ;
M: boii jeah ;
GENERIC: jeah* ( a -- b )
- M: boii jeah* jeah ;""" eval( -- )
+ M: boii jeah* jeah ;" eval( -- )
- """IN: generic.standard.tests
- FORGET: boii""" eval( -- )
+ "IN: generic.standard.tests
+ FORGET: boii" eval( -- )
- """IN: generic.standard.tests
+ "IN: generic.standard.tests
TUPLE: boii ;
- M: boii jeah ;""" eval( -- )
+ M: boii jeah ;" eval( -- )
] unit-test
! Testing next-method
{ $values { "path1" "a pathname string" } { "path2" "a pathname string" } { "path" "a pathname string" } }
{ $description "Appends " { $snippet "path1" } " and " { $snippet "path2" } " to form a pathname." }
{ $examples
- { $unchecked-example """USING: io.pathnames prettyprint ;
-"first" "second.txt" append-path ."""
+ { $unchecked-example "USING: io.pathnames prettyprint ;
+\"first\" \"second.txt\" append-path ."
"\"first/second.txt\""
}
} ;
{ $values { "path1" "a pathname string" } { "path2" "a pathname string" } { "path" "a pathname string" } }
{ $description "Appends " { $snippet "path2" } " and " { $snippet "path1" } " to form a pathname." }
{ $examples
- { $unchecked-example """USING: io.pathnames prettyprint ;
-"second.txt" "first" prepend-path ."""
+ { $unchecked-example "USING: io.pathnames prettyprint ;
+\"second.txt\" \"first\" prepend-path ."
"\"first/second.txt\""
}
} ;
{ "hello world" }
[
-"""#!/usr/bin/env factor
-"hello world" """ eval( -- string )
+"#!/usr/bin/env factor
+\"hello world\"" eval( -- string )
] unit-test
{ "hello world" }
"Is a letter in a string:"
{ $example
"USING: sequences prettyprint ;"
- """CHAR: a "abc" member? ."""
+ "CHAR: a \"abc\" member? ."
"t"
} $nl
"Is a number in a sequence:"
{ $examples
"Join a list of strings:"
{ $example "USING: sequences prettyprint ;"
- """{ "cat" "dog" "ant" } " " join ."""
- """"cat dog ant""""
+ "{ \"cat\" \"dog\" \"ant\" } \" \" join ."
+ "\"cat dog ant\""
}
}
{ $notes "If the " { $snippet "glue" } " sequence is empty, this word calls " { $link concat-as } "." }
{ $examples
"Join a list of strings as a string buffer:"
{ $example "USING: sequences prettyprint ;"
- """{ "a" "b" "c" } "1" SBUF" "join-as ."""
- """SBUF" a1b1c""""
+ "{ \"a\" \"b\" \"c\" } \"1\" SBUF\" \"join-as ."
+ "SBUF\" a1b1c\""
}
}
{ $errors "Throws an error if one of the sequences in " { $snippet "seq" } " contains elements not permitted in sequences of the same class as " { $snippet "exemplar" } "." } ;
{ "Hello\n\rworld" } [ "Hello\\n\\rworld" unescape-string ] unit-test
{ "Hello\n\rworld" } [ "Hello\n\rworld" ] unit-test
-{ "Hello\n\rworld" } [ """Hello\n\rworld""" ] unit-test
{ "Hello\n\rworld\n" } [ "Hello\n\rworld
" ] unit-test
{ "Hello\n\rworld" "hi" } [ "Hello\n\rworld" "hi" ] unit-test
-{ "Hello\n\rworld" "hi" } [ """Hello\n\rworld""" """hi""" ] unit-test
-{ "Hello\n\rworld\n" "hi" } [ """Hello\n\rworld
-""" """hi""" ] unit-test
-{ "Hello\n\rworld\"" "hi" } [ """Hello\n\rworld\"""" """hi""" ] unit-test
+{ "Hello\n\rworld" "hi" } [ "Hello\n\rworld" "hi" ] unit-test
+{ "Hello\n\rworld\n" "hi" } [ "Hello\n\rworld
+" "hi" ] unit-test
+{ "Hello\n\rworld\"" "hi" } [ "Hello\n\rworld\"" "hi" ] unit-test
[
"\"\"\"Hello\n\rworld\\\n\"\"\"" eval( -- obj )
error>> escaped-char-expected?
] must-fail-with
-{
- " \" abc \" "
-} [
- "\"\"\" \" abc \" \"\"\"" eval( -- string )
-] unit-test
-
{
"\"abc\""
} [
- "\"\"\"\"abc\"\"\"\"" eval( -- string )
+ "\"\\\"abc\\\"\"" eval( -- string )
] unit-test
advance-char drop
] if ;
-DEFER: (parse-multiline-string)
+DEFER: (parse-multiline-string-until)
: parse-found-token ( accum lexer string i token -- )
{ sbuf lexer string fixnum fixnum } declare
CHAR: \ = [
2over next-char swap push
2over next-char swap push
- (parse-multiline-string)
+ (parse-multiline-string-until)
] [
2dup lexer-head? [
end-string-parse
] [
2over next-char swap push
- (parse-multiline-string)
+ (parse-multiline-string-until)
] if
] if ;
ERROR: trailing-characters string ;
-: (parse-multiline-string) ( accum lexer string -- )
+: (parse-multiline-string-until) ( accum lexer string -- )
{ sbuf lexer fixnum } declare
over still-parsing? [
2dup first find-next-token [
parse-found-token
] [
drop 2over next-line%
- (parse-multiline-string)
+ (parse-multiline-string-until)
] if*
] [
throw-unexpected-eof
PRIVATE>
-: parse-multiline-string ( -- string )
- SBUF" " clone [
- lexer get
- dup rest-of-line "\"\"" head? [
- [ 2 + ] change-column
- "\"\"\""
- ] [
- "\""
- ] if (parse-multiline-string)
- ] keep unescape-string ;
+: parse-multiline-string-until ( arg -- string )
+ [ SBUF" " clone ] dip [
+ [ lexer get ] dip (parse-multiline-string-until)
+ ] curry keep unescape-string ;
} ;
HELP: "
-{ $syntax "\"string...\"" "\"\"\"string...\"\"\"" }
+{ $syntax "\"string...\"" }
{ $values { "string" "literal and escaped characters" } }
-{ $description "Reads from the input string until the next occurrence of " { $snippet "\"" } " or " { $snippet "\"\"\"" } ", and appends the resulting string to the parse tree. String literals can span multiple lines. Various special characters can be read by inserting " { $link "escape" } ". For triple quoted strings, the double-quote character does not require escaping." }
+{ $description "Reads from the input string until the next occurrence of " { $snippet "\"" } ", and appends the resulting string to the parse tree. String literals can span multiple lines. Various special characters can be read by inserting " { $link "escape" } "." }
{ $examples
"A string with an escaped newline in it:"
{ $example "USE: io" "\"Hello\\nworld\" print" "Hello\nworld" }
{ $example "USE: io" "\"Hello\nworld\" print" "Hello\nworld" }
"A string with a named Unicode code point:"
{ $example "USE: io" "\"\\u{greek-capital-letter-sigma}\" print" "\u{greek-capital-letter-sigma}" }
- "A triple-quoted string:"
- { $example "USE: io \"\"\"Teach a man to \"fish\"...\nand fish will go extinct\"\"\" print" """Teach a man to \"fish\"...
-and fish will go extinct""" }
} ;
HELP: SBUF"
effects.parser generic generic.hook generic.math generic.parser
generic.standard hash-sets hashtables io.pathnames kernel lexer
math namespaces parser quotations sbufs sequences slots
-source-files splitting strings strings.parser vectors vocabs
-vocabs.parser words words.alias words.constant words.symbol ;
+source-files splitting strings strings.parser
+strings.parser.private vectors vocabs vocabs.parser words
+words.alias words.constant words.symbol ;
IN: bootstrap.syntax
! These words are defined as a top-level form, instead of with
} cond suffix!
] define-core-syntax
- "\"" [ parse-multiline-string suffix! ] define-core-syntax
+ "\"" [ "\"" parse-multiline-string-until suffix! ] define-core-syntax
"SBUF\"" [
lexer get skip-blank parse-string >sbuf suffix!
IN: 99-bottles.tests
{
-"""99 bottles of beer on the wall, 99 bottles of beer.
+"99 bottles of beer on the wall, 99 bottles of beer.
Take one down, pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
-"""
+"
}
[ [ 99-bottles ] with-string-writer ] unit-test
! Hello World!
{ "Hello World!\n" } [
- """
+ "
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.
------.--------.>+.>.
- """ get-brainfuck
+ " get-brainfuck
] unit-test
! Addition (single-digit)
{ "8\0" } [
"24" [
- """
+ "
,>,>++++++++[<------<------>>-]
<<[>[>+>+<<-]>>[<<+>>-]<<<-]
>>>++++++[<++++++++>-],<.>.
- """ get-brainfuck
+ " get-brainfuck
] with-string-reader
] unit-test
{ "3" } [
"62" [
- """
+ "
,>,>++++++[-<--------<-------->>]
<<[
>[->+>+<<]
<<<]
>[-]>>>>[-<<<<<+>>>>>]
<<<<++++++[-<++++++++>]<.
- """ get-brainfuck
+ " get-brainfuck
] with-string-reader
] unit-test
${ 100 [0,b] [ dup * number>string ] map "\n" join "\n" append }
[
- """
+ "
++++[>+++++<-]>[<+++++>-]+<+[
>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+
>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]
<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>
[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
- """ get-brainfuck
+ " get-brainfuck
] unit-test
! fun with numbers: 2 + 2 = 5
{ "5" } [
- """
+ "
+++++ +++++
+ +
+ + + +++++
+ + + +++++
+ +
+++++ +++++.
- """ get-brainfuck
+ " get-brainfuck
] unit-test
{ 18 } [ "Phil" 11 11 <b-monster> stop>> ] unit-test
[
- """USE: constructors
+ "USE: constructors
IN: constructors.tests
TUPLE: foo a b ;
-CONSTRUCTOR: <foo> foo ( a a -- obj )""" eval( -- )
+CONSTRUCTOR: <foo> foo ( a a -- obj )" eval( -- )
] [
error>> repeated-constructor-parameters?
] must-fail-with
[
- """USE: constructors
+ "USE: constructors
IN: constructors.tests
TUPLE: foo a b ;
-CONSTRUCTOR: <foo> foo ( a c -- obj )""" eval( -- )
+CONSTRUCTOR: <foo> foo ( a c -- obj )" eval( -- )
] [
error>> unknown-constructor-parameters?
] must-fail-with
USING: cuda.ptx io.streams.string tools.test ;
IN: cuda.ptx.tests
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20, .texmode_independent
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } { texmode .texmode_independent } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_11, map_f64_to_f32
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_11, map_f64_to_f32, .texmode_independent
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
.global .f32 foo[9000];
.extern .align 16 .shared .v4.f32 bar[];
{
ret;
}
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
{ "a[1]" } [ [ T{ ptx-element f "a" 1 } write-ptx-operand ] with-string-writer ] unit-test
{ "{a, b[2], 3, 0d4000000000000000}" } [ [ T{ ptx-vector f { "a" T{ ptx-element f "b" 2 } 3 2.0 } } write-ptx-operand ] with-string-writer ] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
abs.s32 a, b;
@p abs.s32 a, b;
@!p abs.s32 a, b;
foo: abs.s32 a, b;
abs.ftz.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
add.s32 a, b, c;
add.cc.s32 a, b, c;
add.ftz.sat.f32 a, b, c;
add.rz.sat.f32 a, b, c;
add.rz.ftz.sat.f32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
addc.s32 a, b, c;
addc.cc.s32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
and.b32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
atom.and.u32 a, [b], c;
atom.global.or.u32 a, [b], c;
atom.shared.cas.u32 a, [b], c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
bar.arrive a, b;
bar.red.popc.u32 a, b, d;
bar.red.popc.u32 a, b, c, !d;
bar.sync a;
bar.sync a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
bfe.u32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
bfi.u32 a, b, c, d, e;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
bfind.u32 a, b;
bfind.shiftamt.u32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
bra foo;
bra.uni bar;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
brev.b32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
brkpt;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
call foo;
call.uni foo;
call (a), foo, (b, c, d);
call (a[2]), foo, (b, c, d[3]);
call foo, (b, c, d);
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
clz.b32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
cnot.b32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
copysign.f64 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
cos.approx.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
cvt.f32.s32 a, b;
cvt.s32.f32 a, b;
cvt.sat.f32.f64 a, b;
cvt.ftz.sat.f32.f64 a, b;
cvt.rp.ftz.sat.f32.f64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
cvta.global.u64 a, b;
cvta.shared.u64 a, b;
cvta.to.shared.u64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
div.u32 a, b, c;
div.approx.f32 a, b, c;
div.rz.ftz.f32 a, b, c;
div.f64 a, b, c;
div.rz.f64 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
ex2.approx.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
exit;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
fma.f32 a, b, c, d;
fma.sat.f32 a, b, c, d;
fma.ftz.sat.f32 a, b, c, d;
fma.rz.sat.f32 a, b, c, d;
fma.rz.ftz.sat.f32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
isspacep.shared a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
ld.u32 a, [b];
ld.v2.u32 a, [b];
ld.lu.u32 a, [b];
ld.const.lu.u32 a, [b];
ld.volatile.const[5].u32 a, [b];
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
ldu.u32 a, [b];
ldu.v2.u32 a, [b];
ldu.lu.u32 a, [b];
ldu.const.lu.u32 a, [b];
ldu.volatile.const[5].u32 a, [b];
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
lg2.approx.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
mad.s32 a, b, c, d;
mad.lo.s32 a, b, c, d;
mad.ftz.sat.f32 a, b, c, d;
mad.rz.sat.f32 a, b, c, d;
mad.rz.ftz.sat.f32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
mad24.s32 a, b, c, d;
mad24.lo.s32 a, b, c, d;
mad24.sat.s32 a, b, c, d;
mad24.hi.sat.s32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
neg.s32 a, b;
neg.f32 a, b;
neg.ftz.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
not.b32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
or.b32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
pmevent a;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
popc.b64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
prefetch.L1 [a];
prefetch.local.L2 [a];
prefetchu.L1 [a];
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
prmt.b32 a, b, c, d;
prmt.b32.f4e a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
rcp.approx.f32 a, b;
rcp.approx.ftz.f32 a, b;
rcp.rz.ftz.f32 a, b;
rcp.f64 a, b;
rcp.rz.f64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
red.and.u32 [a], b;
red.global.and.u32 [a], b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
rsqrt.approx.f32 a, b;
rsqrt.approx.ftz.f32 a, b;
rsqrt.approx.f64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
rsqrt.approx.f32 a, b;
rsqrt.approx.ftz.f32 a, b;
rsqrt.approx.f64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
sad.u32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
selp.u32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
set.gt.u32.s32 a, b, c;
set.gt.ftz.u32.f32 a, b, c;
set.gt.and.ftz.u32.f32 a, b, c, d;
set.gt.and.ftz.u32.f32 a, b, c, !d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
setp.gt.s32 a, b, c;
setp.gt.s32 a|z, b, c;
setp.gt.ftz.f32 a, b, c;
setp.gt.and.ftz.f32 a, b, c, d;
setp.gt.and.ftz.f32 a, b, c, !d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
shl.b32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
shr.b32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
sin.approx.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
slct.f32.s32 a, b, c, d;
slct.ftz.f32.s32 a, b, c, d;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
sqrt.approx.f32 a, b;
sqrt.approx.ftz.f32 a, b;
sqrt.rz.ftz.f32 a, b;
sqrt.f64 a, b;
sqrt.rz.f64 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
st.u32 [a], b;
st.v2.u32 [a], b;
st.lu.u32 [a], b;
st.local.lu.u32 [a], b;
st.volatile.local.u32 [a], b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
sub.s32 a, b, c;
sub.cc.s32 a, b, c;
sub.ftz.sat.f32 a, b, c;
sub.rz.sat.f32 a, b, c;
sub.rz.ftz.sat.f32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
subc.s32 a, b, c;
subc.cc.s32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
testp.finite.f32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
trap;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
vote.all.pred a, b;
vote.all.pred a, !b;
vote.ballot.b32 a, b;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
} ptx>string
] unit-test
-{ """ .version 2.0
+{ " .version 2.0
.target sm_20
xor.b32 a, b, c;
-""" } [
+" } [
T{ ptx
{ version "2.0" }
{ target T{ ptx-target { arch sm_20 } } }
{ datatype "AUDIO" }
{ title "Reverence" }
{ performer "Faithless" }
- { indices { T{ index f 1 "00:00:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "00:00:00" }
+ }
+ }
+ }
}
T{ track
{ number 2 }
{ datatype "AUDIO" }
{ title "She's My Baby" }
{ performer "Faithless" }
- { indices { T{ index f 1 "06:42:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "06:42:00" }
+ }
+ }
+ }
}
T{ track
{ number 3 }
{ datatype "AUDIO" }
{ title "Take the Long Way Home" }
{ performer "Faithless" }
- { indices { T{ index f 1 "10:54:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "10:54:00" }
+ }
+ }
+ }
}
T{ track
{ number 4 }
{ datatype "AUDIO" }
{ title "Insomnia" }
{ performer "Faithless" }
- { indices { T{ index f 1 "17:04:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "17:04:00" }
+ }
+ }
+ }
}
T{ track
{ number 5 }
{ datatype "AUDIO" }
{ title "Bring the Family Back" }
{ performer "Faithless" }
- { indices { T{ index f 1 "25:44:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "25:44:00" }
+ }
+ }
+ }
}
T{ track
{ number 6 }
{ datatype "AUDIO" }
{ title "Salva Mea" }
{ performer "Faithless" }
- { indices { T{ index f 1 "30:50:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "30:50:00" }
+ }
+ }
+ }
}
T{ track
{ number 7 }
{ datatype "AUDIO" }
{ title "Dirty Old Man" }
{ performer "Faithless" }
- { indices { T{ index f 1 "38:24:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "38:24:00" }
+ }
+ }
+ }
}
T{ track
{ number 8 }
{ datatype "AUDIO" }
- { title "God Is a DJ" }
+ { title "God\"Is a DJ" }
{ performer "Faithless" }
- { indices { T{ index f 1 "42:35:00" } } }
+ { indices
+ {
+ T{ index
+ { number 1 }
+ { duration "42:35:00" }
+ }
+ }
+ }
}
}
}
{ title "Live in Berlin" }
}
} [
- """
- REM GENRE "Electronica"
- REM DATE "1998"
- PERFORMER "Faithless"
- TITLE "Live in Berlin"
- FILE "Faithless - Live in Berlin.mp3" MP3
+ "
+ REM GENRE \"Electronica\"
+ REM DATE \"1998\"
+ PERFORMER \"Faithless\"
+ TITLE \"Live in Berlin\"
+ FILE \"Faithless - Live in Berlin.mp3\" MP3
TRACK 01 AUDIO
- TITLE "Reverence"
- PERFORMER "Faithless"
+ TITLE \"Reverence\"
+ PERFORMER \"Faithless\"
INDEX 01 00:00:00
TRACK 02 AUDIO
- TITLE "She's My Baby"
- PERFORMER "Faithless"
+ TITLE \"She's My Baby\"
+ PERFORMER \"Faithless\"
INDEX 01 06:42:00
TRACK 03 AUDIO
- TITLE "Take the Long Way Home"
- PERFORMER "Faithless"
+ TITLE \"Take the Long Way Home\"
+ PERFORMER \"Faithless\"
INDEX 01 10:54:00
TRACK 04 AUDIO
- TITLE "Insomnia"
- PERFORMER "Faithless"
+ TITLE \"Insomnia\"
+ PERFORMER \"Faithless\"
INDEX 01 17:04:00
TRACK 05 AUDIO
- TITLE "Bring the Family Back"
- PERFORMER "Faithless"
+ TITLE \"Bring the Family Back\"
+ PERFORMER \"Faithless\"
INDEX 01 25:44:00
TRACK 06 AUDIO
- TITLE "Salva Mea"
- PERFORMER "Faithless"
+ TITLE \"Salva Mea\"
+ PERFORMER \"Faithless\"
INDEX 01 30:50:00
TRACK 07 AUDIO
- TITLE "Dirty Old Man"
- PERFORMER "Faithless"
+ TITLE \"Dirty Old Man\"
+ PERFORMER \"Faithless\"
INDEX 01 38:24:00
TRACK 08 AUDIO
- TITLE "God Is a DJ"
- PERFORMER "Faithless"
+ TITLE \"God\"Is a DJ\"
+ PERFORMER \"Faithless\"
INDEX 01 42:35:00
- """ string>cuesheet
+ " string>cuesheet
] unit-test
{ $description "Constructs a " { $link multi-index-range } " tuple." } ;
HELP: UNIFORM-TUPLE:
-{ $syntax """UNIFORM-TUPLE: class-name
- { "slot" uniform-type dimension }
- { "slot" uniform-type dimension }
+{ $syntax "UNIFORM-TUPLE: class-name
+ { \"slot\" uniform-type dimension }
+ { \"slot\" uniform-type dimension }
...
- { "slot" uniform-type dimension } ;""" }
+ { \"slot\" uniform-type dimension } ;" }
{ $description "Defines a new " { $link uniform-tuple } " class. Tuples of the new class can be used as the " { $snippet "uniforms" } " slot of a " { $link render-set } " in order to set the uniform parameters of the active shader program. The " { $link uniform-type } " of each slot defines the component type, and the " { $snippet "dimension" } " specifies an array length if not " { $link f } "."
$nl
"Uniform parameters are passed from Factor to the shader program through the uniform tuple as follows:"
{ $description "Defines a new " { $link shader } " of kind " { $link shader-kind } " named " { $snippet "shader-name" } ". The shader will read its source code from " { $snippet "filename" } " in the current Factor source file's directory." } ;
HELP: GLSL-SHADER:
-{ $syntax """GLSL-SHADER: shader-name shader-kind
+{ $syntax "GLSL-SHADER: shader-name shader-kind
shader source
-;""" }
+;" }
{ $description "Defines a new " { $link shader } " of kind " { $link shader-kind } " named " { $snippet "shader-name" } ". The shader will read its source code from the current Factor source file between the " { $snippet "GLSL-SHADER:" } " line and the first subsequent line with a single semicolon on it." } ;
HELP: VERTEX-FORMAT:
-{ $syntax """VERTEX-FORMAT: format-name
- { "attribute"/f component-type dimension normalize? }
- { "attribute"/f component-type dimension normalize? }
+{ $syntax "VERTEX-FORMAT: format-name
+ { \"attribute\"/f component-type dimension normalize? }
+ { \"attribute\"/f component-type dimension normalize? }
...
- { "attribute"/f component-type dimension normalize? } ;""" }
+ { \"attribute\"/f component-type dimension normalize? } ;" }
{ $description "Defines a new binary " { $link vertex-format } " for structuring vertex data stored in " { $link buffer } "s. Each " { $snippet "attribute" } " name either corresponds to an input parameter of a vertex shader, or is " { $link f } " to include padding in the vertex format. The " { $link component-type } " determines the format of the components, and the " { $snippet "dimension" } " determines the number of components. If the " { $snippet "component-type" } " is an integer type and " { $snippet "normalize?" } " is true, the component values will be scaled to the range 0.0 to 1.0 when fed to the vertex shader; otherwise, they will be cast to floats retaining their integral values." } ;
HELP: VERTEX-STRUCT:
-{ $syntax """VERTEX-STRUCT: struct-name format-name""" }
+{ $syntax "VERTEX-STRUCT: struct-name format-name" }
{ $description "Defines a struct class (like " { $link POSTPONE: STRUCT: } ") with the same binary format and component types as the given " { $link vertex-format } "." } ;
{ POSTPONE: GLSL-PROGRAM: POSTPONE: GLSL-SHADER-FILE: POSTPONE: GLSL-SHADER: } related-words
USING: multiline gpu.shaders gpu.shaders.private tools.test ;
IN: gpu.shaders.tests
-{ """ERROR: foo.factor:20: Bad command or filename
+{ "ERROR: foo.factor:20: Bad command or filename
INFO: foo.factor:30: The operation completed successfully
-NOT:A:LOG:LINE""" }
+NOT:A:LOG:LINE" }
[ T{ shader { filename "foo.factor" } { line 19 } }
-"""ERROR: 0:1: Bad command or filename
+"ERROR: 0:1: Bad command or filename
INFO: 0:11: The operation completed successfully
-NOT:A:LOG:LINE""" replace-log-line-numbers ] unit-test
+NOT:A:LOG:LINE" replace-log-line-numbers ] unit-test
{ { $link func-one-minus-constant-alpha } " returns one minus the alpha component of the current " { $link blend-state } "'s " { $snippet "constant-color" } " for every result component." }
}
"A typical transparency effect will use the values:"
-{ $code """T{ blend-mode
+{ $code "T{ blend-mode
{ equation eq-add }
{ source-function func-source-alpha }
{ dest-function func-one-minus-source-alpha }
-}""" }
+}" }
} } ;
HELP: blend-state
{ "quatint;" "\u002a16" }
{ "quest;" "?" }
{ "questeq;" "\u00225f" }
- { "QUOT" """ }
- { "quot" """ }
- { "QUOT;" """ }
- { "quot;" """ }
+ { "QUOT" " } { \"quot\" " }
+ { "QUOT;" " } { \"quot;\" " }
{ "rAarr;" "\u0021db" }
{ "race;" "\u00223d\u000331" }
{ "Racute;" "\u000154" }
{ $examples
{ $code
"USING: imap ; "
- """"imap.gmail.com" "email_address@gmail.com" "password" [ list-folders ] with-imap"""
+ "\"imap.gmail.com\" \"email_address@gmail.com\" \"password\" [ list-folders ] with-imap"
}
{ $unchecked-example
- """USING: imap namespaces ;
+ "USING: imap namespaces ;
\\ imap-settings get-global [
- "factor" select-folder drop
- "ALL" "" search-mails
- "(BODY[HEADER.FIELDS (SUBJECT)])" fetch-mails
- ] with-imap-settings 3 head ."""
- """{
- "Subject: [Factor-talk] Wiki Tutorial"
- "Subject: Re: [Factor-talk] font-size in listener"
- "Subject: Re: [Factor-talk] Indentation width and other style guidelines"
-}"""
+ \"factor\" select-folder drop
+ \"ALL\" \"\" search-mails
+ \"(BODY[HEADER.FIELDS (SUBJECT)])\" fetch-mails
+ ] with-imap-settings 3 head ."
+ "{
+ \"Subject: [Factor-talk] Wiki Tutorial\"
+ \"Subject: Re: [Factor-talk] font-size in listener\"
+ \"Subject: Re: [Factor-talk] Indentation width and other style guidelines\"
+}"
}
} ;
{ $description "Requests a collection of attributes for the specified folder." }
{ $examples
{ $unchecked-example
- """USING: imap ;
+ "USING: imap ;
\\ imap-settings get-global [
- "INBOX" { "MESSAGES" "UNSEEN" } status-folder
- ] with-imap-settings"""
- """{ { "MESSAGES" 67 } { "UNSEEN" 18 } }"""
+ \"INBOX\" { \"MESSAGES\" \"UNSEEN\" } status-folder
+ ] with-imap-settings"
+ "{ { \"MESSAGES\" 67 } { \"UNSEEN\" 18 } }"
}
} ;
"Add the following settings to your bootstrap rc file:"
{ $unchecked-example
"USING: imap namespaces ;"
- """"imap.gmail.com" "foo@gmail.com" "password" <imap-settings> \\ imap-settings set-global"""
+ "\"imap.gmail.com\" \"foo@gmail.com\" \"password\" <imap-settings> \\ imap-settings set-global"
""
}
"Run your boot rc again:"
{ H{ { "section" H{ { "foo" "abc def" } } } } }
[
- """
+ "
[section]
foo = abc def
- """ string>ini
+ " string>ini
] unit-test
{ H{ { "section" H{ { "foo" "abc def" } } } } }
[
- """
+ "
[section]
foo = abc \\
- "def"
- """ string>ini
+ \"def\"
+ " string>ini
] unit-test
{ H{ { "section" H{ { "foo" "abc def" } } } } }
[
- """
+ "
[section]
- foo = "abc " \\
+ foo = \"abc \" \\
def
- """ string>ini
+ " string>ini
] unit-test
{ H{ { "section" H{ { "foo" "abc def" } } } } }
[
- """
- [section] foo = "abc def"
- """ string>ini
+ "
+ [section] foo = \"abc def\"
+ " string>ini
] unit-test
{ H{ { "section" H{ { "foo" "abc def" } } } } }
[
- """
+ "
[section] foo = abc \\
- "def"
- """ string>ini
+ \"def\"
+ " string>ini
] unit-test
{ H{ { "section" H{ { "foo" "" } } } } }
[
- """
+ "
[section]
foo=
- """ string>ini
+ " string>ini
] unit-test
{ H{ { "section" H{ { "foo" "" } } } } }
[
- """
+ "
[section]
foo
- """ string>ini
+ " string>ini
] unit-test
{ H{ { "" H{ { "" "" } } } } }
[
- """
+ "
[]
=
- """ string>ini
+ " string>ini
] unit-test
{ H{ { "owner" H{ { "name" "John Doe" }
{ "port" "143" }
{ "file" "payroll.dat" } } } } }
[
- """
+ "
; last modified 1 April 2001 by John Doe
[owner]
name=John Doe
[database]
server=192.0.2.62 ; use IP address in case network name resolution is not working
port=143
- file = "payroll.dat"
- """ string>ini
+ file = \"payroll.dat\"
+ " string>ini
] unit-test
{ H{ { "a long section name"
H{ { "a long key name" "a long value name" } } } } }
[
- """
+ "
[a long section name ]
a long key name= a long value name
- """ string>ini
+ " string>ini
] unit-test
{ H{ { "key with \n esc\ape \r codes \""
"value with \t esc\ape codes" } } }
[
- """
+ "
key with \\n esc\\ape \\r codes \\\" = value with \\t esc\\ape codes
- """ string>ini
+ " string>ini
] unit-test
-{ """key with \\n esc\\ape \\r codes \\\"=value with \\t esc\\ape codes\n""" }
+{ "key with \\n esc\\ape \\r codes \\\"=value with \\t esc\\ape codes\n" }
[
H{ { "key with \n esc\ape \r codes \""
"value with \t esc\ape codes" } } ini>string
! XML prolog
{ utf8 }
-[ """<?xml version="1.0"?>""" >byte-array detect-byte-array ]
+[ "<?xml version=\"1.0\"?>" >byte-array detect-byte-array ]
unit-test
{ utf8 }
-[ """<?xml version="1.0" encoding="UTF-8"?>""" >byte-array detect-byte-array ]
+[ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" >byte-array detect-byte-array ]
unit-test
{ latin1 }
-[ """<?xml version='1.0' encoding='ISO-8859-1'?>""" >byte-array detect-byte-array ]
+[ "<?xml version='1.0' encoding='ISO-8859-1'?>" >byte-array detect-byte-array ]
unit-test
{ latin1 }
-[ """<?xml version='1.0' encoding="ISO-8859-1" """ >byte-array detect-byte-array ]
+[ "<?xml version='1.0' encoding=\"ISO-8859-1\" " >byte-array detect-byte-array ]
unit-test
! Default to utf8 if decoding succeeds and there are no nulls
docs key chat-docs get set-at ;
[ handle-help ]
-"""Syntax: /help [command]
-Displays the documentation for a command."""
+"Syntax: /help [command]
+Displays the documentation for a command."
"help" add-command
[ drop clients keys [ "``" "''" surround ] map ", " join send-line ]
-"""Syntax: /who
-Shows the list of connected users."""
+"Syntax: /who
+Shows the list of connected users."
"who" add-command
[ drop gmt timestamp>rfc822 send-line ]
-"""Syntax: /time
-Returns the current GMT time.""" "time" add-command
+"Syntax: /time
+Returns the current GMT time." "time" add-command
[ handle-nick ]
-"""Syntax: /nick nickname
-Changes your nickname."""
+"Syntax: /nick nickname
+Changes your nickname."
"nick" add-command
[ handle-me ]
-"""Syntax: /me action"""
+"Syntax: /me action"
"me" add-command
[ handle-quit ]
-"""Syntax: /quit [message]
-Disconnects a user from the chat server.""" "quit" add-command
+"Syntax: /quit [message]
+Disconnects a user from the chat server." "quit" add-command
: handle-command ( string -- )
dup " " split1 swap >lower commands get at* [
deploy-blas?
}
"The interface attempts to set default values based on the ones encountered on the Factor project's build machines. If these settings don't work with your system's BLAS, or you wish to use a commercial BLAS, you may change the global values of those variables in your " { $link ".factor-rc" } ". For example, to use AMD's ACML library on Windows with " { $snippet "math.blas" } ", your " { $snippet ".factor-rc" } " would look like this:"
-{ $code """
+{ $code "
USING: math.blas.config namespaces ;
-"X:\\path\\to\\acml.dll" blas-library set-global
+\"X:\\path\\to\\acml.dll\" blas-library set-global
intel-windows-abi blas-fortran-abi set-global
t deploy-blas? set-global
-""" }
+" }
"To take effect, the " { $snippet "blas-library" } " and " { $snippet "blas-fortran-abi" } " variables must be set before any other " { $snippet "math.blas" } " vocabularies are loaded."
;
{ $description "Return a vector of zeros with the given " { $snippet "length" } " and the same element type as " { $snippet "v" } "." } ;
HELP: smatrix{
-{ $syntax """smatrix{
+{ $syntax "smatrix{
{ 1.0 0.0 0.0 1.0 }
{ 0.0 1.0 0.0 2.0 }
{ 0.0 0.0 1.0 3.0 }
{ 0.0 0.0 0.0 1.0 }
-}""" }
+}" }
{ $description "Construct a literal " { $link float-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
HELP: dmatrix{
-{ $syntax """dmatrix{
+{ $syntax "dmatrix{
{ 1.0 0.0 0.0 1.0 }
{ 0.0 1.0 0.0 2.0 }
{ 0.0 0.0 1.0 3.0 }
{ 0.0 0.0 0.0 1.0 }
-}""" }
+}" }
{ $description "Construct a literal " { $link double-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
HELP: cmatrix{
-{ $syntax """cmatrix{
+{ $syntax "cmatrix{
{ 1.0 0.0 0.0 1.0 }
{ 0.0 C{ 0.0 1.0 } 0.0 2.0 }
{ 0.0 0.0 -1.0 3.0 }
{ 0.0 0.0 0.0 C{ 0.0 -1.0 } }
-}""" }
+}" }
{ $description "Construct a literal " { $link complex-float-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
HELP: zmatrix{
-{ $syntax """zmatrix{
+{ $syntax "zmatrix{
{ 1.0 0.0 0.0 1.0 }
{ 0.0 C{ 0.0 1.0 } 0.0 2.0 }
{ 0.0 0.0 -1.0 3.0 }
{ 0.0 0.0 0.0 C{ 0.0 -1.0 } }
-}""" }
+}" }
{ $description "Construct a literal " { $link complex-double-blas-matrix } ". Note that although BLAS matrices are stored in column-major order, the literal is specified in row-major order." } ;
{
{ $slide "Locals example"
"Area of a triangle using Heron's formula"
{ $code
- """:: area ( a b c -- x )
+ ":: area ( a b c -- x )
a b c + + 2 / :> p
p
p a - *
p b - *
- p c - * sqrt ;"""
+ p c - * sqrt ;"
}
}
{ $slide "Previous example without locals"
"A bit unwieldy..."
{ $code
- """: area ( a b c -- x )
+ ": area ( a b c -- x )
[ ] [ + + 2 / ] 3bi
[ '[ _ - ] tri@ ] [ neg ] bi
- * * * sqrt ;""" }
+ * * * sqrt ;" }
}
{ $slide "More idiomatic version"
"But there's a trick: put the points in an array"
- { $code """: v-n ( v n -- w ) '[ _ - ] map ;
+ { $code ": v-n ( v n -- w ) '[ _ - ] map ;
: area ( points -- x )
[ 0 suffix ] [ sum 2 / ] bi
- v-n product sqrt ;""" }
+ v-n product sqrt ;" }
}
! { $slide "The parser"
! "All data types have a literal syntax"
}
{ $slide "This is hard with mainstream syntax!"
{ $code
- """var customer = ...;
+ "var customer = ...;
var orders = (customer == null ? null : customer.orders);
var order = (orders == null ? null : orders[0]);
-var price = (order == null ? null : order.price);""" }
+var price = (order == null ? null : order.price);" }
}
{ $slide "An ad-hoc solution"
"Something like..."
}
{ $slide "UI example"
{ $code
- """<pile>
+ "<pile>
{ 5 5 } >>gap
1 >>fill
- "Hello world!" <label> add-gadget
- "Click me!" [ drop beep ]
+ \"Hello world!\" <label> add-gadget
+ \"Click me!\" [ drop beep ]
<bevel-button> add-gadget
<editor> <scroller> add-gadget
-"UI test" open-window""" }
+\"UI test\" open-window" }
}
{ $slide "Help system"
"Help markup is just literal data"
] unit-test
{ t } [
-"""
+"
var x=5
var y=10
-""" main \ javascript rule (parse) remaining>> length zero?
+" main \ javascript rule (parse) remaining>> length zero?
] unit-test
{ t } [
-"""
+"
function foldl(f, initial, seq) {
for(var i=0; i< seq.length; ++i)
initial = f(initial, seq[i]);
return initial;
-}""" main \ javascript rule (parse) remaining>> length zero?
+}" main \ javascript rule (parse) remaining>> length zero?
] unit-test
{ t } [
-"""
+"
ParseState.prototype.from = function(index) {
var r = new ParseState(this.input, this.index + index);
r.cache = this.cache;
r.length = this.length - index;
return r;
-}""" main \ javascript rule (parse) remaining>> length zero?
+}" main \ javascript rule (parse) remaining>> length zero?
] unit-test
] unit-test
{ t } [
-"""VAR x, squ;
+"VAR x, squ;
PROCEDURE square;
BEGIN
CALL square;
x := x + 1;
END
-END.""" main \ pl0 rule (parse) remaining>> empty?
+END." main \ pl0 rule (parse) remaining>> empty?
] unit-test
{ f } [
-"""
+"
CONST
m = 7,
n = 85;
y := 36;
CALL gcd;
END.
-""" main \ pl0 rule (parse) remaining>> empty?
+" main \ pl0 rule (parse) remaining>> empty?
] unit-test
{ $examples
{ $example "USING: kernel poker prettyprint ;"
"HAND{ AS KD JC KH 2D 2S KC } best-holdem-hand drop value>hand-name ."
- """"Full House""""
+ "\"Full House\""
}
} ;
{ $examples
{ $code
"consolidate ."
-"""{
+"{
T{ message
{ # 1 }
{ uidl \"000000d547ac2fc2\" }
{ subject \"Second subject\" }
{ size \"747\" }
}
-}"""
+}"
""
}
}
{
[ dup "TOP 1 0" = ]
[
-"""+OK
+"+OK
Return-Path: <from.first@mail.com>
Delivered-To: username@host.com
Received: from User.local ([66.249.71.201])
Content-Type: text/plain; charset=UTF-8
.
-"""
+"
write flush t
]
}
{
[ dup "TOP 2 0" = ]
[
-"""+OK
+"+OK
Return-Path: <from.second@mail.com>
Delivered-To: username@host.com
Received: from User.local ([66.249.71.201])
Content-Type: text/plain; charset=UTF-8
.
-"""
+"
write flush t
]
}
{
[ dup "RETR 1" = ]
[
-"""+OK
+"+OK
Return-Path: <from.first@mail.com>
Delivered-To: username@host.com
Received: from User.local ([66.249.71.201])
This is the body of the first test.
.
-"""
+"
write flush t
]
}
{
[ dup "RETR 2" = ]
[
-"""+OK
+"+OK
Return-Path: <from.second@mail.com>
Delivered-To: username@host.com
Received: from User.local ([66.249.71.201])
This is the body of the second test.
.
-"""
+"
write flush t
]
}
{ $description "Opens a file for reading, displays a progress bar, and calls the quotation for processing the file. The progress bar will automtically update every 100 milliseconds, but only if the quotation yields (by calling " { $link yield } ") so that the UI has a chance to redraw." }
{ $examples
"Loop through the Factor image file, discarding each character as it's read and updating a progress bar:"
- { $unchecked-example """USING: system progress-bars.models prettyprint io.encodings.binary threads ;
+ { $unchecked-example "USING: system progress-bars.models prettyprint io.encodings.binary threads ;
image binary [
[ 4096 read yield ] loop
-] with-file-reader-progress"""
+] with-file-reader-progress"
""
}
} ;
{ $syntax "qw{ lorem ipsum }" }
{ $description "Marks the beginning of a literal array of strings. Component strings are delimited by whitespace." }
{ $examples
-{ $unchecked-example """USING: prettyprint qw ;
-qw{ pop quiz my hive of big wild ex tranny jocks } ."""
-"""{ "pop" "quiz" "my" "hive" "of" "big" "wild" "ex" "tranny" "jocks" }""" }
+{ $unchecked-example "USING: prettyprint qw ;
+qw{ pop quiz my hive of big wild ex tranny jocks } ."
+"{ \"pop\" \"quiz\" \"my\" \"hive\" \"of\" \"big\" \"wild\" \"ex\" \"tranny\" \"jocks\" }" }
} ;
ARTICLE: "qw" "Quoted words"
IN: roles
HELP: ROLE:
-{ $syntax """ROLE: name slots... ;
+{ $syntax "ROLE: name slots... ;
ROLE: name < role slots... ;
-ROLE: name <{ roles... } slots... ;""" }
+ROLE: name <{ roles... } slots... ;" }
{ $description "Defines a new " { $link role } ". " { $link tuple } " classes which inherit this role will contain the specified " { $snippet "slots" } " as well as the slots associated with the optional inherited " { $snippet "roles" } "."
$nl
"Slot specifiers take one of the following three forms:"
"Slot attributes are lists of slot attribute specifiers followed by values; a slot attribute specifier is one of " { $link initial: } " or " { $link read-only } ". See " { $link "tuple-declarations" } " for details." } ;
HELP: ROLE-TUPLE:
-{ $syntax """ROLE-TUPLE: name slots ;
+{ $syntax "ROLE-TUPLE: name slots ;
ROLE-TUPLE: name < estate slots ;
-ROLE-TUPLE: name <{ estates... } slots... ;""" }
+ROLE-TUPLE: name <{ estates... } slots... ;" }
{ $description "Defines a new " { $link tuple } " class."
$nl
"The list of inherited " { $snippet "estates" } " is optional; a single tuple superclass and/or a set of " { $link role } "s can be specified. If no superclass is provided, it defaults to " { $link tuple } "."
{ "subseq" sequence } { "seq" sequence } { "indices" sequence } }
{ $description "Outputs the starting indices of the non-overlapping occurences of " { $snippet "subseq" } " in " { $snippet "seq" } "." }
{ $examples
- { $example """USING: prettyprint sequences.extras ; "ABA" "ABABA" start-all ."""
+ { $example "USING: prettyprint sequences.extras ; \"ABA\" \"ABABA\" start-all ."
"{ 0 }"
}
- { $example """USING: prettyprint sequences.extras ; "ABA" "ABAABA" start-all ."""
+ { $example "USING: prettyprint sequences.extras ; \"ABA\" \"ABAABA\" start-all ."
"{ 0 3 }"
}
} ;
{ "subseq" sequence } { "seq" sequence } { "indices" sequence } }
{ $description "Outputs the starting indices of the possibly overlapping occurences of " { $snippet "subseq" } " in " { $snippet "seq" } "." }
{ $examples
- { $example """USING: prettyprint sequences.extras ; "ABA" "ABABA" start-all* ."""
+ { $example "USING: prettyprint sequences.extras ; \"ABA\" \"ABABA\" start-all* ."
"{ 0 2 }"
} } ;
{ "subseq" sequence } { "seq" sequence } { "n" integer } }
{ $description "Outputs the number of non-overlapping occurences of " { $snippet "subseq" } " in " { $snippet "seq" } "." }
{ $examples
- { $example """USING: prettyprint sequences.extras ; "ABA" "ABABA" count-subseq ."""
+ { $example "USING: prettyprint sequences.extras ; \"ABA\" \"ABABA\" count-subseq ."
"1"
} } ;
{ "subseq" sequence } { "seq" sequence } { "n" integer } }
{ $description "Outputs the number of possibly overlapping occurences of " { $snippet "subseq" } " in " { $snippet "seq" } "." }
{ $examples
- { $example """USING: prettyprint sequences.extras ; "ABA" "ABABA" count-subseq* ."""
+ { $example "USING: prettyprint sequences.extras ; \"ABA\" \"ABABA\" count-subseq* ."
"2"
} } ;
{ $values { "seq" sequence } { "base" integer } { "n-based-assoc" n-based-assoc } }
{ $description "Wraps " { $snippet "seq" } " in an " { $link n-based-assoc } " wrapper." }
{ $examples
-{ $example """
+{ $example "
USING: assocs prettyprint kernel sequences.n-based ;
IN: scratchpad
: months ( -- assoc )
{
- "January"
- "February"
- "March"
- "April"
- "May"
- "June"
- "July"
- "August"
- "September"
- "October"
- "November"
- "December"
+ \"January\"
+ \"February\"
+ \"March\"
+ \"April\"
+ \"May\"
+ \"June\"
+ \"July\"
+ \"August\"
+ \"September\"
+ \"October\"
+ \"November\"
+ \"December\"
} 1 <n-based-assoc> ;
10 months at .
-""" "\"October\"" } } ;
+" "\"October\"" } } ;
HELP: n-based-assoc
{ $class-description "An adaptor class that allows a sequence to be treated as an assoc with non-zero-based keys." }
{ $examples
-{ $example """
+{ $example "
USING: assocs prettyprint kernel sequences.n-based ;
IN: scratchpad
: months ( -- assoc )
{
- "January"
- "February"
- "March"
- "April"
- "May"
- "June"
- "July"
- "August"
- "September"
- "October"
- "November"
- "December"
+ \"January\"
+ \"February\"
+ \"March\"
+ \"April\"
+ \"May\"
+ \"June\"
+ \"July\"
+ \"August\"
+ \"September\"
+ \"October\"
+ \"November\"
+ \"December\"
} 1 <n-based-assoc> ;
10 months at .
-""" "\"October\"" } } ;
+" "\"October\"" } } ;
{ n-based-assoc <n-based-assoc> } related-words
"IN: slots.syntax.example"
"TUPLE: rectangle width height ;"
"T{ rectangle { width 3 } { height 5 } } slots[ width height ] [ . ] bi@"
- """3
-5"""
+ "3
+5"
} ;
HELP: slots{
ARTICLE: "spider-tutorial" "Spider tutorial"
"To create a new spider, call the " { $link <spider> } " word with a link to the site you wish to spider."
-{ $code """"http://concatenative.org" <spider>""" }
+{ $code "\"http://concatenative.org\" <spider>" }
"The max-depth is initialized to 0, which retrieves just the initial page. Let's initialize it to something more fun:"
-{ $code """1 >>max-depth""" }
+{ $code "1 >>max-depth" }
"Now the spider will retrieve the first page and all the pages it links to in the same domain." $nl
"But suppose the front page contains thousands of links. To avoid grabbing them all, we can set " { $slot "max-count" } " to a reasonable limit."
-{ $code """10 >>max-count""" }
+{ $code "10 >>max-count" }
"A timeout might keep the spider from hitting the server too hard:"
-{ $code """USE: calendar 1.5 seconds >>sleep""" }
+{ $code "USE: calendar 1.5 seconds >>sleep" }
"Since we happen to know that not all pages of a wiki are suitable for spidering, we will spider only the wiki view pages, not the edit or revisions pages. To do this, we add a filter through which new links are tested; links that pass the filter are added to the todo queue, while links that do not are discarded. You can add several filters to the filter array, but we'll just add a single one for now."
-{ $code """{ [ path>> "/wiki/view" head? ] } >>filters""" }
+{ $code "{ [ path>> \"/wiki/view\" head? ] } >>filters" }
"Finally, to start the spider, call the " { $link run-spider } " word."
{ $code "run-spider" }
"The full code from the tutorial."
-{ $code """USING: spider calendar sequences accessors ;
+{ $code "USING: spider calendar sequences accessors ;
: spider-concatenative ( -- spider )
- "http://concatenative.org" <spider>
+ \"http://concatenative.org\" <spider>
1 >>max-depth
10 >>max-count
1.5 seconds >>sleep
- { [ path>> "/wiki/view" head? ] } >>filters
- run-spider ;""" } ;
+ { [ path>> \"/wiki/view\" head? ] } >>filters
+ run-spider ;" } ;
ARTICLE: "spider" "Spider"
"The " { $vocab-link "spider" } " vocabulary implements a simple web spider for retrieving sets of webpages."
}
}
} [
-"""1
+"1
00:00:10,500 --> 00:00:13,000
Elephant's Dream
2
00:00:15,000 --> 00:00:18,000
-At the left we can see..."""
+At the left we can see..."
parse-srt-string
] unit-test
}
}
} [
-"""1
+"1
00:00:10,500 --> 00:00:13,000 X1:63 X2:223 Y1:43 Y2:58
<i>Elephant's Dream</i>
2
00:00:15,000 --> 00:00:18,000 X1:53 X2:303 Y1:438 Y2:453
-<font color="cyan">At the left we can see...</font>"""
+<font color=\"cyan\">At the left we can see...</font>"
parse-srt-string
] unit-test
T{ elliptical-arc f { 5.0 6.0 } 7.0 t f { 8.0 9.0 } f }
} } [
- """
+ "
M 1.0,+1 3,-10e-1 l 2 2, 2 -2, 2 2 v -9 1 H 9 8 z
M 0 0 C -4.0 0.0 -8.0 4.0 -8.0 8.0 -8.0 4.0 -12.0 8.0 -16.0 8.0
s 0.0,2.0 2.0,0.0
Q -2 0 0 -2 -3. 0 0 3
t 1 2 3 4
A 5 6 7 1 0 8 9
- """ svg-path>array
+ " svg-path>array
] unit-test
STRING: test-svg-string
{ $slide "First, some examples"
{ $code "3 weeks ago noon monday ." }
{ $code "USE: roman 2009 >roman ." }
- { $code """: average ( seq -- x )
- [ sum ] [ length ] bi / ;""" }
+ { $code ": average ( seq -- x )
+ [ sum ] [ length ] bi / ;" }
{ $code "1 miles [ km ] undo >float ." }
{ $code "[ readln eval>string print t ] loop" }
}
{ $slide "XML Literals"
{ $code
- """USING: splitting xml.writer xml.syntax ;
-{ "one" "two" "three" }
+ "USING: splitting xml.writer xml.syntax ;
+{ \"one\" \"two\" \"three\" }
[ [XML <item><-></item> XML] ] map
-<XML <doc><-></doc> XML> pprint-xml"""
+<XML <doc><-></doc> XML> pprint-xml"
}
}
{ $slide "Differences between Factor and Lisp"
}
{ $slide "Object system example: shape protocol"
"In ~/factor/work/shapes/shapes.factor"
- { $code """IN: shapes
+ { $code "IN: shapes
GENERIC: area ( shape -- x )
-GENERIC: perimeter ( shape -- x )"""
+GENERIC: perimeter ( shape -- x )"
}
}
{ $slide "Implementing the shape protocol: circles"
"In ~/factor/work/shapes/circle/circle.factor"
- { $code """USING: shapes constructors math
+ { $code "USING: shapes constructors math
math.constants ;
IN: shapes.circle
TUPLE: circle radius ;
CONSTRUCTOR: <circle> circle ( radius -- obj ) ;
M: circle area radius>> sq pi * ;
-M: circle perimeter radius>> pi * 2 * ;"""
+M: circle perimeter radius>> pi * 2 * ;"
}
}
{ $slide "Dynamic variables"
"Implemented as a stack of hashtables"
{ "Useful words are " { $link get } ", " { $link set } }
"Input, output, error streams are stored in dynamic variables"
- { $code """"Today is the first day of the rest of your life."
+ { $code "\"Today is the first day of the rest of your life.\"
[
readln print
-] with-string-reader"""
+] with-string-reader"
}
}
{ $slide "The global namespace"
"The global namespace is just the namespace at the bottom of the namespace stack"
{ "Useful words are " { $link get-global } ", " { $link set-global } }
"Factor idiom for changing a particular namespace"
- { $code """SYMBOL: king
-global [ "Henry VIII" king set ] with-variables"""
+ { $code "SYMBOL: king
+global [ \"Henry VIII\" king set ] with-variables"
}
{ $code "with-scope" }
{ $code "namestack" }
}
{ $slide "Hooks"
"Dispatch on a dynamic variable"
- { $code """HOOK: computer-name os ( -- string )
+ { $code "HOOK: computer-name os ( -- string )
M: macosx computer-name uname first ;
macosx \ os set-global
-computer-name"""
+computer-name"
}
}
{ $slide "Interpolate"
"Replaces variables in a string"
{ $code
-""""Dawg" "name" set
-"rims" "noun" set
-"bling" "verb1" set
-"roll" "verb2" set
+"\"Dawg\" \"name\" set
+\"rims\" \"noun\" set
+\"bling\" \"verb1\" set
+\"roll\" \"verb2\" set
[
- "Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your car so you can ${verb1} while you ${verb2}."
+ \"Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your car so you can ${verb1} while you ${verb2}.\"
interpolate
-] with-string-writer print """
+] with-string-writer print "
}
}
{ $slide "Sequence protocol"
{ $slide "Specialized arrays code"
"One line per array/vector"
{ "In ~/factor/basis/specialized-arrays/float/float.factor"
- { $code """<< "float" define-array >>""" }
+ { $code "<< \"float\" define-array >>" }
}
{ "In ~/factor/basis/specialized-vectors/float/float.factor"
- { $code """<< "float" define-vector >>""" }
+ { $code "<< \"float\" define-vector >>" }
}
}
}
{ $slide "Functor for sorting"
{ $code
- """FUNCTOR: define-sorting ( NAME QUOT -- )
+ "FUNCTOR: define-sorting ( NAME QUOT -- )
NAME<=> DEFINES ${NAME}<=>
NAME>=< DEFINES ${NAME}>=<
: NAME>=< ( obj1 obj2 -- >=< )
NAME<=> invert-comparison ;
-;FUNCTOR"""
+;FUNCTOR"
}
}
{ $slide "Example of sorting functor"
- { $code """USING: sorting.functor ;
-<< "length" [ length ] define-sorting >>"""
+ { $code "USING: sorting.functor ;
+<< \"length\" [ length ] define-sorting >>"
}
{ $code
- """{ { 1 2 3 } { 1 2 } { 1 } }
-[ length<=> ] sort"""
+ "{ { 1 2 3 } { 1 2 } { 1 } }
+[ length<=> ] sort"
}
}
{ $slide "Combinators"
}
{ $slide "Control flow: if"
{ $link if }
- { $code """10 random dup even? [ 2 / ] [ 1 - ] if""" }
+ { $code "10 random dup even? [ 2 / ] [ 1 - ] if" }
{ $link when }
- { $code """10 random dup even? [ 2 / ] when""" }
+ { $code "10 random dup even? [ 2 / ] when" }
{ $link unless }
- { $code """10 random dup even? [ 1 - ] unless""" }
+ { $code "10 random dup even? [ 1 - ] unless" }
}
{ $slide "Control flow: case"
{ $link case }
- { $code """ERROR: not-possible obj ;
+ { $code "ERROR: not-possible obj ;
10 random 5 <=> {
- { +lt+ [ "Less" ] }
- { +gt+ [ "More" ] }
- { +eq+ [ "Equal" ] }
+ { +lt+ [ \"Less\" ] }
+ { +gt+ [ \"More\" ] }
+ { +eq+ [ \"Equal\" ] }
[ not-possible ]
-} case"""
+} case"
}
}
{ $slide "Fry"
{ $slide "Locals example"
"Area of a triangle using Heron's formula"
{ $code
- """:: area ( a b c -- x )
+ ":: area ( a b c -- x )
a b c + + 2 / :> p
p
p a - *
p b - *
- p c - * sqrt ;"""
+ p c - * sqrt ;"
}
}
{ $slide "Previous example without locals"
"A bit unwieldy..."
{ $code
- """: area ( a b c -- x )
+ ": area ( a b c -- x )
[ ] [ + + 2 / ] 3bi
[ '[ _ - ] tri@ ] [ neg ] bi
- * * * sqrt ;""" }
+ * * * sqrt ;" }
}
{ $slide "More idiomatic version"
"But there's a trick: put the lengths in an array"
- { $code """: v-n ( v n -- w ) '[ _ - ] map ;
+ { $code ": v-n ( v n -- w ) '[ _ - ] map ;
: area ( seq -- x )
[ 0 suffix ] [ sum 2 / ] bi
- v-n product sqrt ;""" }
+ v-n product sqrt ;" }
}
{ $slide "Implementing an abstraction"
{ "Suppose we want to get the price of the customer's first order, but any one of the steps along the way could be a nil value (" { $link f } " in Factor):" }
}
{ $slide "This is hard with mainstream syntax!"
{ $code
- """var customer = ...;
+ "var customer = ...;
var orders = (customer == null ? null : customer.orders);
var order = (orders == null ? null : orders[0]);
-var price = (order == null ? null : order.price);""" }
+var price = (order == null ? null : order.price);" }
}
{ $slide "An ad-hoc solution"
"Something like..."
{ $slide "A macro solution"
"Returns a quotation to the compiler"
"Constructed using map, fry, and concat"
- { $code """MACRO: plox ( seq -- quot )
+ { $code "MACRO: plox ( seq -- quot )
[
'[ dup _ when ]
- ] map [ ] concat-as ;"""
+ ] map [ ] concat-as ;"
}
}
{ $slide "Macro example"
"Return the caaar of a sequence"
{ "Return " { $snippet f } " on failure" }
- { $code """: caaar ( seq/f -- x/f )
+ { $code ": caaar ( seq/f -- x/f )
{
[ first ]
[ first ]
[ first ]
- } plox ;"""
+ } plox ;"
}
- { $code """{ { f } } caaar""" }
- { $code """{ { { 1 2 3 } } } caaar""" }
+ { $code "{ { f } } caaar" }
+ { $code "{ { { 1 2 3 } } } caaar" }
}
{ $slide "Smart combinators"
"Use stack checker to infer inputs and outputs"
{ $slide "Fibonacci"
"Not tail recursive"
"Call tree is huge"
- { $code """: fib ( n -- x )
+ { $code ": fib ( n -- x )
dup 1 <= [
[ 1 - fib ] [ 2 - fib ] bi +
- ] unless ;"""
+ ] unless ;"
}
{ $code "36 iota [ fib ] map ." }
}
{ $slide "Memoized Fibonacci"
"Change one word and it's efficient"
- { $code """MEMO: fib ( n -- x )
+ { $code "MEMO: fib ( n -- x )
dup 1 <= [
[ 1 - fib ] [ 2 - fib ] bi +
- ] unless ;"""
+ ] unless ;"
}
{ $code "36 iota [ fib ] map ." }
}
{ $slide "Example in C"
{ $code
-"""void do_stuff()
+"void do_stuff()
{
void *obj1, *obj2;
if(!(*obj1 = malloc(256))) goto end;
cleanup2: free(*obj2);
cleanup1: free(*obj1);
end: return;
-}"""
+}"
}
}
{ $slide "Example: allocating and disposing two buffers"
- { $code """: do-stuff ( -- )
+ { $code ": do-stuff ( -- )
[
256 malloc &free
256 malloc &free
... work goes here ...
- ] with-destructors ;"""
+ ] with-destructors ;"
}
}
{ $slide "Example: allocating two buffers for later"
- { $code """: do-stuff ( -- )
+ { $code ": do-stuff ( -- )
[
256 malloc |free
256 malloc |free
... work goes here ...
- ] with-destructors ;"""
+ ] with-destructors ;"
}
}
{ $slide "Example: disposing of an output port"
- { $code """M: output-port dispose*
+ { $code "M: output-port dispose*
[
{
[ handle>> &dispose drop ]
[ port-flush ]
[ handle>> shutdown ]
} cleave
- ] with-destructors ;"""
+ ] with-destructors ;"
}
}
{ $slide "Rapid application development"
}
{ $slide "The essence of Factor"
"Nicely named words abstract away the stack, leaving readable code"
- { $code """: surround ( seq left right -- seq' )
- swapd 3append ;"""
+ { $code ": surround ( seq left right -- seq' )
+ swapd 3append ;"
}
- { $code """: glue ( left right middle -- seq' )
- swap 3append ;"""
+ { $code ": glue ( left right middle -- seq' )
+ swap 3append ;"
}
{ $code HEREDOC: xyz
"a" "b" "c" 3append
"Handles C structures, C types, callbacks"
"Used extensively in the Windows and Unix backends"
{ $code
- """FUNCTION: double pow ( double x, double y ) ;
-2 5.0 pow ."""
+ "FUNCTION: double pow ( double x, double y ) ;
+2 5.0 pow ."
}
}
{ $slide "Windows win32 example"
{ $code
-"""M: windows gmt-offset
+"M: windows gmt-offset
( -- hours minutes seconds )
- "TIME_ZONE_INFORMATION" <c-object>
+ \"TIME_ZONE_INFORMATION\" <c-object>
dup GetTimeZoneInformation {
{ TIME_ZONE_ID_INVALID [
win32-error-string throw
{ TIME_ZONE_ID_STANDARD [
TIME_ZONE_INFORMATION-Bias
] }
- } case neg 60 /mod 0 ;"""
+ } case neg 60 /mod 0 ;"
}
}
{ $slide "Struct and function"
- { $code """C-STRUCT: TIME_ZONE_INFORMATION
- { "LONG" "Bias" }
- { { "WCHAR" 32 } "StandardName" }
- { "SYSTEMTIME" "StandardDate" }
- { "LONG" "StandardBias" }
- { { "WCHAR" 32 } "DaylightName" }
- { "SYSTEMTIME" "DaylightDate" }
- { "LONG" "DaylightBias" } ;"""
+ { $code "C-STRUCT: TIME_ZONE_INFORMATION
+ { \"LONG\" \"Bias\" }
+ { { \"WCHAR\" 32 } \"StandardName\" }
+ { \"SYSTEMTIME\" \"StandardDate\" }
+ { \"LONG\" \"StandardBias\" }
+ { { \"WCHAR\" 32 } \"DaylightName\" }
+ { \"SYSTEMTIME\" \"DaylightDate\" }
+ { \"LONG\" \"DaylightBias\" } ;"
}
- { $code """FUNCTION: DWORD GetTimeZoneInformation (
+ { $code "FUNCTION: DWORD GetTimeZoneInformation (
LPTIME_ZONE_INFORMATION
lpTimeZoneInformation
-) ;"""
+) ;"
}
}
{ $slide "Cocoa FFI"
- { $code """IMPORT: NSAlert [
+ { $code "IMPORT: NSAlert [
NSAlert -> new
[ -> retain ] [
- "Raptor" <CFString> &CFRelease
+ \"Raptor\" <CFString> &CFRelease
-> setMessageText:
] [
- "Look out!" <CFString> &CFRelease
+ \"Look out!\" <CFString> &CFRelease
-> setInformativeText:
] tri -> runModal drop
-] with-destructors"""
+] with-destructors"
}
}
{ $slide "Deployment demo"
IN: variants
HELP: VARIANT:
-{ $syntax """
+{ $syntax "
VARIANT: class-name
singleton
singleton
.
.
.
- ; """ }
+ ; " }
{ $description "Defines " { $snippet "class-name" } " as a union of the following " { $link singleton-class } " and " { $link tuple-class } " definitions. Each " { $snippet "singleton" } " word is defined as a " { $snippet "singleton-class" } ", and each " { $snippet "tuple" } " word is defined as a " { $snippet "tuple-class" } " with the given set of " { $snippet "slot" } "s, using the same syntax for slot specifiers as " { $link POSTPONE: TUPLE: } ". Typed tuple slots can recursively reference the variant " { $snippet "class-name" } " being defined. For " { $snippet "tuple" } " types, a " { $link boa } " constructor word " { $snippet "<tuple>" } " is defined as well." }
-{ $examples { $code """
+{ $examples { $code "
USING: kernel variants ;
IN: scratchpad
nil
cons: { { first object } { rest list } }
;
-""" } } ;
+" } } ;
HELP: VARIANT-MEMBER:
{ $description "Defines a new member of a variant class without restricting such definitions to a single statement or source file. The variant class should be listed first, and the class member should follow." }
-{ $examples { $code """
+{ $examples { $code "
USING: kernel variants ;
IN: scratchpad
VARIANT-MEMBER: list nil ;
VARIANT-MEMBER: list cons: { { first object } { rest list } } ;
-""" } } ;
+" } } ;
HELP: match
{ $values { "branches" array } }
{ $description "Dispatches on the type of the value on the top of the stack. If the type is a " { $link singleton-class } ", the corresponding quotation is called with the underlying stack unchanged. If the type is a " { $link tuple-class } ", the tuple slots are pushed onto the stack by order of arguments." }
-{ $examples { $example """
+{ $examples { $example "
USING: kernel math prettyprint variants ;
IN: scratchpad
} match ;
1 2 3 4 nil <cons> <cons> <cons> <cons> list-length .
-""" "4" } } ;
+" "4" } } ;
HELP: unboa
{ $values { "class" class } }
;
HELP: implicit-tags
-{ $var-description """When this is set, tags are omitted during serialization when it safe to do so. For example, 42 can be safely serialized as "42", but "42" must be serialized as "'42'" or ""42"" or "!!str 42". This uses the """
+{ $var-description "When this is set, tags are omitted during serialization when it safe to do so. For example, 42 can be safely serialized as \"42\", but \"42\" must be serialized as \"'42'\" or \"\"42\"\" or \"!!str 42\". This uses the "
{ $snippet "implicit" } " parameter of "
{ $link yaml_scalar_event_initialize } ", " { $link yaml_sequence_start_event_initialize } " and " { $link yaml_mapping_start_event_initialize } "."
} ;
"See " { $url "http://yaml.org/type/merge.html" } $nl
"As per " { $url "http://sourceforge.net/p/yaml/mailman/message/12308050" }
", the merge key is implemented bottom up:" $nl
-{ $example """USING: yaml prettyprint ;
-"
+{ $example "USING: yaml prettyprint ;
+\"
foo: 1
<<:
bar: 2
<<:
baz: 3
-" yaml> ."""
-"""H{ { "baz" 3 } { "foo" 1 } { "bar" 2 } }""" }
+\" yaml> ."
+"H{ { \"baz\" 3 } { \"foo\" 1 } { \"bar\" 2 } }" }
{ $heading "!!value" }
"See " { $url "http://yaml.org/type/value.html" } $nl
-{ $example """USING: yaml prettyprint ;
-"
+{ $example "USING: yaml prettyprint ;
+\"
--- # Old schema
link with:
- library1.dll
version: 1.2
- = : library2.dll
version: 2.3
-" yaml-docs> ."""
-"""{
- H{ { "link with" { "library1.dll" "library2.dll" } } }
- H{ { "link with" { "library1.dll" "library2.dll" } } }
-}"""
+\" yaml-docs> ."
+"{
+ H{ { \"link with\" { \"library1.dll\" \"library2.dll\" } } }
+ H{ { \"link with\" { \"library1.dll\" \"library2.dll\" } } }
+}"
}
;
+libyaml-default+ emitter-line-break set
t emitter-unicode set
"
-"""{
+"{
H{
- { "name" "Mark McGwire" }
- { "hr" 65 }
- { "avg" 0.278 }
+ { \"name\" \"Mark McGwire\" }
+ { \"hr\" 65 }
+ { \"avg\" 0.278 }
}
H{
- { "name" "Sammy Sosa" }
- { "hr" 63 }
- { "avg" 0.288 }
+ { \"name\" \"Sammy Sosa\" }
+ { \"hr\" 63 }
+ { \"avg\" 0.288 }
}
-} >yaml print"""
+} >yaml print"
"- name: Mark McGwire
hr: 65
avg: 0.278
}
{ $heading "Output -- verbose" }
{ $example "USING: yaml yaml.config ;"
-"""f implicit-tags set
+"f implicit-tags set
f implicit-start set
f implicit-end set
+libyaml-default+ emitter-canonical set
+libyaml-default+ emitter-line-break set
t emitter-unicode set
-{ t 32 "foobar" { "nested" "list" } H{ { "nested" "assoc" } } } >yaml print"""
+{ t 32 \"foobar\" { \"nested\" \"list\" } H{ { \"nested\" \"assoc\" } } } >yaml print"
"--- !!seq\n- !!bool true\n- !!int 32\n- !!str foobar\n- !!seq\n - !!str nested\n - !!str list\n- !!map\n !!str nested: !!str assoc\n...\n"
}
}
t emitter-unicode set
! Basic test
-CONSTANT: test-string """--- # Favorite movies
+CONSTANT: test-string "--- # Favorite movies
- Casablanca
- North by Northwest
- The Man Who Wasn't There
- foo
- bar
- baz
-"""
+"
CONSTANT: test-obj {
"Casablanca"
"North by Northwest"
"The Man Who Wasn't There"
H{ { "last" { "foo" "bar" "baz" } } }
}
-CONSTANT: test-represented-string """--- !!seq
+CONSTANT: test-represented-string "--- !!seq
- !!str Casablanca
- !!str North by Northwest
- !!str The Man Who Wasn't There
- !!str bar
- !!str baz
...
-"""
+"
${ test-obj } [ $ test-string yaml> ] unit-test
${ test-represented-string } [ $ test-obj >yaml ] unit-test
! Non-scalar key
CONSTANT: complex-key H{ { { "foo" } "bar" } }
-CONSTANT: complex-key-represented """--- !!map
+CONSTANT: complex-key-represented "--- !!map
? !!seq
- !!str foo
: !!str bar
...
-"""
+"
${ complex-key } [ $ complex-key-represented yaml> ] unit-test
! Multiple docs
-CONSTANT: test-docs """--- !!str a
+CONSTANT: test-docs "--- !!str a
...
--- !!seq
- !!str b
--- !!map
!!str d: !!str e
...
-"""
+"
CONSTANT: test-objs { "a" { "b" "c" } H{ { "d" "e" } } }
${ test-objs } [ $ test-docs yaml-docs> ] unit-test
! Misc types
CONSTANT: test-types { 1 t f 1.0 }
-CONSTANT: test-represented-types """--- !!seq
+CONSTANT: test-represented-types "--- !!seq
- !!int 1
- !!bool true
- !!bool false
- !!float 1.0
...
-"""
+"
${ test-types } [ $ test-represented-types yaml> ] unit-test
${ test-types } [ $ test-types >yaml yaml> ] unit-test
! Anchors
-CONSTANT: test-anchors """- &1 "1"
+CONSTANT: test-anchors "- &1 \"1\"
- *1
- &2 ["1","2"]
- *2
- &3
*1 : "one"
- *3
-"""
+"
CONSTANT: test-anchors-obj {
"1" "1" { "1" "2" } { "1" "2" } H{ { "1" "one" } } H{ { "1" "one" } }
}
{ t } [ $ test-anchors yaml> >yaml yaml> 2 group [ all-eq? ] all? ] unit-test
! Anchors and fancy types
-CONSTANT: fancy-anchors """- &1 [ "foo" ]
+CONSTANT: fancy-anchors "- &1 [ \"foo\" ]
- &2 !!set
? *1
- *2
-"""
+"
CONSTANT: fancy-anchors-obj {
{ "foo" } HS{ { "foo" } } HS{ { "foo" } }
}
CONSTANT: simple-recursive-list-anchored T{ yaml-anchor f "0" {
T{ yaml-alias f "0" }
} }
-CONSTANT: simple-recursive-list-yaml """&0
-- *0"""
+CONSTANT: simple-recursive-list-yaml "&0
+- *0"
${ simple-recursive-list-anchored } [ simple-recursive-list replace-identities ] unit-test
${ simple-recursive-list-anchored } [ $ simple-recursive-list-yaml yaml> replace-identities ] unit-test
! { "but" H{ { "y" "is a string" } { "n" "is a string" } } }
! }
!
-! CONSTANT: construct-bool-str """canonical: yes
+! CONSTANT: construct-bool-str "canonical: yes
! answer: NO
! logical: True
! option: on
! but:
! y: is a string
! n: is a string
-! """
+! "
!
! ${ construct-bool-obj } [ $ construct-bool-str yaml> ] unit-test
! ${ construct-bool-obj } [ $ construct-bool-obj >yaml yaml> ] unit-test
! { "binary" 685230 }
! { "sexagesimal" 685230 }
! }
-! CONSTANT: construct-int-str """canonical: 685230
+! CONSTANT: construct-int-str "canonical: 685230
! decimal: +685_230
! octal: 02472256
! hexadecimal: 0x_0A_74_AE
! binary: 0b1010_0111_0100_1010_1110
! sexagesimal: 190:20:30
-! """
+! "
!
! ${ construct-int-obj } [ $ construct-int-str yaml> ] unit-test
! ${ construct-int-obj } [ $ construct-int-obj >yaml yaml> ] unit-test
}
}
-CONSTANT: construct-map-str """# Unordered set of key: value pairs.
+CONSTANT: construct-map-str "# Unordered set of key: value pairs.
Block style: !!map
Clark : Evans
Brian : Ingerson
Oren : Ben-Kiki
Flow style: !!map { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki }
-"""
+"
${ construct-map-obj } [ $ construct-map-str yaml> ] unit-test
${ construct-map-obj } [ $ construct-map-obj >yaml yaml> ] unit-test
}
-CONSTANT: construct-null-str """# A document may be null.
+CONSTANT: construct-null-str "# A document may be null.
---
---
# This mapping has four keys,
-
- 4th entry
- Null
-"""
+"
${ construct-null-obj } [ $ construct-null-str yaml-docs> ] unit-test
! TODO Decide what to do with null -> f -> false
{ "Flow style" { "Mercury" "Venus" "Earth" "Mars" "Jupiter" "Saturn" "Uranus" "Neptune" "Pluto" } }
}
-CONSTANT: construct-seq-str """# Ordered sequence of nodes
+CONSTANT: construct-seq-str "# Ordered sequence of nodes
Block style: !!seq
- Mercury # Rotates - no light/dark sides.
- Venus # Deadliest. Aptly named.
Flow style: !!seq [ Mercury, Venus, Earth, Mars, # Rocks
Jupiter, Saturn, Uranus, Neptune, # Gas
Pluto ] # Overrated
-"""
+"
${ construct-seq-obj } [ $ construct-seq-str yaml> ] unit-test
${ construct-seq-obj } [ $ construct-seq-obj >yaml yaml> ] unit-test
}
}
-CONSTANT: construct-set-str """# Explicitly typed set.
+CONSTANT: construct-set-str "# Explicitly typed set.
baseball players: !!set
? Mark McGwire
? Sammy Sosa
? Ken Griffey
# Flow style
baseball teams: !!set { Boston Red Sox, Detroit Tigers, New York Yankees }
-"""
+"
${ construct-set-obj } [ $ construct-set-str yaml> ] unit-test
${ construct-set-obj } [ $ construct-set-obj >yaml yaml> ] unit-test
}
}
-CONSTANT: construct-binary-str """canonical: !!binary "\\
+CONSTANT: construct-binary-str "canonical: !!binary \"\\
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\\
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\\
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\\
- AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=\"
generic: !!binary |
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
description:
The binary value above is a tiny arrow encoded as a gif image.
-"""
+"
${ construct-binary-obj } [ $ construct-binary-str yaml> ] unit-test
${ construct-binary-obj } [ $ construct-binary-obj >yaml yaml> ] unit-test
H{ { T{ yaml-merge } { BIG LEFT SMALL } } { "x" 1 } { "label" "center/big" } }
} ;
-CONSTANT: construct-merge-str """---
+CONSTANT: construct-merge-str "---
- &CENTER { x: 1, 'y': 2 }
- &LEFT { x: 0, 'y': 2 }
- &BIG { r: 10 }
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big
-"""
+"
${ construct-merge-obj } [ $ construct-merge-str yaml> ] unit-test
${ construct-merge-obj } [ $ construct-merge-obj2 >yaml yaml> ] unit-test
}
}
-CONSTANT: construct-omap-str """# Explicitly typed ordered map (dictionary).
+CONSTANT: construct-omap-str "# Explicitly typed ordered map (dictionary).
Bestiary: !!omap
- aardvark: African pig-like ant eater. Ugly.
- anteater: South-American ant eater. Two species.
# Etc.
# Flow style
Numbers: !!omap [ one: 1, two: 2, three : 3 ]
-"""
+"
${ construct-omap-obj } [ $ construct-omap-str yaml> ] unit-test
${ construct-omap-obj } [ construct-omap-obj >yaml yaml> ] unit-test
}
}
-CONSTANT: construct-pairs-str """# Explicitly typed pairs.
+CONSTANT: construct-pairs-str "# Explicitly typed pairs.
Block tasks: !!pairs
- meeting: with team.
- meeting: with boss.
- break: lunch.
- meeting: with client.
Flow tasks: !!pairs [ meeting: with team, meeting: with boss ]
-"""
+"
CONSTANT: construct-pairs-obj-roundtripped H{
{
}
}
}
-CONSTANT: construct-timestamp-str """canonical: 2001-12-15T02:59:43.1Z
+CONSTANT: construct-timestamp-str "canonical: 2001-12-15T02:59:43.1Z
valid iso8601: 2001-12-14t21:59:43.10-05:00
space separated: 2001-12-14 21:59:43.10 -5
no time zone (Z): 2001-12-15 2:59:43.10
date (00:00:00Z): 2002-12-14
crazy: 2002-2-4 \t\t \t 1:02:59.123 \t\t +10:23
-"""
+"
${ construct-timestamp-obj } [ $ construct-timestamp-str yaml> ] unit-test
${ construct-timestamp-obj } [ $ construct-timestamp-obj >yaml yaml> ] unit-test
H{ { "link with" { "library1.dll" "library2.dll" } } }
}
-CONSTANT: construct-value-str """--- # Old schema
+CONSTANT: construct-value-str "--- # Old schema
link with:
- library1.dll
- library2.dll
version: 1.2
- = : library2.dll
version: 2.3
-"""
+"
${ construct-value-safe-obj } [ $ construct-value-str yaml-docs> ] unit-test
${ construct-value-safe-obj } [ $ construct-value-safe-obj >yaml-docs yaml-docs> ] unit-test
! unicode off
f emitter-unicode
[
-{ """- Hello
-- "Gr\\xFC\\xDF dich"
-- "\\u0437\\u0434\\u0440\\u0430\\u0432\\u0441\\u0442\\u0432\\u0443\\u0439\\u0442\\u0435"
-- "\\u3053\\u3093\\u306B\\u3061\\u306F"
-- "\\uC548\\uB155\\uD558\\uC138\\uC694"
-- "\\u05E9\\u05B8\\u05C1\\u05DC\\u05D5\\u05B9\\u05DD "
-- "\\u10D2\\u10D0\\u10DB\\u10D0\\u10E0\\u10EF\\u10DD\\u10D1\\u10D0"
-""" } [ { "Hello" "Grüß dich" "здравствуйте" "こんにちは" "안녕하세요" "שָׁלוֹם " "გამარჯობა" } >yaml ] unit-test
+{ "- Hello
+- \"Gr\\xFC\\xDF dich\"
+- \"\\u0437\\u0434\\u0440\\u0430\\u0432\\u0441\\u0442\\u0432\\u0443\\u0439\\u0442\\u0435\"
+- \"\\u3053\\u3093\\u306B\\u3061\\u306F\"
+- \"\\uC548\\uB155\\uD558\\uC138\\uC694\"
+- \"\\u05E9\\u05B8\\u05C1\\u05DC\\u05D5\\u05B9\\u05DD \"
+- \"\\u10D2\\u10D0\\u10DB\\u10D0\\u10E0\\u10EF\\u10DD\\u10D1\\u10D0\"
+" } [ { "Hello" "Grüß dich" "здравствуйте" "こんにちは" "안녕하세요" "שָׁלוֹם " "გამარჯობა" } >yaml ] unit-test
] with-variable
! canonical
t emitter-canonical [
-{ """---
+{ "---
!!seq [
- !!int "1",
- !!float "2.0",
- !!bool "false",
+ !!int \"1\",
+ !!float \"2.0\",
+ !!bool \"false\",
]
-""" } [ { 1 2.0 f } >yaml ] unit-test
+" } [ { 1 2.0 f } >yaml ] unit-test
] with-variable
{