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

db4
Jon Harper 2009-10-04 03:26:14 +09:00
commit d75be8defe
629 changed files with 9937 additions and 6838 deletions

View File

@ -24,10 +24,12 @@ HELP: every
ARTICLE: "alarms" "Alarms"
"The " { $vocab-link "alarms" } " vocabulary provides a lightweight way to schedule one-time and recurring tasks without spawning a new thread."
{ $subsection alarm }
{ $subsection add-alarm }
{ $subsection later }
{ $subsection cancel-alarm }
{ $subsections
alarm
add-alarm
later
cancel-alarm
}
"Alarms do not persist across image saves. Saving and restoring an image has the effect of calling " { $link cancel-alarm } " on all " { $link alarm } " instances." ;
ABOUT: "alarms"

View File

@ -136,33 +136,37 @@ ARTICLE: "c-out-params" "Output parameters in C"
"A frequently-occurring idiom in C code is the \"out parameter\". If a C function returns more than one value, the caller passes pointers of the correct type, and the C function writes its return values to those locations."
$nl
"Each numerical C type, together with " { $snippet "void*" } ", has an associated " { $emphasis "out parameter constructor" } " word which takes a Factor object as input, constructs a byte array of the correct size, and converts the Factor object to a C value stored into the byte array:"
{ $subsection <char> }
{ $subsection <uchar> }
{ $subsection <short> }
{ $subsection <ushort> }
{ $subsection <int> }
{ $subsection <uint> }
{ $subsection <long> }
{ $subsection <ulong> }
{ $subsection <longlong> }
{ $subsection <ulonglong> }
{ $subsection <float> }
{ $subsection <double> }
{ $subsection <void*> }
{ $subsections
<char>
<uchar>
<short>
<ushort>
<int>
<uint>
<long>
<ulong>
<longlong>
<ulonglong>
<float>
<double>
<void*>
}
"You call the out parameter constructor with the required initial value, then pass the byte array to the C function, which receives a pointer to the start of the byte array's data area. The C function then returns, leaving the result in the byte array; you read it back using the next set of words:"
{ $subsection *char }
{ $subsection *uchar }
{ $subsection *short }
{ $subsection *ushort }
{ $subsection *int }
{ $subsection *uint }
{ $subsection *long }
{ $subsection *ulong }
{ $subsection *longlong }
{ $subsection *ulonglong }
{ $subsection *float }
{ $subsection *double }
{ $subsection *void* }
{ $subsections
*char
*uchar
*short
*ushort
*int
*uint
*long
*ulong
*longlong
*ulonglong
*float
*double
*void*
}
"Note that while structure and union types do not get these words defined for them, there is no loss of generality since " { $link <void*> } " and " { $link *void* } " may be used." ;
ARTICLE: "c-types.primitives" "Primitive C types"
@ -227,11 +231,22 @@ ARTICLE: "c-types.structs" "Struct and union types"
"Struct and union types are identified by their class word. See " { $link "classes.struct" } "." ;
ARTICLE: "c-types-specs" "C type specifiers"
"C types are identified by special words, and type names occur as parameters to the " { $link alien-invoke } ", " { $link alien-indirect } " and " { $link alien-callback } " words. New C types can be defined by the words " { $link POSTPONE: STRUCT: } ", " { $link POSTPONE: UNION-STRUCT: } ", " { $link POSTPONE: CALLBACK: } ", and " { $link POSTPONE: TYPEDEF: } "."
{ $subsection "c-types.primitives" }
{ $subsection "c-types.pointers" }
{ $subsection "c-types.ambiguity" }
{ $subsection "c-types.structs" }
"C types are identified by special words, and type names occur as parameters to the " { $link alien-invoke } ", " { $link alien-indirect } " and " { $link alien-callback } " words."
$nl
"Defining new C types:"
{ $subsections
POSTPONE: STRUCT:
POSTPONE: UNION-STRUCT:
POSTPONE: CALLBACK:
POSTPONE: TYPEDEF:
}
{ $heading "Related articles" }
{ $subsections
"c-types.primitives"
"c-types.pointers"
"c-types.ambiguity"
"c-types.structs"
}
;
ABOUT: "c-types-specs"

View File

@ -53,26 +53,32 @@ ARTICLE: "malloc" "Manual memory management"
"Sometimes data passed to C functions must be allocated at a fixed address. See " { $link "byte-arrays-gc" } " for an explanation of when this is the case."
$nl
"Allocating a C datum with a fixed address:"
{ $subsection malloc-object }
{ $subsection malloc-byte-array }
{ $subsection malloc-file-contents }
"There is a set of words in the " { $vocab-link "libc" } " vocabulary which directly call C standard library memory management functions:"
{ $subsection malloc }
{ $subsection calloc }
{ $subsection realloc }
{ $subsections
malloc-object
malloc-byte-array
malloc-file-contents
}
"The " { $vocab-link "libc" } " vocabulary defines several words which directly call C standard library memory management functions:"
{ $subsections
malloc
calloc
realloc
}
"You must always free pointers returned by any of the above words when the block of memory is no longer in use:"
{ $subsection free }
{ $subsections free }
"Utilities for automatically freeing memory in conjunction with " { $link with-destructors } ":"
{ $subsection &free }
{ $subsection |free }
{ $subsections
&free
|free
}
"The " { $link &free } " and " { $link |free } " words are generated using " { $link "alien.destructors" } "."
$nl
"You can unsafely copy a range of bytes from one memory location to another:"
{ $subsection memcpy }
{ $subsections memcpy }
"You can copy a range of bytes from memory into a byte array:"
{ $subsection memory>byte-array }
{ $subsections memory>byte-array }
"You can copy a byte array to memory unsafely:"
{ $subsection byte-array>memory } ;
{ $subsections byte-array>memory } ;
ARTICLE: "c-pointers" "Passing pointers to C functions"
"The following Factor objects may be passed to C function parameters with pointer types:"
@ -83,11 +89,11 @@ ARTICLE: "c-pointers" "Passing pointers to C functions"
{ "Any data type which defines a method on " { $link >c-ptr } " that returns an instance of one of the above. This includes " { $link "classes.struct" } " and " { $link "specialized-arrays" } "." }
}
"The class of primitive C pointer types:"
{ $subsection c-ptr }
{ $subsections c-ptr }
"A generic word for converting any object to a C pointer; user-defined types may add methods to this generic word:"
{ $subsection >c-ptr }
{ $subsections >c-ptr }
"More about the " { $link alien } " type:"
{ $subsection "aliens" }
{ $subsections "aliens" }
{ $warning
"The Factor garbage collector can move byte arrays around, and code passing byte arrays, or objects backed by byte arrays, must obey important guidelines. See " { $link "byte-arrays-gc" } "." } ;
@ -95,19 +101,21 @@ ARTICLE: "c-data" "Passing data between Factor and C"
"Two defining characteristics of Factor are dynamic typing and automatic memory management, which are somewhat incompatible with the machine-level data model exposed by C. Factor's C library interface defines its own set of C data types, distinct from Factor language types, together with automatic conversion between Factor values and C types. For example, C integer types must be declared and are fixed-width, whereas Factor supports arbitrary-precision integers."
$nl
"Furthermore, Factor's garbage collector can move objects in memory; for a discussion of the consequences, see " { $link "byte-arrays-gc" } "."
{ $subsection "c-types-specs" }
{ $subsection "c-pointers" }
{ $subsection "malloc" }
{ $subsection "c-strings" }
{ $subsection "c-out-params" }
{ $subsections
"c-types-specs"
"c-pointers"
"malloc"
"c-strings"
"c-out-params"
}
"Important guidelines for passing data in byte arrays:"
{ $subsection "byte-arrays-gc" }
{ $subsections "byte-arrays-gc" }
"C-style enumerated types are supported:"
{ $subsection POSTPONE: C-ENUM: }
{ $subsections POSTPONE: C-ENUM: }
"C types can be aliased for convenience and consitency with native library documentation:"
{ $subsection POSTPONE: TYPEDEF: }
{ $subsections POSTPONE: TYPEDEF: }
"A utility for defining " { $link "destructors" } " for deallocating memory:"
{ $subsection "alien.destructors" }
{ $subsections "alien.destructors" }
"C struct and union types can be defined with " { $link POSTPONE: STRUCT: } " and " { $link POSTPONE: UNION: } ". See " { $link "classes.struct" } " for details. For passing arrays to and from C, use the " { $link "specialized-arrays" } " vocabulary." ;
HELP: malloc-string
@ -142,11 +150,13 @@ $nl
"Care must be taken if the C function expects a " { $link char* } " with a length in bytes, rather than a null-terminated " { $link char* } "; passing the result of calling " { $link length } " on the string object will not suffice. This is because a Factor string of " { $emphasis "n" } " characters will not necessarily encode to " { $emphasis "n" } " bytes. The correct idiom for C functions which take a string with a length is to first encode the string using " { $link encode } ", and then pass the resulting byte array together with the length of this byte array."
$nl
"Sometimes a C function has a parameter type of " { $link void* } ", and various data types, among them strings, can be passed in. In this case, strings are not automatically converted to aliens, and instead you must call one of these words:"
{ $subsection string>alien }
{ $subsection malloc-string }
{ $subsections
string>alien
malloc-string
}
"The first allocates " { $link byte-array } "s, and the latter allocates manually-managed memory which is not moved by the garbage collector and has to be explicitly freed by calling " { $link free } ". See " { $link "byte-arrays-gc" } " for a discussion of the two approaches."
$nl
"A word to read strings from arbitrary addresses:"
{ $subsection alien>string }
{ $subsections alien>string }
"For example, if a C function returns a " { $link char* } " but stipulates that the caller must deallocate the memory afterward, you must define the function as returning " { $link void* } ", and call one of the above words before passing the pointer to " { $link free } "." ;

View File

@ -25,6 +25,6 @@ HELP: DESTRUCTOR:
ARTICLE: "alien.destructors" "Alien destructors"
"The " { $vocab-link "alien.destructors" } " vocabulary defines a utility parsing word for defining new disposable classes."
{ $subsection POSTPONE: DESTRUCTOR: } ;
{ $subsections POSTPONE: DESTRUCTOR: } ;
ABOUT: "alien.destructors"

View File

@ -56,13 +56,14 @@ HELP: fortran-invoke
ARTICLE: "alien.fortran" "Fortran FFI"
"The " { $vocab-link "alien.fortran" } " vocabulary provides an interface to code in shared libraries written in Fortran."
{ $subsection "alien.fortran-types" }
{ $subsection "alien.fortran-abis" }
{ $subsection add-fortran-library }
{ $subsection POSTPONE: LIBRARY: }
{ $subsection POSTPONE: FUNCTION: }
{ $subsection POSTPONE: SUBROUTINE: }
{ $subsection fortran-invoke }
;
{ $subsections
"alien.fortran-types"
"alien.fortran-abis"
add-fortran-library
POSTPONE: LIBRARY:
POSTPONE: FUNCTION:
POSTPONE: SUBROUTINE:
fortran-invoke
} ;
ABOUT: "alien.fortran"

View File

@ -65,8 +65,10 @@ HELP: remove-library
ARTICLE: "loading-libs" "Loading native libraries"
"Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
{ $subsection add-library }
{ $subsection remove-library }
{ $subsections
add-library
remove-library
}
"Once a library has been defined, you can try loading it to see if the path name is correct:"
{ $subsection load-library }
{ $subsections load-library }
"If the compiler cannot load a library, or cannot resolve a symbol in a library, a linkage error is reported using the compiler error mechanism (see " { $link "compiler-errors" } "). Once you install the right library, reload the source file containing the " { $link add-library } " form to force the compiler to try loading the library again." ;

View File

@ -13,8 +13,10 @@ HELP: ALIEN:
{ $notes "Alien objects are invalidated between image saves and loads, and hence source files should not contain alien literals; this word is for interactive use only. See " { $link "alien-expiry" } " for details." } ;
ARTICLE: "syntax-aliens" "Alien object literal syntax"
{ $subsection POSTPONE: ALIEN: }
{ $subsection POSTPONE: DLL" } ;
{ $subsections
POSTPONE: ALIEN:
POSTPONE: DLL"
} ;
HELP: LIBRARY:
{ $syntax "LIBRARY: name" }

View File

@ -61,18 +61,22 @@ ARTICLE: "ascii" "ASCII"
"The " { $vocab-link "ascii" } " vocabulary implements support for the legacy ASCII character set. Most applications should use " { $link "unicode" } " instead."
$nl
"ASCII character classes:"
{ $subsection blank? }
{ $subsection letter? }
{ $subsection LETTER? }
{ $subsection digit? }
{ $subsection printable? }
{ $subsection control? }
{ $subsection quotable? }
{ $subsection ascii? }
{ $subsections
blank?
letter?
LETTER?
digit?
printable?
control?
quotable?
ascii?
}
"ASCII case conversion:"
{ $subsection ch>lower }
{ $subsection ch>upper }
{ $subsection >lower }
{ $subsection >upper } ;
{ $subsections
ch>lower
ch>upper
>lower
>upper
} ;
ABOUT: "ascii"

View File

@ -36,12 +36,16 @@ HELP: encode-base64-lines
ARTICLE: "base64" "Base 64 conversions"
"The " { $vocab-link "base64" } " vocabulary implements conversions of sequences to printable characters in base 64. These plain-text representations of binary data may be passed around and converted back to binary data later." $nl
"Converting to and from base64 as strings:"
{ $subsection >base64 }
{ $subsection >base64-lines }
{ $subsection base64> }
{ $subsections
>base64
>base64-lines
base64>
}
"Using base64 from streams:"
{ $subsection encode-base64 }
{ $subsection encode-base64-lines }
{ $subsection decode-base64 } ;
{ $subsections
encode-base64
encode-base64-lines
decode-base64
} ;
ABOUT: "base64"

View File

@ -26,12 +26,16 @@ $nl
"Bidirectional assocs implement the entire " { $link "assocs-protocol" } " with the exception of " { $link delete-at } ". Duplicate values are allowed, however value lookups with " { $link value-at } " only return the first key that a given value was stored with."
$nl
"The class of biassocs:"
{ $subsection biassoc }
{ $subsection biassoc? }
{ $subsections
biassoc
biassoc?
}
"Creating new biassocs:"
{ $subsection <biassoc> }
{ $subsection <bihash> }
{ $subsections
<biassoc>
<bihash>
}
"Converting existing assocs to biassocs:"
{ $subsection >biassoc } ;
{ $subsections >biassoc } ;
ABOUT: "biassocs"

View File

@ -33,11 +33,13 @@ HELP: sorted-memq?
ARTICLE: "binary-search" "Binary search"
"The " { $emphasis "binary search" } " algorithm allows elements to be located in sorted sequence in " { $snippet "O(log n)" } " time."
{ $subsection search }
{ $subsections search }
"Variants of sequence words optimized for sorted sequences:"
{ $subsection sorted-index }
{ $subsection sorted-member? }
{ $subsection sorted-memq? }
{ $subsections
sorted-index
sorted-member?
sorted-memq?
}
{ $see-also "order-specifiers" "sequences-sorting" } ;
ABOUT: "binary-search"

View File

@ -10,19 +10,27 @@ $nl
"Bit arrays play a special role in the C library interface; they can be used to pass binary data back and forth between Factor and C. See " { $link "c-pointers" } "."
$nl
"Bit arrays form a class of objects:"
{ $subsection bit-array }
{ $subsection bit-array? }
{ $subsections
bit-array
bit-array?
}
"Creating new bit arrays:"
{ $subsection >bit-array }
{ $subsection <bit-array> }
{ $subsections
>bit-array
<bit-array>
}
"Efficiently setting and clearing all bits in a bit array:"
{ $subsection set-bits }
{ $subsection clear-bits }
{ $subsections
set-bits
clear-bits
}
"Converting between unsigned integers and their binary representation:"
{ $subsection integer>bit-array }
{ $subsection bit-array>integer }
{ $subsections
integer>bit-array
bit-array>integer
}
"Bit array literal syntax:"
{ $subsection POSTPONE: ?{ } ;
{ $subsections POSTPONE: ?{ } ;
ABOUT: "bit-arrays"

View File

@ -6,13 +6,17 @@ ARTICLE: "bit-vectors" "Bit vectors"
"A bit vector is a resizable mutable sequence of bits. Bit vector words are found in the " { $vocab-link "bit-vectors" } " vocabulary."
$nl
"Bit vectors form a class:"
{ $subsection bit-vector }
{ $subsection bit-vector? }
{ $subsections
bit-vector
bit-vector?
}
"Creating bit vectors:"
{ $subsection >bit-vector }
{ $subsection <bit-vector> }
{ $subsections
>bit-vector
<bit-vector>
}
"Literal syntax:"
{ $subsection POSTPONE: ?V{ }
{ $subsections POSTPONE: ?V{ }
"If you don't care about initial capacity, a more elegant way to create a new bit vector is to write:"
{ $code "?V{ } clone" } ;

View File

@ -3,7 +3,7 @@ IN: bootstrap.image
ARTICLE: "bootstrap.image" "Bootstrapping new images"
"A new image can be built from source; this is known as " { $emphasis "bootstrap" } ". Bootstrap is a two-step process. The first stage is the creation of a bootstrap image from a running Factor instance:"
{ $subsection make-image }
{ $subsections make-image }
"The second bootstrapping stage is initiated by running the resulting bootstrap image:"
{ $code "./factor -i=boot.x86.32.image" }
"This stage loads additional code, compiles all words, and dumps a final " { $snippet "factor.image" } "."

View File

@ -24,14 +24,16 @@ HELP: ?box
ARTICLE: "boxes" "Boxes"
"A " { $emphasis "box" } " is a container which can either be empty or hold a single value."
{ $subsection box }
{ $subsections box }
"Creating an empty box:"
{ $subsection <box> }
{ $subsections <box> }
"Storing a value and removing a value from a box:"
{ $subsection >box }
{ $subsection box> }
{ $subsections
>box
box>
}
"Safely removing a value:"
{ $subsection ?box }
{ $subsections ?box }
"Testing if a box is full can be done by reading the " { $snippet "occupied" } " slot." ;
ABOUT: "boxes"

View File

@ -520,125 +520,142 @@ HELP: since-1970
ARTICLE: "calendar" "Calendar"
"The two data types used throughout the calendar library:"
{ $subsection timestamp }
{ $subsection duration }
{ $subsections
timestamp
duration
}
"Durations represent spans of time:"
{ $subsection "using-durations" }
{ $subsections "using-durations" }
"Arithmetic on timestamps and durations:"
{ $subsection "timestamp-arithmetic" }
{ $subsections "timestamp-arithmetic" }
"Getting the current timestamp:"
{ $subsection now }
{ $subsection gmt }
{ $subsections
now
gmt
}
"Converting between timestamps:"
{ $subsection >local-time }
{ $subsection >gmt }
{ $subsections
>local-time
>gmt
}
"Converting between timezones:"
{ $subsection convert-timezone }
{ $subsections convert-timezone }
"Timestamps relative to each other:"
{ $subsection "relative-timestamps" }
{ $subsections "relative-timestamps" }
"Operations on units of time:"
{ $subsection "years" }
{ $subsection "months" }
{ $subsection "days" }
{ $subsections
"years"
"months"
"days"
}
"Meta-data about the calendar:"
{ $subsection "calendar-facts" }
{ $subsections "calendar-facts" }
;
ARTICLE: "timestamp-arithmetic" "Timestamp arithmetic"
"Adding timestamps and durations, or durations and durations:"
{ $subsection time+ }
{ $subsections time+ }
"Subtracting:"
{ $subsection time- }
{ $subsections time- }
"Element-wise multiplication:"
{ $subsection time* } ;
{ $subsections time* } ;
ARTICLE: "using-durations" "Using durations"
"Creating a duration object:"
{ $subsection years }
{ $subsection months }
{ $subsection weeks }
{ $subsection days }
{ $subsection hours }
{ $subsection minutes }
{ $subsection seconds }
{ $subsection milliseconds }
{ $subsection microseconds }
{ $subsection nanoseconds }
{ $subsection instant }
{ $subsections
years
months
weeks
days
hours
minutes
seconds
milliseconds
microseconds
nanoseconds
instant
}
"Converting a duration to a number:"
{ $subsection duration>years }
{ $subsection duration>months }
{ $subsection duration>days }
{ $subsection duration>hours }
{ $subsection duration>minutes }
{ $subsection duration>seconds }
{ $subsection duration>milliseconds }
{ $subsection duration>microseconds }
{ $subsection duration>nanoseconds } ;
{ $subsections
duration>years
duration>months
duration>days
duration>hours
duration>minutes
duration>seconds
duration>milliseconds
duration>microseconds
duration>nanoseconds
} ;
ARTICLE: "relative-timestamps" "Relative timestamps"
"In the future:"
{ $subsection hence }
{ $subsections hence }
"In the past:"
{ $subsection ago }
{ $subsections ago }
"Invert a duration:"
{ $subsection before }
{ $subsections before }
"Days of the week relative to " { $link now } ":"
{ $subsection sunday }
{ $subsection monday }
{ $subsection tuesday }
{ $subsection wednesday }
{ $subsection thursday }
{ $subsection friday }
{ $subsection saturday }
{ $subsections
sunday
monday
tuesday
wednesday
thursday
friday
saturday
}
"New timestamps relative to calendar events:"
{ $subsection beginning-of-year }
{ $subsection beginning-of-month }
{ $subsection beginning-of-week }
{ $subsection midnight }
{ $subsection noon }
;
{ $subsections
beginning-of-year
beginning-of-month
beginning-of-week
midnight
noon
} ;
ARTICLE: "days" "Day operations"
"Naming days:"
{ $subsection day-abbreviation2 }
{ $subsection day-abbreviations2 }
{ $subsection day-abbreviation3 }
{ $subsection day-abbreviations3 }
{ $subsection day-name }
{ $subsection day-names }
{ $subsections
day-abbreviation2
day-abbreviations2
day-abbreviation3
day-abbreviations3
day-name
day-names
}
"Calculating a Julian day number:"
{ $subsection julian-day-number }
{ $subsections julian-day-number }
"Calculate a timestamp:"
{ $subsection julian-day-number>date }
;
{ $subsections julian-day-number>date } ;
ARTICLE: "calendar-facts" "Calendar facts"
"Calendar facts:"
{ $subsection average-month }
{ $subsection months-per-year }
{ $subsection days-per-year }
{ $subsection hours-per-year }
{ $subsection minutes-per-year }
{ $subsection seconds-per-year }
{ $subsection days-in-month }
{ $subsection day-of-year }
{ $subsection day-of-week }
;
{ $subsections
average-month
months-per-year
days-per-year
hours-per-year
minutes-per-year
seconds-per-year
days-in-month
day-of-year
day-of-week
} ;
ARTICLE: "years" "Year operations"
"Leap year predicate:"
{ $subsection leap-year? }
{ $subsections leap-year? }
"Find the number of days in a year:"
{ $subsection days-in-year }
;
{ $subsections days-in-year } ;
ARTICLE: "months" "Month operations"
"Naming months:"
{ $subsection month-name }
{ $subsection month-names }
{ $subsection month-abbreviation }
{ $subsection month-abbreviations }
;
{ $subsections
month-name
month-names
month-abbreviation
month-abbreviations
} ;
ABOUT: "calendar"

View File

@ -37,10 +37,10 @@ HELP: from
ARTICLE: "channels" "Channels"
"The " { $vocab-link "channels" } " vocabulary provides a simple abstraction to send and receive objects." $nl
"Opening a channel:"
{ $subsection <channel> }
{ $subsections <channel> }
"Sending a message:"
{ $subsection to }
{ $subsections to }
"Receiving a message:"
{ $subsection from } ;
{ $subsections from } ;
ABOUT: "channels"

View File

@ -6,6 +6,6 @@ HELP: adler-32
ARTICLE: "checksums.adler-32" "Adler-32 checksum"
"The Adler-32 checksum algorithm implements simple and fast checksum. It is used in zlib and rsync."
{ $subsection adler-32 } ;
{ $subsections adler-32 } ;
ABOUT: "checksums.adler-32"

View File

@ -44,24 +44,29 @@ HELP: fnv1a-1024
ARTICLE: "checksums.fnv1" "Fowler-Noll-Vo checksum"
"The Fowler-Noll-Vo checksum algorithm is another simple and fast checksum. It comes in 32, 64, 128, 256, 512 and 1024-bit versions, each in 1 and 1a variants. The 1a variants tend to produce a slightly better result. See http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash for more details."
{ $subsection fnv1-32 }
{ $subsection fnv1a-32 }
{ $subsection fnv1-64 }
{ $subsection fnv1a-64 }
{ $subsection fnv1-128 }
{ $subsection fnv1a-128 }
{ $subsection fnv1-256 }
{ $subsection fnv1a-256 }
{ $subsection fnv1-512 }
{ $subsection fnv1a-512 }
{ $subsection fnv1-1024 }
{ $subsection fnv1a-1024 }
;
{ $subsections
fnv1-32
fnv1a-32
}
{ $subsections
fnv1-64
fnv1a-64
}
{ $subsections
fnv1-128
fnv1a-128
}
{ $subsections
fnv1-256
fnv1a-256
}
{ $subsections
fnv1-512
fnv1a-512
}
{ $subsections
fnv1-1024
fnv1a-1024
} ;
ABOUT: "checksums.fnv1"

View File

@ -6,6 +6,6 @@ HELP: md5
ARTICLE: "checksums.md5" "MD5 checksum"
"The MD5 checksum algorithm implements a one-way hash function. While it is widely used, many weaknesses are known and it should not be used in new applications (" { $url "http://www.schneier.com/blog/archives/2005/03/more_hash_funct.html" } ")."
{ $subsection md5 } ;
{ $subsections md5 } ;
ABOUT: "checksums.md5"

View File

@ -1,7 +1,8 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: byte-arrays checksums checksums.md5 io.encodings.binary
io.streams.byte-array kernel math namespaces tools.test ;
io.streams.byte-array kernel math namespaces tools.test
sequences ;
IN: checksums.md5.tests
[ "d41d8cd98f00b204e9800998ecf8427e" ] [ "" >byte-array md5 checksum-bytes hex-string ] unit-test
@ -33,3 +34,9 @@ IN: checksums.md5.tests
<md5-state> "asdf" binary <byte-reader> add-checksum-stream
[ get-checksum ] [ get-checksum ] bi =
] unit-test
[
t
] [
{ "abcd" "efg" } md5 checksum-lines length 16 =
] unit-test

View File

@ -21,14 +21,16 @@ HELP: unknown-digest
ARTICLE: "checksums.openssl" "OpenSSL checksums"
"The OpenSSL library provides a large number of efficient checksum (message digest) algorithms which may be used independently of its SSL functionality."
{ $subsection openssl-checksum }
{ $subsections openssl-checksum }
"Constructing a checksum from a known name:"
{ $subsection <openssl-checksum> }
{ $subsections <openssl-checksum> }
"Two utility words:"
{ $subsection openssl-md5 }
{ $subsection openssl-sha1 }
{ $subsections
openssl-md5
openssl-sha1
}
"An error thrown if the digest name is unrecognized:"
{ $subsection unknown-digest }
{ $subsections unknown-digest }
"An example where we compute the SHA1 checksum of a string using the OpenSSL implementation of SHA1:"
{ $example "USING: byte-arrays checksums checksums.openssl ;" "\"hello world\" >byte-array openssl-sha1 checksum-bytes hex-string ." "\"2aae6c35c94fcfb415dbe95f408b9ce91ee846ed\"" }
"If we use the Factor implementation, we get the same result, just slightly slower:"

View File

@ -10,9 +10,11 @@ HELP: sha-256
ARTICLE: "checksums.sha" "SHA-2 checksum"
"The SHA family of checksum algorithms are one-way hashes useful for checksumming data. SHA-1 is considered insecure, while SHA-2 It is generally considered to be pretty strong." $nl
"SHA-2 checksums:"
{ $subsection sha-224 }
{ $subsection sha-256 }
{ $subsections
sha-224
sha-256
}
"SHA-1 checksum:"
{ $subsection sha1 } ;
{ $subsections sha1 } ;
ABOUT: "checksums.sha"

View File

@ -51,14 +51,20 @@ HELP: rotate-circular
ARTICLE: "circular" "Circular sequences"
"The " { $vocab-link "circular" } " vocabulary implements the " { $link "sequence-protocol" } " to allow an arbitrary start index and wrap-around indexing." $nl
"Creating a new circular object:"
{ $subsection <circular> }
{ $subsection <circular-string> }
{ $subsection <growing-circular> }
{ $subsections
<circular>
<circular-string>
<growing-circular>
}
"Changing the start index:"
{ $subsection change-circular-start }
{ $subsection rotate-circular }
{ $subsections
change-circular-start
rotate-circular
}
"Pushing new elements:"
{ $subsection push-circular }
{ $subsection push-growing-circular } ;
{ $subsections
push-circular
push-growing-circular
} ;
ABOUT: "circular"

View File

@ -120,21 +120,25 @@ ARTICLE: "classes.struct.examples" "Struct class examples"
ARTICLE: "classes.struct.define" "Defining struct classes"
"Struct classes are defined using a syntax similar to the " { $link POSTPONE: TUPLE: } " syntax for defining tuple classes:"
{ $subsection POSTPONE: STRUCT: }
{ $subsections POSTPONE: STRUCT: }
"Union structs are also supported, which behave like structs but share the same memory for all the slots."
{ $subsection POSTPONE: UNION-STRUCT: } ;
{ $subsections POSTPONE: UNION-STRUCT: } ;
ARTICLE: "classes.struct.create" "Creating instances of structs"
"Structs can be allocated with " { $link new } "- and " { $link boa } "-like constructor words. Additional words are provided for building structs from C memory and from existing buffers:"
{ $subsection <struct> }
{ $subsection <struct-boa> }
{ $subsection malloc-struct }
{ $subsection memory>struct }
{ $subsections
<struct>
<struct-boa>
malloc-struct
memory>struct
}
"When the contents of a struct will be immediately reset, faster primitive words are available that will create a struct without initializing its contents:"
{ $subsection (struct) }
{ $subsection (malloc-struct) }
{ $subsections
(struct)
(malloc-struct)
}
"Structs have literal syntax, similar to " { $link POSTPONE: T{ } " for tuples:"
{ $subsection POSTPONE: S{ } ;
{ $subsections POSTPONE: S{ } ;
ARTICLE: "classes.struct.c" "Passing structs to C functions"
"Structs can be passed and returned by value, or by reference."
@ -164,9 +168,11 @@ $nl
ARTICLE: "classes.struct" "Struct classes"
"The " { $vocab-link "classes.struct" } " vocabulary implements " { $link struct } " classes. They are similar to " { $link tuple } " classes, but their slots exhibit value semantics, and they are backed by a contiguous structured block of memory. Structs can be used for space-efficient storage of data in the Factor heap, as well as for passing data to and from C libraries using the " { $link "alien" } "."
{ $subsection "classes.struct.examples" }
{ $subsection "classes.struct.define" }
{ $subsection "classes.struct.create" }
{ $subsection "classes.struct.c" } ;
{ $subsections
"classes.struct.examples"
"classes.struct.define"
"classes.struct.create"
"classes.struct.c"
} ;
ABOUT: "classes.struct"

View File

@ -41,14 +41,18 @@ HELP: objc-error
ARTICLE: "cocoa-application-utils" "Cocoa application utilities"
"Utilities:"
{ $subsection NSApp }
{ $subsection add-observer }
{ $subsection remove-observer }
{ $subsection install-delegate }
{ $subsections
NSApp
add-observer
remove-observer
install-delegate
}
"Combinators:"
{ $subsection cocoa-app }
{ $subsection with-autorelease-pool }
{ $subsection with-cocoa } ;
{ $subsections
cocoa-app
with-autorelease-pool
with-cocoa
} ;
IN: cocoa.application
ABOUT: "cocoa-application-utils"

View File

@ -25,15 +25,19 @@ HELP: IMPORT:
ARTICLE: "objc-calling" "Calling Objective C code"
"Before an Objective C class can be used, it must be imported; by default, a small set of common classes are imported automatically, but additional classes can be imported as needed."
{ $subsection POSTPONE: IMPORT: }
{ $subsections POSTPONE: IMPORT: }
"Every imported Objective C class has as corresponding class word in the " { $vocab-link "cocoa.classes" } " vocabulary. Class words push the class object in the stack, allowing class methods to be invoked."
$nl
"Messages can be sent to classes and instances using a pair of parsing words:"
{ $subsection POSTPONE: -> }
{ $subsection POSTPONE: SUPER-> }
{ $subsections
POSTPONE: ->
POSTPONE: SUPER->
}
"These parsing words are actually syntax sugar for a pair of ordinary words; they can be used instead of the parsing words if the selector name is dynamically computed:"
{ $subsection send }
{ $subsection super-send } ;
{ $subsections
send
super-send
} ;
ARTICLE: "cocoa" "Cocoa bridge"
"The " { $vocab-link "cocoa" } " vocabulary implements a Factor-Cocoa bridge for Mac OS X (GNUstep is not supported)."
@ -41,14 +45,18 @@ $nl
"The lowest layer uses the " { $link "alien" } " to define bindings for the various functions in Apple's Objective-C runtime. This is defined in the " { $vocab-link "cocoa.runtime" } " vocabulary."
$nl
"On top of this, a dynamic message send facility is built:"
{ $subsection "objc-calling" }
{ $subsection "objc-subclassing" }
{ $subsections
"objc-calling"
"objc-subclassing"
}
"A utility library is built to faciliate the development of Cocoa applications in Factor:"
{ $subsection "cocoa-application-utils" }
{ $subsection "cocoa-dialogs" }
{ $subsection "cocoa-pasteboard-utils" }
{ $subsection "cocoa-view-utils" }
{ $subsection "cocoa-window-utils" } ;
{ $subsections
"cocoa-application-utils"
"cocoa-dialogs"
"cocoa-pasteboard-utils"
"cocoa-view-utils"
"cocoa-window-utils"
} ;
IN: cocoa
ABOUT: "cocoa"

View File

@ -19,11 +19,15 @@ HELP: save-panel
ARTICLE: "cocoa-dialogs" "Cocoa file dialogs"
"Open dialogs:"
{ $subsection <NSOpenPanel> }
{ $subsection open-panel }
{ $subsections
<NSOpenPanel>
open-panel
}
"Save dialogs:"
{ $subsection <NSSavePanel> }
{ $subsection save-panel } ;
{ $subsections
<NSSavePanel>
save-panel
} ;
IN: cocoa.dialogs
ABOUT: "cocoa-dialogs"

View File

@ -14,9 +14,11 @@ HELP: set-pasteboard-string
{ $description "Sets the contents of the pasteboard." } ;
ARTICLE: "cocoa-pasteboard-utils" "Cocoa pasteboard utilities"
{ $subsection pasteboard-string? }
{ $subsection pasteboard-string }
{ $subsection set-pasteboard-string } ;
{ $subsections
pasteboard-string?
pasteboard-string
set-pasteboard-string
} ;
IN: cocoa.pasteboard
ABOUT: "cocoa-pasteboard-utils"

View File

@ -37,9 +37,9 @@ HELP: CLASS:
ARTICLE: "objc-subclassing" "Subclassing Objective C classes"
"Objective C classes can be subclassed, with new methods defined in Factor, using a parsing word:"
{ $subsection POSTPONE: CLASS: }
{ $subsections POSTPONE: CLASS: }
"This word is actually syntax sugar for an ordinary word:"
{ $subsection define-objc-class }
{ $subsections define-objc-class }
"Objective C class definitions are saved in the image. If the image is saved and Factor is restarted with the saved image, custom class definitions are made available to the Objective C runtime when they are first accessed from within Factor." ;
IN: cocoa.subclassing

View File

@ -14,9 +14,11 @@ HELP: mouse-location
{ $description "Outputs the current mouse location." } ;
ARTICLE: "cocoa-view-utils" "Cocoa view utilities"
{ $subsection <GLView> }
{ $subsection view-dim }
{ $subsection mouse-location } ;
{ $subsections
<GLView>
view-dim
mouse-location
} ;
IN: cocoa.views
ABOUT: "cocoa-view-utils"

View File

@ -10,8 +10,10 @@ HELP: <ViewWindow>
{ $description "Creates a new " { $snippet "NSWindow" } " with the specified dimensions, containing the given view." } ;
ARTICLE: "cocoa-window-utils" "Cocoa window utilities"
{ $subsection <NSWindow> }
{ $subsection <ViewWindow> } ;
{ $subsections
<NSWindow>
<ViewWindow>
} ;
IN: cocoa.windows
ABOUT: "cocoa-window-utils"

View File

@ -13,7 +13,7 @@ HELP: >rgba
ARTICLE: "colors.protocol" "Color protocol"
"Abstract superclass for colors:"
{ $subsection color }
{ $subsections color }
"All color objects must are required to implement a method on the " { $link >rgba } " generic word."
$nl
"Optionally, they can provide methods on the accessors " { $link red>> } ", " { $link green>> } ", " { $link blue>> } " and " { $link alpha>> } ", either by defining slots with the appropriate names, or with methods which calculate the color component values. The accessors should return color components which are real numbers in the range between 0 and 1."
@ -24,15 +24,19 @@ ARTICLE: "colors" "Colors"
"The " { $vocab-link "colors" } " vocabulary defines a protocol for colors, with a concrete implementation for RGBA colors. This vocabulary is used by " { $vocab-link "io.styles" } ", " { $vocab-link "ui" } " and other vocabularies, but it is independent of them."
$nl
"RGBA colors with floating point components in the range " { $snippet "[0,1]" } ":"
{ $subsection rgba }
{ $subsection <rgba> }
{ $subsections
rgba
<rgba>
}
"Converting a color to RGBA:"
{ $subsection >rgba }
{ $subsections >rgba }
"Extracting RGBA components of colors:"
{ $subsection >rgba-components }
{ $subsections >rgba-components }
"Further topics:"
{ $subsection "colors.protocol" }
{ $subsection "colors.constants" }
{ $subsections
"colors.protocol"
"colors.constants"
}
{ $vocab-subsection "Grayscale colors" "colors.gray" }
{ $vocab-subsection "HSV colors" "colors.hsv" } ;

View File

@ -24,8 +24,10 @@ HELP: COLOR:
ARTICLE: "colors.constants" "Standard color database"
"The " { $vocab-link "colors.constants" } " vocabulary bundles the X11 " { $snippet "rgb.txt" } " database and Factor's " { $snippet "factor-colors.txt" } " theme database to provide words for looking up color values by name."
{ $subsection named-color }
{ $subsection named-colors }
{ $subsection POSTPONE: COLOR: } ;
{ $subsections
named-color
named-colors
POSTPONE: COLOR:
} ;
ABOUT: "colors.constants"

View File

@ -3,7 +3,9 @@ IN: colors.gray
ARTICLE: "colors.gray" "Grayscale colors"
"The " { $vocab-link "colors.gray" } " vocabulary implements grayscale colors. These colors hold a single value, and respond to " { $link red>> } ", " { $link green>> } ", " { $link blue>> } " with that value. They also have an independent alpha channel, " { $link alpha>> } "."
{ $subsection gray }
{ $subsection <gray> } ;
{ $subsections
gray
<gray>
} ;
ABOUT: "colors.gray"

View File

@ -6,8 +6,10 @@ HELP: hsva
ARTICLE: "colors.hsv" "HSV colors"
"The " { $vocab-link "colors.hsv" } " vocabulary implements colors specified by their hue, saturation, and value, together with an alpha channel."
{ $subsection hsva }
{ $subsection <hsva> }
{ $subsections
hsva
<hsva>
}
{ $see-also "colors" } ;
ABOUT: "colors.hsv"

View File

@ -25,9 +25,11 @@ HELP: <flipped>
ARTICLE: "columns" "Column sequences"
"A " { $emphasis "column" } " presents a column of a matrix represented as a sequence of rows:"
{ $subsection column }
{ $subsection <column> }
{ $subsections
column
<column>
}
"A utility word:"
{ $subsection <flipped> } ;
{ $subsections <flipped> } ;
ABOUT: "columns"

View File

@ -51,18 +51,24 @@ HELP: n||
ARTICLE: "combinators.short-circuit" "Short-circuit combinators"
"The " { $vocab-link "combinators.short-circuit" } " vocabulary stops a computation early once a condition is met." $nl
"AND combinators:"
{ $subsection 0&& }
{ $subsection 1&& }
{ $subsection 2&& }
{ $subsection 3&& }
{ $subsections
0&&
1&&
2&&
3&&
}
"OR combinators:"
{ $subsection 0|| }
{ $subsection 1|| }
{ $subsection 2|| }
{ $subsection 3|| }
{ $subsections
0||
1||
2||
3||
}
"Generalized combinators:"
{ $subsection n&& }
{ $subsection n|| }
{ $subsections
n&&
n||
}
;
ABOUT: "combinators.short-circuit"

View File

@ -31,8 +31,8 @@ ARTICLE: "combinators.short-circuit.smart" "Smart short-circuit combinators"
"The " { $vocab-link "combinators.short-circuit.smart" } " vocabulary is similar to " { $vocab-link "combinators.short-circuit" } " except the combinators here infer the number of inputs that the sequence of quotations takes."
$nl
"Generalized AND:"
{ $subsection && }
{ $subsections && }
"Generalized OR:"
{ $subsection || } ;
{ $subsections || } ;
ABOUT: "combinators.short-circuit.smart"

View File

@ -119,20 +119,26 @@ HELP: keep-inputs
ARTICLE: "combinators.smart" "Smart combinators"
"A " { $emphasis "smart combinator" } " is a macro which reflects on the stack effect of an input quotation. The " { $vocab-link "combinators.smart" } " vocabulary implements a few simple smart combinators which look at the static stack effects of input quotations and generate code which produces or consumes the relevant number of stack values." $nl
"Call a quotation and discard all output values or preserve all input values:"
{ $subsection drop-outputs }
{ $subsection keep-inputs }
{ $subsections
drop-outputs
keep-inputs
}
"Take all input values from a sequence:"
{ $subsection input<sequence }
{ $subsections input<sequence }
"Store all output values to a sequence:"
{ $subsection output>sequence }
{ $subsection output>array }
{ $subsections
output>sequence
output>array
}
"Reducing the set of output values:"
{ $subsection reduce-outputs }
{ $subsections reduce-outputs }
"Summing output values:"
{ $subsection sum-outputs }
{ $subsections sum-outputs }
"Concatenating output values:"
{ $subsection append-outputs }
{ $subsection append-outputs-as }
{ $subsections
append-outputs
append-outputs-as
}
"New smart combinators can be created by defining " { $link "macros" } " which call " { $link infer } "." ;
ABOUT: "combinators.smart"

View File

@ -25,7 +25,7 @@ HELP: (command-line)
{ $description "Outputs the command line parameters which were passed to the Factor VM on startup." } ;
HELP: command-line
{ $var-description "The command line parameters which follow the name of the script on the command line." } ;
{ $var-description "When Factor is run with a script, this variable contains command line parameters which follow the name of the script on the command line. In deployed applications, it contains the entire command line. In all other cases it is set to " { $link f } "." } ;
HELP: main-vocab-hook
{ $var-description "Global variable holding a quotation which outputs a vocabulary name. UI backends set this so that the UI can automatically start if the prerequisites are met (for example, " { $snippet "$DISPLAY" } " being set on X11)." } ;
@ -99,26 +99,28 @@ ARTICLE: "factor-boot-rc" "Bootstrap initialization file"
"The botstrap initialization file is named " { $snippet "factor-boot-rc" } " on Windows and " { $snippet ".factor-boot-rc" } " on Unix. This file can contain " { $link require } " calls for vocabularies you use frequently, and other such long-running tasks that you do not want to perform every time Factor starts."
$nl
"A word to run this file from an existing Factor session:"
{ $subsection run-bootstrap-init }
{ $subsections run-bootstrap-init }
"For example, if you changed " { $snippet ".factor-boot-rc" } " and do not want to bootstrap again, you can just invoke " { $link run-bootstrap-init } " in the listener." ;
ARTICLE: "factor-rc" "Startup initialization file"
"The startup initialization file is named " { $snippet "factor-rc" } " on Windows and " { $snippet ".factor-rc" } " on Unix. If it exists, it is run every time Factor starts."
$nl
"A word to run this file from an existing Factor session:"
{ $subsection run-user-init } ;
{ $subsections run-user-init } ;
ARTICLE: "factor-roots" "Additional vocabulary roots file"
"The vocabulary roots file is named " { $snippet "factor-roots" } " on Windows and " { $snippet ".factor-roots" } " on Unix. If it exists, it is loaded every time Factor starts. It contains a newline-separated list of " { $link "vocabs.roots" } "."
$nl
"A word to run this file from an existing Factor session:"
{ $subsection load-vocab-roots } ;
{ $subsections load-vocab-roots } ;
ARTICLE: "rc-files" "Running code on startup"
"Factor looks for three optional files in your home directory."
{ $subsection "factor-boot-rc" }
{ $subsection "factor-rc" }
{ $subsection "factor-roots" }
{ $subsections
"factor-boot-rc"
"factor-rc"
"factor-roots"
}
"The " { $snippet "-no-user-init" } " command line switch will inhibit loading running of these files."
$nl
"If you are unsure where the files should be located, evaluate the following code:"
@ -127,19 +129,17 @@ $nl
"\"factor-rc\" rc-path print"
"\"factor-boot-rc\" rc-path print"
}
"Here is an example " { $snippet ".factor-boot-rc" } " which sets up GVIM editor integration, adds an additional vocabulary root (see " { $link "vocabs.roots" } "), and increases the font size in the UI by setting the DPI (dots-per-inch) variable:"
"Here is an example " { $snippet ".factor-boot-rc" } " which sets up GVIM editor integration:"
{ $code
"USING: editors.gvim vocabs.loader ui.freetype namespaces sequences ;"
"USING: editors.gvim namespaces ;"
"\"/opt/local/bin\" \\ gvim-path set-global"
"\"/home/jane/src/\" vocab-roots get push"
"100 dpi set-global"
} ;
ARTICLE: "cli" "Command line arguments"
"Factor command line usage:"
{ $code "factor [system switches...] [script args...]" }
"Zero or more system switches can be passed in, followed by an optional script file name. If the script file is specified, it will be run on startup, any arguments after the script file are stored in a variable, with no further processing by Factor itself:"
{ $subsection command-line }
{ $code "factor [VM args...] [script] [args...]" }
"Zero or more VM arguments can be passed in, followed by an optional script file name. If the script file is specified, it will be run on startup, any arguments after the script file are stored in the following variable, with no further processing by Factor itself:"
{ $subsections command-line }
"Instead of running a script, it is also possible to run a vocabulary; this invokes the vocabulary's " { $link POSTPONE: MAIN: } " word:"
{ $code "factor [system switches...] -run=<vocab name>" }
"If no script file or " { $snippet "-run=" } " switch is specified, Factor will start " { $link "listener" } " or " { $link "ui-tools" } ", depending on the operating system."
@ -152,12 +152,14 @@ $nl
{ { $snippet "-no-" { $emphasis "foo" } } " - sets the global variable " { $snippet "\"" { $emphasis "foo" } "\"" } " to " { $link f } }
{ { $snippet "-" { $emphasis "foo" } "=" { $emphasis "bar" } } " - sets the global variable " { $snippet "\"" { $emphasis "foo" } "\"" } " to " { $snippet "\"" { $emphasis "bar" } "\"" } }
}
{ $subsection "runtime-cli-args" }
{ $subsection "bootstrap-cli-args" }
{ $subsection "standard-cli-args" }
{ $subsections
"runtime-cli-args"
"bootstrap-cli-args"
"standard-cli-args"
}
"The raw list of command line arguments can also be obtained and inspected directly:"
{ $subsection (command-line) }
{ $subsections (command-line) }
"There is a way to override the default vocabulary to run on startup, if no script name or " { $snippet "-run" } " switch is specified:"
{ $subsection main-vocab-hook } ;
{ $subsections main-vocab-hook } ;
ABOUT: "cli"

View File

@ -1,10 +1,17 @@
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math namespaces assocs hashtables sequences arrays
accessors vectors combinators sets classes cpu.architecture
compiler.cfg compiler.cfg.registers compiler.cfg.instructions
compiler.cfg.def-use compiler.cfg.copy-prop compiler.cfg.rpo
compiler.cfg.liveness ;
accessors words vectors combinators combinators.short-circuit
sets classes layouts cpu.architecture
compiler.cfg
compiler.cfg.rpo
compiler.cfg.def-use
compiler.cfg.liveness
compiler.cfg.copy-prop
compiler.cfg.registers
compiler.cfg.comparisons
compiler.cfg.instructions
compiler.cfg.representations.preferred ;
IN: compiler.cfg.alias-analysis
! We try to eliminate redundant slot operations using some simple heuristics.
@ -77,10 +84,15 @@ SYMBOL: acs>vregs
: ac>vregs ( ac -- vregs ) acs>vregs get at ;
: aliases ( vreg -- vregs )
GENERIC: aliases ( vreg -- vregs )
M: integer aliases
#! All vregs which may contain the same value as vreg.
vreg>ac ac>vregs ;
M: word aliases
1array ;
: each-alias ( vreg quot -- )
[ aliases ] dip each ; inline
@ -181,7 +193,6 @@ SYMBOL: constants
#! assigned by an ##load-immediate.
resolve constants get at ;
! We treat slot accessors and stack traffic alike
GENERIC: insn-slot# ( insn -- slot#/f )
GENERIC: insn-object ( insn -- vreg )
@ -190,7 +201,7 @@ M: ##slot-imm insn-slot# slot>> ;
M: ##set-slot insn-slot# slot>> constant ;
M: ##set-slot-imm insn-slot# slot>> ;
M: ##alien-global insn-slot# [ library>> ] [ symbol>> ] bi 2array ;
M: ##vm-field-ptr insn-slot# field-name>> ; ! is this right?
M: ##vm-field-ptr insn-slot# field-name>> ;
M: ##slot insn-object obj>> resolve ;
M: ##slot-imm insn-object obj>> resolve ;
@ -206,18 +217,33 @@ M: ##vm-field-ptr insn-object drop \ ##vm-field-ptr ;
H{ } clone live-slots set
H{ } clone constants set
H{ } clone copies set
0 ac-counter set
next-ac heap-ac set
\ ##vm-field-ptr set-new-ac
\ ##alien-global set-new-ac
dup local-live-in [ set-heap-ac ] each ;
GENERIC: analyze-aliases* ( insn -- insn' )
M: insn analyze-aliases*
dup defs-vreg [ set-heap-ac ] when* ;
! If an instruction defines a value with a non-integer
! representation it means that the value will be boxed
! anywhere its used as a tagged pointer. Boxing allocates
! a new value, except boxing instructions haven't been
! inserted yet.
dup defs-vreg [
over defs-vreg-rep int-rep eq?
[ set-heap-ac ] [ set-new-ac ] if
] when* ;
M: ##phi analyze-aliases*
dup defs-vreg set-heap-ac ;
M: ##load-immediate analyze-aliases*
call-next-method
dup [ val>> ] [ dst>> ] bi constants get set-at ;
M: ##allocation analyze-aliases*
@ -249,6 +275,19 @@ M: ##copy analyze-aliases*
#! vreg, since they both contain the same value.
dup record-copy ;
: useless-compare? ( insn -- ? )
{
[ cc>> cc= eq? ]
[ [ src1>> ] [ src2>> ] bi [ resolve vreg>ac ] bi@ = not ]
} 1&& ; inline
M: ##compare analyze-aliases*
call-next-method
dup useless-compare? [
dst>> \ f tag-number \ ##load-immediate new-insn
analyze-aliases*
] when ;
: analyze-aliases ( insns -- insns' )
[ insn# set analyze-aliases* ] map-index sift ;

View File

@ -159,9 +159,12 @@ IN: compiler.cfg.builder.tests
{ pinned-c-ptr class fixnum } \ set-alien-cell '[ _ declare _ execute ] unit-test-cfg
] each
: contains-insn? ( quot insn-check -- ? )
: count-insns ( quot insn-check -- ? )
[ test-mr [ instructions>> ] map ] dip
'[ _ any? ] any? ; inline
'[ _ count ] sigma ; inline
: contains-insn? ( quot insn-check -- ? )
count-insns 0 > ; inline
[ t ] [ [ swap ] [ ##replace? ] contains-insn? ] unit-test
@ -197,14 +200,16 @@ IN: compiler.cfg.builder.tests
[ f t ] [
[ { byte-array fixnum } declare alien-cell 4 alien-float ]
[ [ ##box-alien? ] contains-insn? ]
[ [ ##box-float? ] contains-insn? ] bi
[ [ ##allot? ] contains-insn? ] bi
] unit-test
[ f t ] [
[ { byte-array fixnum } declare alien-cell { simple-alien } declare 4 alien-float ]
[ [ ##box-alien? ] contains-insn? ]
[ [ ##box-float? ] contains-insn? ] bi
[ [ ##allot? ] contains-insn? ] bi
] unit-test
[ 1 ] [ [ dup float+ ] [ ##alien-double? ] count-insns ] unit-test
] when
! Regression. Make sure everything is inlined correctly

View File

@ -9,6 +9,9 @@ SYMBOLS:
cc< cc<= cc= cc> cc>= cc<> cc<>=
cc/< cc/<= cc/= cc/> cc/>= cc/<> cc/<>= ;
SYMBOLS:
vcc-all vcc-notall vcc-any vcc-none ;
: negate-cc ( cc -- cc' )
H{
{ cc< cc/< }
@ -27,6 +30,14 @@ SYMBOLS:
{ cc/<>= cc<>= }
} at ;
: negate-vcc ( cc -- cc' )
H{
{ vcc-all vcc-notall }
{ vcc-any vcc-none }
{ vcc-none vcc-any }
{ vcc-notall vcc-all }
} at ;
: swap-cc ( cc -- cc' )
H{
{ cc< cc> }

View File

@ -16,7 +16,7 @@ V{
} 0 test-bb
V{
T{ ##box-float f 0 1 }
T{ ##box-alien f 0 1 }
} 1 test-bb
0 1 edge

View File

@ -49,24 +49,9 @@ insn-classes get [
[ ##load-reference ]
} cond ;
: ^^unbox-c-ptr ( src class -- dst )
[ next-vreg dup ] 2dip next-vreg ##unbox-c-ptr ;
: ^^allot-tuple ( n -- dst )
2 + cells tuple ^^allot ;
: ^^allot-array ( n -- dst )
2 + cells array ^^allot ;
: ^^allot-byte-array ( n -- dst )
2 cells + byte-array ^^allot ;
: ^^offset>slot ( slot -- vreg' )
cell 4 = [ 1 ^^shr-imm ] [ any-rep ^^copy ] if ;
: ^^tag-offset>slot ( slot tag -- vreg' )
[ ^^offset>slot ] dip ^^sub-imm ;
: ^^tag-fixnum ( src -- dst )
tag-bits get ^^shl-imm ;

View File

@ -199,15 +199,6 @@ def: dst/int-rep
use: src/int-rep ;
! Float arithmetic
PURE-INSN: ##unbox-float
def: dst/double-rep
use: src/int-rep ;
PURE-INSN: ##box-float
def: dst/int-rep
use: src/double-rep
temp: temp/int-rep ;
PURE-INSN: ##add-float
def: dst/double-rep
use: src1/double-rep src2/double-rep ;
@ -266,19 +257,11 @@ def: dst/double-rep
use: src/int-rep ;
! SIMD operations
PURE-INSN: ##box-vector
def: dst/int-rep
use: src
literal: rep
temp: temp/int-rep ;
PURE-INSN: ##unbox-vector
PURE-INSN: ##zero-vector
def: dst
use: src/int-rep
literal: rep ;
PURE-INSN: ##zero-vector
PURE-INSN: ##fill-vector
def: dst
literal: rep ;
@ -297,6 +280,29 @@ def: dst
use: src
literal: shuffle rep ;
PURE-INSN: ##compare-vector
def: dst
use: src1 src2
temp: temp
literal: rep cc ;
PURE-INSN: ##test-vector
def: dst/int-rep
use: src1
temp: temp/int-rep
literal: rep vcc ;
INSN: ##test-vector-branch
use: src1
temp: temp/int-rep
literal: rep vcc ;
INSN: _test-vector-branch
literal: label
use: src1
temp: temp/int-rep
literal: rep vcc ;
PURE-INSN: ##add-vector
def: dst
use: src1 src2
@ -402,6 +408,11 @@ def: dst
use: src1 src2
literal: rep ;
PURE-INSN: ##not-vector
def: dst
use: src
literal: rep ;
PURE-INSN: ##shl-vector
def: dst
use: src1 src2/int-scalar-rep
@ -738,13 +749,11 @@ literal: n ;
UNION: ##allocation
##allot
##box-float
##box-vector
##box-alien
##box-displaced-alien ;
! For alias analysis
UNION: ##read ##slot ##slot-imm ;
UNION: ##read ##slot ##slot-imm ##vm-field-ptr ##alien-global ;
UNION: ##write ##set-slot ##set-slot-imm ;
! Instructions that kill all live vregs but cannot trigger GC
@ -766,6 +775,8 @@ UNION: kill-vreg-insn
UNION: def-is-use-insn
##box-alien
##box-displaced-alien
##compare-vector
##not-vector
##string-nth
##unbox-any-c-ptr ;

View File

@ -3,8 +3,9 @@
USING: accessors kernel sequences alien math classes.algebra fry
locals combinators combinators.short-circuit cpu.architecture
compiler.tree.propagation.info compiler.cfg.hats
compiler.cfg.stacks compiler.cfg.instructions
compiler.cfg.utilities compiler.cfg.builder.blocks ;
compiler.cfg.registers compiler.cfg.stacks
compiler.cfg.instructions compiler.cfg.utilities
compiler.cfg.builder.blocks ;
IN: compiler.cfg.intrinsics.alien
: emit-<displaced-alien>? ( node -- ? )
@ -33,6 +34,9 @@ IN: compiler.cfg.intrinsics.alien
[ second class>> fixnum class<= ]
bi and ;
: ^^unbox-c-ptr ( src class -- dst )
[ next-vreg dup ] 2dip next-vreg ##unbox-c-ptr ;
: prepare-alien-accessor ( info -- ptr-vreg offset )
class>> [ 2inputs ^^untag-fixnum swap ] dip ^^unbox-c-ptr ^^add 0 ;

View File

@ -18,6 +18,9 @@ IN: compiler.cfg.intrinsics.allot
: tuple-slot-regs ( layout -- vregs )
[ second ds-load ] [ ^^load-literal ] bi prefix ;
: ^^allot-tuple ( n -- dst )
2 + cells tuple ^^allot ;
: emit-<tuple-boa> ( node -- )
dup node-input-infos last literal>>
dup array? [
@ -36,6 +39,9 @@ IN: compiler.cfg.intrinsics.allot
: expand-<array>? ( obj -- ? )
dup integer? [ 0 8 between? ] [ drop f ] if ;
: ^^allot-array ( n -- dst )
2 + cells array ^^allot ;
:: emit-<array> ( node -- )
[let | len [ node node-input-infos first literal>> ] |
len expand-<array>? [
@ -54,6 +60,9 @@ IN: compiler.cfg.intrinsics.allot
: bytes>cells ( m -- n ) cell align cell /i ;
: ^^allot-byte-array ( n -- dst )
2 cells + byte-array ^^allot ;
: emit-allot-byte-array ( len -- dst )
ds-drop
dup ^^allot-byte-array

View File

@ -171,6 +171,21 @@ IN: compiler.cfg.intrinsics
{ math.vectors.simd.intrinsics:(simd-vbitandn) [ [ ^^andn-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vbitor) [ [ ^^or-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vbitxor) [ [ ^^xor-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vbitnot) [ [ ^^not-vector ] emit-unary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vand) [ [ ^^and-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vandn) [ [ ^^andn-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vor) [ [ ^^or-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vxor) [ [ ^^xor-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vnot) [ [ ^^not-vector ] emit-unary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-v<=) [ [ cc<= ^^compare-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-v<) [ [ cc< ^^compare-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-v=) [ [ cc= ^^compare-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-v>) [ [ cc> ^^compare-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-v>=) [ [ cc>= ^^compare-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vunordered?) [ [ cc/<>= ^^compare-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vany?) [ [ vcc-any ^^test-vector ] emit-unary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vall?) [ [ vcc-all ^^test-vector ] emit-unary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vnone?) [ [ vcc-none ^^test-vector ] emit-unary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vlshift) [ [ ^^shl-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-vrshift) [ [ ^^shr-vector ] emit-binary-vector-op ] }
{ math.vectors.simd.intrinsics:(simd-hlshift) [ [ ^^horizontal-shl-vector ] emit-horizontal-shift ] }

View File

@ -8,6 +8,9 @@ IN: compiler.cfg.intrinsics.slots
: value-tag ( info -- n ) class>> class-tag ; inline
: ^^tag-offset>slot ( slot tag -- vreg' )
[ ^^offset>slot ] dip ^^sub-imm ;
: (emit-slot) ( infos -- dst )
[ 2inputs ] [ first value-tag ] bi*
^^tag-offset>slot ^^slot ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math accessors sequences namespaces make
combinators assocs arrays locals layouts hashtables
cpu.architecture
cpu.architecture generalizations
compiler.cfg
compiler.cfg.comparisons
compiler.cfg.stack-frame
@ -42,14 +42,26 @@ M: ##branch linearize-insn
: successors ( bb -- first second ) successors>> first2 ; inline
:: conditional ( bb insn n conditional-quot negate-cc-quot -- bb successor label ... )
bb insn
conditional-quot
[ drop dup successors>> second useless-branch? ] 2bi
[ [ swap block-number ] n ndip ]
[ [ block-number ] n ndip negate-cc-quot call ] if ; inline
: (binary-conditional) ( bb insn -- bb successor1 successor2 src1 src2 cc )
[ dup successors ]
[ [ src1>> ] [ src2>> ] [ cc>> ] tri ] bi* ; inline
: binary-conditional ( bb insn -- bb successor label2 src1 src2 cc )
[ (binary-conditional) ]
[ drop dup successors>> second useless-branch? ] 2bi
[ [ swap block-number ] 3dip ] [ [ block-number ] 3dip negate-cc ] if ;
3 [ (binary-conditional) ] [ negate-cc ] conditional ;
: (test-vector-conditional) ( bb insn -- bb successor1 successor2 src1 temp rep vcc )
[ dup successors ]
[ { [ src1>> ] [ temp>> ] [ rep>> ] [ vcc>> ] } cleave ] bi* ; inline
: test-vector-conditional ( bb insn -- bb successor label src1 temp rep vcc )
4 [ (test-vector-conditional) ] [ negate-vcc ] conditional ;
M: ##compare-branch linearize-insn
binary-conditional _compare-branch emit-branch ;
@ -63,6 +75,9 @@ M: ##compare-float-ordered-branch linearize-insn
M: ##compare-float-unordered-branch linearize-insn
binary-conditional _compare-float-unordered-branch emit-branch ;
M: ##test-vector-branch linearize-insn
test-vector-conditional _test-vector-branch emit-branch ;
: overflow-conditional ( bb insn -- bb successor label2 dst src1 src2 )
[ dup successors block-number ]
[ [ dst>> ] [ src1>> ] [ src2>> ] tri ] bi* ; inline

View File

@ -1,8 +1,10 @@
! Copyright (C) 2009 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
USING: kernel fry accessors sequences assocs sets namespaces
arrays combinators combinators.short-circuit make locals deques
dlists layouts cpu.architecture compiler.utilities
arrays combinators combinators.short-circuit math make locals
deques dlists layouts byte-arrays cpu.architecture
compiler.utilities
compiler.constants
compiler.cfg
compiler.cfg.rpo
compiler.cfg.hats
@ -25,24 +27,31 @@ GENERIC: emit-unbox ( dst src rep -- )
M:: float-rep emit-box ( dst src rep -- )
double-rep next-vreg-rep :> temp
temp src ##single>double-float
dst temp int-rep next-vreg-rep ##box-float ;
dst temp double-rep emit-box ;
M:: float-rep emit-unbox ( dst src rep -- )
double-rep next-vreg-rep :> temp
temp src ##unbox-float
temp src double-rep emit-unbox
dst temp ##double>single-float ;
M: double-rep emit-box
drop int-rep next-vreg-rep ##box-float ;
drop
[ drop 16 float int-rep next-vreg-rep ##allot ]
[ float-offset swap ##set-alien-double ]
2bi ;
M: double-rep emit-unbox
drop ##unbox-float ;
drop float-offset ##alien-double ;
M: vector-rep emit-box
int-rep next-vreg-rep ##box-vector ;
M:: vector-rep emit-box ( dst src rep -- )
int-rep next-vreg-rep :> temp
dst 16 2 cells + byte-array int-rep next-vreg-rep ##allot
temp 16 tag-fixnum ##load-immediate
temp dst 1 byte-array tag-number ##set-slot-imm
dst byte-array-offset src rep ##set-alien-vector ;
M: vector-rep emit-unbox
##unbox-vector ;
[ byte-array-offset ] dip ##alien-vector ;
M:: scalar-rep emit-box ( dst src rep -- )
int-rep next-vreg-rep :> temp
@ -143,6 +152,9 @@ SYMBOL: costs
! Insert conversions. This introduces new temporaries, so we need
! to rename opearands too.
! Mapping from vreg,rep pairs to vregs
SYMBOL: alternatives
:: emit-def-conversion ( dst preferred required -- new-dst' )
! If an instruction defines a register with representation 'required',
! but the register has preferred representation 'preferred', then
@ -155,7 +167,13 @@ SYMBOL: costs
! but the register has preferred representation 'preferred', then
! we rename the instruction's input to a new register, which
! becomes the output of a conversion instruction.
required next-vreg-rep [ src required preferred emit-conversion ] keep ;
preferred required eq? [ src ] [
src required alternatives get [
required next-vreg-rep :> new-src
[ new-src ] 2dip preferred emit-conversion
new-src
] 2cache
] if ;
SYMBOLS: renaming-set needs-renaming? ;
@ -236,6 +254,7 @@ M: insn conversions-for-insn , ;
dup kill-block? [ drop ] [
[
[
H{ } clone alternatives set
[ conversions-for-insn ] each
] V{ } make
] change-instructions drop

View File

@ -40,6 +40,7 @@ M: insn rewrite drop f ;
[ compare-imm-expr? ]
[ compare-float-unordered-expr? ]
[ compare-float-ordered-expr? ]
[ test-vector-expr? ]
} 1|| ;
: rewrite-boolean-comparison? ( insn -- ? )
@ -53,12 +54,21 @@ M: insn rewrite drop f ;
: >compare-imm-expr< ( expr -- in1 in2 cc )
[ src1>> vn>vreg ] [ src2>> vn>constant ] [ cc>> ] tri ; inline
: >test-vector-expr< ( expr -- src1 temp rep vcc )
{
[ src1>> vn>vreg ]
[ drop next-vreg ]
[ rep>> ]
[ vcc>> ]
} cleave ; inline
: rewrite-boolean-comparison ( expr -- insn )
src1>> vreg>expr {
{ [ dup compare-expr? ] [ >compare-expr< \ ##compare-branch new-insn ] }
{ [ dup compare-imm-expr? ] [ >compare-imm-expr< \ ##compare-imm-branch new-insn ] }
{ [ dup compare-float-unordered-expr? ] [ >compare-expr< \ ##compare-float-unordered-branch new-insn ] }
{ [ dup compare-float-ordered-expr? ] [ >compare-expr< \ ##compare-float-ordered-branch new-insn ] }
{ [ dup test-vector-expr? ] [ >test-vector-expr< \ ##test-vector-branch new-insn ] }
} cond ;
: tag-fixnum-expr? ( expr -- ? )

View File

@ -14,6 +14,8 @@ IN: compiler.cfg.value-numbering.tests
[ ##compare-imm? ]
[ ##compare-float-unordered? ]
[ ##compare-float-ordered? ]
[ ##test-vector? ]
[ ##test-vector-branch? ]
} 1|| [ f >>temp ] when
] map ;
@ -107,19 +109,15 @@ IN: compiler.cfg.value-numbering.tests
{
T{ ##peek f 8 D 0 }
T{ ##peek f 9 D -1 }
T{ ##unbox-float f 10 8 }
T{ ##unbox-float f 11 9 }
T{ ##compare-float-unordered f 12 10 11 cc< }
T{ ##compare-float-unordered f 14 10 11 cc/< }
T{ ##compare-float-unordered f 12 8 9 cc< }
T{ ##compare-float-unordered f 14 8 9 cc/< }
T{ ##replace f 14 D 0 }
}
] [
{
T{ ##peek f 8 D 0 }
T{ ##peek f 9 D -1 }
T{ ##unbox-float f 10 8 }
T{ ##unbox-float f 11 9 }
T{ ##compare-float-unordered f 12 10 11 cc< }
T{ ##compare-float-unordered f 12 8 9 cc< }
T{ ##compare-imm f 14 12 5 cc= }
T{ ##replace f 14 D 0 }
} value-numbering-step trim-temps
@ -141,6 +139,20 @@ IN: compiler.cfg.value-numbering.tests
} value-numbering-step trim-temps
] unit-test
[
{
T{ ##peek f 1 D -1 }
T{ ##test-vector f 2 1 f float-4-rep vcc-any }
T{ ##test-vector-branch f 1 f float-4-rep vcc-any }
}
] [
{
T{ ##peek f 1 D -1 }
T{ ##test-vector f 2 1 f float-4-rep vcc-any }
T{ ##compare-imm-branch f 2 5 cc/= }
} value-numbering-step trim-temps
] unit-test
! Immediate operand conversion
[
{

View File

@ -75,7 +75,7 @@ M: insn remove-dead-barrier drop t ;
! Anticipation of this and set-slot would help too, maybe later
FORWARD-ANALYSIS: slot
UNION: access ##read ##write ;
UNION: access ##slot ##slot-imm ##set-slot ##set-slot-imm ;
M: slot-analysis transfer-set
drop [ H{ } assoc-clone-like ] dip

View File

@ -146,8 +146,6 @@ CODEGEN: ##not %not
CODEGEN: ##neg %neg
CODEGEN: ##log2 %log2
CODEGEN: ##copy %copy
CODEGEN: ##unbox-float %unbox-float
CODEGEN: ##box-float %box-float
CODEGEN: ##add-float %add-float
CODEGEN: ##sub-float %sub-float
CODEGEN: ##mul-float %mul-float
@ -161,12 +159,12 @@ CODEGEN: ##single>double-float %single>double-float
CODEGEN: ##double>single-float %double>single-float
CODEGEN: ##integer>float %integer>float
CODEGEN: ##float>integer %float>integer
CODEGEN: ##unbox-vector %unbox-vector
CODEGEN: ##zero-vector %zero-vector
CODEGEN: ##gather-vector-2 %gather-vector-2
CODEGEN: ##gather-vector-4 %gather-vector-4
CODEGEN: ##shuffle-vector %shuffle-vector
CODEGEN: ##box-vector %box-vector
CODEGEN: ##compare-vector %compare-vector
CODEGEN: ##test-vector %test-vector
CODEGEN: ##add-vector %add-vector
CODEGEN: ##saturated-add-vector %saturated-add-vector
CODEGEN: ##add-sub-vector %add-sub-vector
@ -188,6 +186,7 @@ CODEGEN: ##and-vector %and-vector
CODEGEN: ##andn-vector %andn-vector
CODEGEN: ##or-vector %or-vector
CODEGEN: ##xor-vector %xor-vector
CODEGEN: ##not-vector %not-vector
CODEGEN: ##shl-vector %shl-vector
CODEGEN: ##shr-vector %shr-vector
CODEGEN: ##integer>scalar %integer>scalar
@ -233,6 +232,7 @@ CODEGEN: _compare-branch %compare-branch
CODEGEN: _compare-imm-branch %compare-imm-branch
CODEGEN: _compare-float-ordered-branch %compare-float-ordered-branch
CODEGEN: _compare-float-unordered-branch %compare-float-unordered-branch
CODEGEN: _test-vector-branch %test-vector-branch
CODEGEN: _dispatch %dispatch
CODEGEN: _spill %spill
CODEGEN: _reload %reload

View File

@ -12,19 +12,21 @@ HELP: disable-optimizer
ARTICLE: "compiler-usage" "Calling the optimizing compiler"
"Normally, new word definitions are recompiled automatically. This can be changed:"
{ $subsection disable-optimizer }
{ $subsection enable-optimizer }
{ $subsections
disable-optimizer
enable-optimizer
}
"Removing a word's optimized definition:"
{ $subsection decompile }
{ $subsections decompile }
"Compiling a single quotation:"
{ $subsection compile-call }
{ $subsections compile-call }
"Higher-level words can be found in " { $link "compilation-units" } "." ;
ARTICLE: "compiler-impl" "Compiler implementation"
"The " { $vocab-link "compiler" } "vocabulary, in addition to providing the user-visible words of the compiler, implements the main compilation loop."
$nl
"Words are added to the " { $link compile-queue } " variable as needed and compiled."
{ $subsection compile-queue }
{ $subsections compile-queue }
"Once compiled, a word is added to the assoc stored in the " { $link compiled } " variable. When compilation is complete, this assoc is passed to " { $link modify-code-heap } "."
$nl
"The " { $link compile-word } " word performs the actual task of compiling an individual word. The process proceeds as follows:"
@ -49,10 +51,12 @@ $nl
"The optimizing compiler also trades off compile time for performance of generated code, so loading certain vocabularies might take a while. Saving the image after loading vocabularies can save you a lot of time that you would spend waiting for the same code to load in every coding session; see " { $link "images" } " for information."
$nl
"Most code you write will run with the optimizing compiler. Sometimes, the non-optimizing compiler is used, for example for listener interactions, or for running the quotation passed to " { $link POSTPONE: call( } "."
{ $subsection "compiler-errors" }
{ $subsection "hints" }
{ $subsection "compiler-usage" }
{ $subsection "compiler-impl" } ;
{ $subsections
"compiler-errors"
"hints"
"compiler-usage"
"compiler-impl"
} ;
ABOUT: "compiler"

View File

@ -46,20 +46,6 @@ IN: compiler.tests.low-level-ir
} compile-test-bb
] unit-test
! ##copy on floats. We can only run this test if float intrinsics
! are enabled.
\ float+ "intrinsic" word-prop [
[ 1.5 ] [
V{
T{ ##load-reference f 4 1.5 }
T{ ##unbox-float f 1 4 }
T{ ##copy f 2 1 double-rep }
T{ ##box-float f 3 2 }
T{ ##copy f 0 3 int-rep }
} compile-test-bb
] unit-test
] when
! make sure slot access works when the destination is
! one of the sources
[ t ] [

View File

@ -20,11 +20,23 @@ IN: compiler.tree.propagation.simd
(simd-vbitandn)
(simd-vbitor)
(simd-vbitxor)
(simd-vbitnot)
(simd-vand)
(simd-vandn)
(simd-vor)
(simd-vxor)
(simd-vnot)
(simd-vlshift)
(simd-vrshift)
(simd-hlshift)
(simd-hrshift)
(simd-vshuffle)
(simd-v<=)
(simd-v<)
(simd-v=)
(simd-v>)
(simd-v>=)
(simd-vunordered?)
(simd-with)
(simd-gather-2)
(simd-gather-4)
@ -45,6 +57,12 @@ IN: compiler.tree.propagation.simd
\ (simd-v.) [ 2nip scalar-output-class ] "outputs" set-word-prop
{
(simd-vany?)
(simd-vall?)
(simd-vnone?)
} [ { boolean } "default-output-classes" set-word-prop ] each
\ (simd-select) [ 2nip scalar-output-class ] "outputs" set-word-prop
\ assert-positive [

View File

@ -71,13 +71,15 @@ ARTICLE: "compression.lzw" "LZW Compression"
$nl
"Implements both the TIFF and GIF variations of the LZW algorithm."
{ $heading "Decompression" }
{ $subsection tiff-lzw-uncompress }
{ $subsection gif-lzw-uncompress }
{ $subsections
tiff-lzw-uncompress
gif-lzw-uncompress
}
{ $heading "Compression" }
"Compression has not yet been implemented."
$nl
"Implementation details:"
{ $subsection "compression.lzw.differences" }
{ $subsections "compression.lzw.differences" }
;
ABOUT: "compression.lzw"

View File

@ -30,14 +30,18 @@ ARTICLE: "concurrency.combinators" "Concurrent combinators"
"The " { $vocab-link "concurrency.combinators" } " vocabulary provides concurrent variants of various combinators."
$nl
"Concurrent sequence combinators:"
{ $subsection parallel-each }
{ $subsection 2parallel-each }
{ $subsection parallel-map }
{ $subsection 2parallel-map }
{ $subsection parallel-filter }
{ $subsections
parallel-each
2parallel-each
parallel-map
2parallel-map
parallel-filter
}
"Concurrent cleave combinators:"
{ $subsection parallel-cleave }
{ $subsection parallel-spread }
{ $subsection parallel-napply } ;
{ $subsections
parallel-cleave
parallel-spread
parallel-napply
} ;
ABOUT: "concurrency.combinators"

View File

@ -17,9 +17,11 @@ HELP: await
ARTICLE: "concurrency.count-downs" "Count-down latches"
"The " { $vocab-link "concurrency.count-downs" } " vocabulary implements the " { $emphasis "count-down latch" } " data type, whichis a wrapper for a non-negative integer value which tends towards zero. A thread can either decrement the value, or wait for it to become zero."
{ $subsection <count-down> }
{ $subsection count-down }
{ $subsection await }
{ $subsections
<count-down>
count-down
await
}
"The vocabulary was modelled after a similar feature in Java's " { $snippet "java.util.concurrent" } " library." ;
ABOUT: "concurrency.count-downs"

View File

@ -10,9 +10,9 @@ HELP: start-node
ARTICLE: "concurrency.distributed" "Distributed message passing"
"The " { $vocab-link "concurrency.distributed" } " implements transparent distributed message passing, inspired by Erlang and Termite."
{ $subsection start-node }
{ $subsections start-node }
"Instances of " { $link thread } " can be sent to remote processes, at which point they are converted to objects holding the thread ID and the current node's host name:"
{ $subsection remote-process }
{ $subsections remote-process }
"The " { $vocab-link "serialize" } " vocabulary is used to convert Factor objects to byte arrays for transfer over a socket." ;
ABOUT: "concurrency.distributed"

View File

@ -14,9 +14,11 @@ HELP: exchange
ARTICLE: "concurrency.exchangers" "Object exchange points"
"The " { $vocab-link "concurrency.exchangers" } " vocabulary implements " { $emphasis "object exchange points" } ", which are rendezvous points where two threads can exchange objects."
{ $subsection exchanger }
{ $subsection <exchanger> }
{ $subsection exchange }
{ $subsections
exchanger
<exchanger>
exchange
}
"One use-case is two threads, where one thread reads data into a buffer and another thread processes the data. The reader thread can begin by reading the data, then passing the buffer through an exchanger, then recursing. The processing thread can begin by creating an empty buffer, and exchanging it through the exchanger. It then processes the result and recurses."
$nl
"The vocabulary was modelled after a similar feature in Java's " { $snippet "java.util.concurrent" } " library." ;

View File

@ -28,11 +28,15 @@ $nl
"The flag can be raised at any time; raising a raised flag does nothing. Lowering a flag if it has not been raised yet will wait for another thread to raise the flag."
$nl
"Essentially, a flag can be thought of as a counting semaphore where the count never goes above one."
{ $subsection flag }
{ $subsection flag? }
{ $subsections
flag
flag?
}
"Waiting for a flag to be raised:"
{ $subsection raise-flag }
{ $subsection wait-for-flag }
{ $subsection lower-flag } ;
{ $subsections
raise-flag
wait-for-flag
lower-flag
} ;
ABOUT: "concurrency.flags"

View File

@ -22,8 +22,10 @@ HELP: ?future
ARTICLE: "concurrency.futures" "Futures"
"The " { $vocab-link "concurrency.futures" } " vocabulary implements " { $emphasis "futures" } ", which are deferred computations performed in a background thread. A thread may create a future, then proceed to perform other tasks, then later wait for the future to complete."
{ $subsection future }
{ $subsection ?future }
{ $subsection ?future-timeout } ;
{ $subsections
future
?future
?future-timeout
} ;
ABOUT: "concurrency.futures"

View File

@ -26,11 +26,13 @@ ARTICLE: "concurrency.locks.mutex" "Mutual-exclusion locks"
"A mutual-exclusion lock ensures that only one thread executes with the lock held at a time. They are used to protect critical sections so that certain operations appear to be atomic to other threads."
$nl
"There are two varieties of locks: non-reentrant and reentrant. The latter may be acquired recursively by the same thread. Attempting to do so with the former will deadlock."
{ $subsection lock }
{ $subsection <lock> }
{ $subsection <reentrant-lock> }
{ $subsection with-lock }
{ $subsection with-lock-timeout } ;
{ $subsections
lock
<lock>
<reentrant-lock>
with-lock
with-lock-timeout
} ;
HELP: rw-lock
{ $class-description "The class of reader/writer locks." } ;
@ -61,17 +63,23 @@ $nl
"Read/write locks allow any number of threads to hold the read lock simulateneously, however attempting to acquire a write lock blocks until all other threads release read locks and write locks."
$nl
"Read/write locks are reentrant. A thread holding a write lock may acquire a read lock or a write lock without blocking. However a thread holding a read lock may not acquire a write lock recursively since that could break invariants assumed by the code executing with the read lock held."
{ $subsection rw-lock }
{ $subsection <rw-lock> }
{ $subsection with-read-lock }
{ $subsection with-write-lock }
{ $subsections
rw-lock
<rw-lock>
with-read-lock
with-write-lock
}
"Versions of the above that take a timeout duration:"
{ $subsection with-read-lock-timeout }
{ $subsection with-write-lock-timeout } ;
{ $subsections
with-read-lock-timeout
with-write-lock-timeout
} ;
ARTICLE: "concurrency.locks" "Locks"
"A " { $emphasis "lock" } " is an object protecting a critical region of code, enforcing a particular mutual-exclusion policy. The " { $vocab-link "concurrency.locks" } " vocabulary implements two types of locks:"
{ $subsection "concurrency.locks.mutex" }
{ $subsection "concurrency.locks.rw" } ;
{ $subsections
"concurrency.locks.mutex"
"concurrency.locks.rw"
} ;
ABOUT: "concurrency.locks"

View File

@ -53,20 +53,28 @@ HELP: mailbox-get?
ARTICLE: "concurrency.mailboxes" "Mailboxes"
"A " { $emphasis "mailbox" } " is a first-in-first-out queue where the operation of removing an element blocks if the queue is empty. Mailboxes are implemented in the " { $vocab-link "concurrency.mailboxes" } " vocabulary."
{ $subsection mailbox }
{ $subsection <mailbox> }
{ $subsections
mailbox
<mailbox>
}
"Removing the first element:"
{ $subsection mailbox-get }
{ $subsection mailbox-get-timeout }
{ $subsections
mailbox-get
mailbox-get-timeout
}
"Removing the first element matching a predicate:"
{ $subsection mailbox-get? }
{ $subsection mailbox-get-timeout? }
{ $subsections
mailbox-get?
mailbox-get-timeout?
}
"Emptying out a mailbox:"
{ $subsection mailbox-get-all }
{ $subsections mailbox-get-all }
"Adding an element:"
{ $subsection mailbox-put }
{ $subsections mailbox-put }
"Testing if a mailbox is empty:"
{ $subsection mailbox-empty? }
{ $subsection while-mailbox-empty } ;
{ $subsections
mailbox-empty?
while-mailbox-empty
} ;
ABOUT: "concurrency.mailboxes"

View File

@ -38,19 +38,21 @@ $nl
"The messages that are sent from thread to thread are any Factor value. Factor tuples are ideal for this sort of thing as you can send a tuple to a thread and the generic word dispatch mechanism can be used to perform actions depending on what the type of the tuple is."
$nl
"The " { $link spawn } " word pushes the newly-created thread on the calling thread's stack; this thread object can then be sent messages:"
{ $subsection send }
{ $subsections send }
"A thread can get a message from its queue:"
{ $subsection receive }
{ $subsection receive-timeout }
{ $subsection receive-if }
{ $subsection receive-if-timeout }
{ $subsections
receive
receive-timeout
receive-if
receive-if-timeout
}
{ $see-also "concurrency.mailboxes" } ;
ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends"
"The " { $link send } " word sends a message asynchronously, and the sending thread continues immediately. It is also possible to send a message to a thread and block until a response is received:"
{ $subsection send-synchronous }
{ $subsections send-synchronous }
"To reply to a synchronous message:"
{ $subsection reply-synchronous }
{ $subsections reply-synchronous }
"An example:"
{ $example
"USING: concurrency.messaging threads ;"
@ -66,7 +68,7 @@ ARTICLE: { "concurrency" "exceptions" } "Linked exceptions"
"A thread can handle exceptions using the standard Factor exception handling mechanism. If an exception is uncaught the thread will terminate. For example:"
{ $code "[ 1 0 / \"This will not print\" print ] \"division-by-zero\" spawn" }
"Processes can be linked so that a parent thread can receive the exception that caused the child thread to terminate. In this way 'supervisor' threads can be created that are notified when child threads terminate and possibly restart them."
{ $subsection spawn-linked }
{ $subsections spawn-linked }
"This will create a unidirectional link, such that if an uncaught exception causes the child to terminate, the parent thread can catch it:"
{ $code "["
" [ 1 0 / \"This will not print\" print ] \"linked-division\" spawn-linked drop"
@ -80,8 +82,10 @@ $nl
"A concurrency-oriented program is one in which multiple threads run simultaneously in a single Factor image or across multiple running Factor instances. The threads can communicate with each other by asynchronous message sends."
$nl
"Although threads can share data via Factor's mutable data structures it is not recommended to mix shared state with message passing as it can lead to confusing code."
{ $subsection { "concurrency" "messaging" } }
{ $subsection { "concurrency" "synchronous-sends" } }
{ $subsection { "concurrency" "exceptions" } } ;
{ $subsections
{ "concurrency" "messaging" }
{ "concurrency" "synchronous-sends" }
{ "concurrency" "exceptions" }
} ;
ABOUT: "concurrency.messaging"

View File

@ -31,10 +31,12 @@ HELP: fulfill
ARTICLE: "concurrency.promises" "Promises"
"The " { $vocab-link "concurrency.promises" } " vocabulary implements " { $emphasis "promises" } ", which are thread-safe write-once variables. Once a promise is created, threads may block waiting for it to be " { $emphasis "fulfilled" } "; at some point in the future, another thread may provide a value at which point all waiting threads are notified."
{ $subsection promise }
{ $subsection <promise> }
{ $subsection fulfill }
{ $subsection ?promise }
{ $subsection ?promise-timeout } ;
{ $subsections
promise
<promise>
fulfill
?promise
?promise-timeout
} ;
ABOUT: "concurrency.promises"

View File

@ -43,14 +43,20 @@ $nl
"] parallel-map"
}
"Creating semaphores:"
{ $subsection semaphore }
{ $subsection <semaphore> }
{ $subsections
semaphore
<semaphore>
}
"Unlike locks, where acquisition and release are always paired by a combinator, semaphores expose these operations directly and there is no requirement that they be performed in the same thread:"
{ $subsection acquire }
{ $subsection acquire-timeout }
{ $subsection release }
{ $subsections
acquire
acquire-timeout
release
}
"Combinators which pair acquisition and release:"
{ $subsection with-semaphore }
{ $subsection with-semaphore-timeout } ;
{ $subsections
with-semaphore
with-semaphore-timeout
} ;
ABOUT: "concurrency.semaphores"

View File

@ -21,9 +21,11 @@ ARTICLE: "core-graphics.types" "Core Graphics types"
"CGSize"
}
"Some words for working with the above:"
{ $subsection <CGRect> }
{ $subsection <CGPoint> }
{ $subsection <CGSize> } ;
{ $subsections
<CGRect>
<CGPoint>
<CGSize>
} ;
IN: core-graphics.types
ABOUT: "core-graphics.types"

View File

@ -197,9 +197,6 @@ HOOK: %fixnum-add cpu ( label dst src1 src2 -- )
HOOK: %fixnum-sub cpu ( label dst src1 src2 -- )
HOOK: %fixnum-mul cpu ( label dst src1 src2 -- )
HOOK: %unbox-float cpu ( dst src -- )
HOOK: %box-float cpu ( dst src temp -- )
HOOK: %add-float cpu ( dst src1 src2 -- )
HOOK: %sub-float cpu ( dst src1 src2 -- )
HOOK: %mul-float cpu ( dst src1 src2 -- )
@ -216,13 +213,14 @@ HOOK: %double>single-float cpu ( dst src -- )
HOOK: %integer>float cpu ( dst src -- )
HOOK: %float>integer cpu ( dst src -- )
HOOK: %box-vector cpu ( dst src temp rep -- )
HOOK: %unbox-vector cpu ( dst src rep -- )
HOOK: %zero-vector cpu ( dst rep -- )
HOOK: %fill-vector cpu ( dst rep -- )
HOOK: %gather-vector-2 cpu ( dst src1 src2 rep -- )
HOOK: %gather-vector-4 cpu ( dst src1 src2 src3 src4 rep -- )
HOOK: %shuffle-vector cpu ( dst src shuffle rep -- )
HOOK: %compare-vector cpu ( dst src1 src2 temp rep cc -- )
HOOK: %test-vector cpu ( dst src1 temp rep vcc -- )
HOOK: %test-vector-branch cpu ( label src1 temp rep vcc -- )
HOOK: %add-vector cpu ( dst src1 src2 rep -- )
HOOK: %saturated-add-vector cpu ( dst src1 src2 rep -- )
HOOK: %add-sub-vector cpu ( dst src1 src2 rep -- )
@ -242,6 +240,7 @@ HOOK: %and-vector cpu ( dst src1 src2 rep -- )
HOOK: %andn-vector cpu ( dst src1 src2 rep -- )
HOOK: %or-vector cpu ( dst src1 src2 rep -- )
HOOK: %xor-vector cpu ( dst src1 src2 rep -- )
HOOK: %not-vector cpu ( dst src rep -- )
HOOK: %shl-vector cpu ( dst src1 src2 rep -- )
HOOK: %shr-vector cpu ( dst src1 src2 rep -- )
HOOK: %horizontal-shl-vector cpu ( dst src1 src2 rep -- )
@ -253,9 +252,12 @@ HOOK: %vector>scalar cpu ( dst src rep -- )
HOOK: %scalar>vector cpu ( dst src rep -- )
HOOK: %zero-vector-reps cpu ( -- reps )
HOOK: %fill-vector-reps cpu ( -- reps )
HOOK: %gather-vector-2-reps cpu ( -- reps )
HOOK: %gather-vector-4-reps cpu ( -- reps )
HOOK: %shuffle-vector-reps cpu ( -- reps )
HOOK: %compare-vector-reps cpu ( cc -- reps )
HOOK: %test-vector-reps cpu ( -- reps )
HOOK: %add-vector-reps cpu ( -- reps )
HOOK: %saturated-add-vector-reps cpu ( -- reps )
HOOK: %add-sub-vector-reps cpu ( -- reps )
@ -275,6 +277,7 @@ HOOK: %and-vector-reps cpu ( -- reps )
HOOK: %andn-vector-reps cpu ( -- reps )
HOOK: %or-vector-reps cpu ( -- reps )
HOOK: %xor-vector-reps cpu ( -- reps )
HOOK: %not-vector-reps cpu ( -- reps )
HOOK: %shl-vector-reps cpu ( -- reps )
HOOK: %shr-vector-reps cpu ( -- reps )
HOOK: %horizontal-shl-vector-reps cpu ( -- reps )

View File

@ -1,8 +1,9 @@
IN: cpu.arm.assembler.tests
USING: assembler-arm math test namespaces sequences kernel
quotations ;
USING: cpu.arm.assembler math tools.test namespaces make
sequences kernel quotations ;
FROM: cpu.arm.assembler => B ;
: test-opcode [ { } make first ] curry unit-test ;
: test-opcode ( expect quot -- ) [ { } make first ] curry unit-test ;
[ HEX: ea000000 ] [ 0 B ] test-opcode
[ HEX: eb000000 ] [ 0 BL ] test-opcode

View File

@ -1,31 +1,46 @@
! Copyright (C) 2007 Slava Pestov.
! Copyright (C) 2007, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays generator generator.fixup kernel sequences words
namespaces math math.bitfields ;
USING: accessors arrays combinators kernel make math math.bitwise
namespaces sequences words words.symbol parser ;
IN: cpu.arm.assembler
: define-registers ( seq -- )
dup length [ "register" set-word-prop ] 2each ;
! Registers
<<
SYMBOL: R0
SYMBOL: R1
SYMBOL: R2
SYMBOL: R3
SYMBOL: R4
SYMBOL: R5
SYMBOL: R6
SYMBOL: R7
SYMBOL: R8
SYMBOL: R9
SYMBOL: R10
SYMBOL: R11
SYMBOL: R12
SYMBOL: R13
SYMBOL: R14
SYMBOL: R15
SYMBOL: registers
{ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 }
define-registers
V{ } registers set-global
SYNTAX: REGISTER:
CREATE-WORD
[ define-symbol ]
[ registers get length "register" set-word-prop ]
[ registers get push ]
tri ;
>>
REGISTER: R0
REGISTER: R1
REGISTER: R2
REGISTER: R3
REGISTER: R4
REGISTER: R5
REGISTER: R6
REGISTER: R7
REGISTER: R8
REGISTER: R9
REGISTER: R10
REGISTER: R11
REGISTER: R12
REGISTER: R13
REGISTER: R14
REGISTER: R15
ALIAS: SL R10 ALIAS: FP R11 ALIAS: IP R12
ALIAS: SP R13 ALIAS: LR R14 ALIAS: PC R15
<PRIVATE
PREDICATE: register < word register >boolean ;
@ -33,8 +48,7 @@ GENERIC: register ( register -- n )
M: word register "register" word-prop ;
M: f register drop 0 ;
: SL R10 ; inline : FP R11 ; inline : IP R12 ; inline
: SP R13 ; inline : LR R14 ; inline : PC R15 ; inline
PRIVATE>
! Condition codes
SYMBOL: cond-code
@ -46,43 +60,52 @@ SYMBOL: cond-code
#! Default value is BIN: 1110 AL (= always)
cond-code [ f ] change BIN: 1110 or ;
: EQ BIN: 0000 >CC ;
: NE BIN: 0001 >CC ;
: CS BIN: 0010 >CC ;
: CC BIN: 0011 >CC ;
: LO BIN: 0100 >CC ;
: PL BIN: 0101 >CC ;
: VS BIN: 0110 >CC ;
: VC BIN: 0111 >CC ;
: HI BIN: 1000 >CC ;
: LS BIN: 1001 >CC ;
: GE BIN: 1010 >CC ;
: LT BIN: 1011 >CC ;
: GT BIN: 1100 >CC ;
: LE BIN: 1101 >CC ;
: AL BIN: 1110 >CC ;
: NV BIN: 1111 >CC ;
: EQ ( -- ) BIN: 0000 >CC ;
: NE ( -- ) BIN: 0001 >CC ;
: CS ( -- ) BIN: 0010 >CC ;
: CC ( -- ) BIN: 0011 >CC ;
: LO ( -- ) BIN: 0100 >CC ;
: PL ( -- ) BIN: 0101 >CC ;
: VS ( -- ) BIN: 0110 >CC ;
: VC ( -- ) BIN: 0111 >CC ;
: HI ( -- ) BIN: 1000 >CC ;
: LS ( -- ) BIN: 1001 >CC ;
: GE ( -- ) BIN: 1010 >CC ;
: LT ( -- ) BIN: 1011 >CC ;
: GT ( -- ) BIN: 1100 >CC ;
: LE ( -- ) BIN: 1101 >CC ;
: AL ( -- ) BIN: 1110 >CC ;
: NV ( -- ) BIN: 1111 >CC ;
<PRIVATE
: (insn) ( n -- ) CC> 28 shift bitor , ;
: insn ( bitspec -- ) bitfield (insn) ; inline
! Branching instructions
GENERIC# (B) 1 ( signed-imm-24 l -- )
GENERIC# (B) 1 ( target l -- )
M: integer (B) { 24 { 1 25 } { 0 26 } { 1 27 } 0 } insn ;
M: word (B) 0 swap (B) rc-relative-arm-3 rel-word ;
M: label (B) 0 swap (B) rc-relative-arm-3 label-fixup ;
: B 0 (B) ; : BL 1 (B) ;
PRIVATE>
: B ( target -- ) 0 (B) ;
: BL ( target -- ) 1 (B) ;
! Data processing instructions
<PRIVATE
SYMBOL: updates-cond-code
PRIVATE>
: S ( -- ) updates-cond-code on ;
: S> ( -- ? ) updates-cond-code [ f ] change ;
<PRIVATE
: sinsn ( bitspec -- )
bitfield S> [ 20 2^ bitor ] when (insn) ; inline
@ -100,21 +123,25 @@ M: register shift-imm/reg ( Rs Rm shift -- n )
{ register 0 }
} bitfield ;
GENERIC: shifter-op ( shifter-op -- n )
PRIVATE>
TUPLE: IMM immed rotate ;
C: <IMM> IMM
M: IMM shifter-op
dup IMM-immed swap IMM-rotate
{ { 1 25 } 8 0 } bitfield ;
TUPLE: shifter Rm by shift ;
C: <shifter> shifter
<PRIVATE
GENERIC: shifter-op ( shifter-op -- n )
M: IMM shifter-op
[ immed>> ] [ rotate>> ] bi { { 1 25 } 8 0 } bitfield ;
M: shifter shifter-op
dup shifter-by over shifter-Rm rot shifter-shift
shift-imm/reg ;
[ by>> ] [ Rm>> ] [ shift>> ] tri shift-imm/reg ;
PRIVATE>
: <LSL> ( Rm shift-imm/Rs -- shifter-op ) BIN: 00 <shifter> ;
: <LSR> ( Rm shift-imm/Rs -- shifter-op ) BIN: 01 <shifter> ;
@ -123,9 +150,10 @@ M: shifter shifter-op
: <RRX> ( Rm -- shifter-op ) 0 <ROR> ;
M: register shifter-op 0 <LSL> shifter-op ;
M: integer shifter-op 0 <IMM> shifter-op ;
<PRIVATE
: addr1 ( Rd Rn shifter-op opcode -- )
{
21 ! opcode
@ -134,30 +162,38 @@ M: integer shifter-op 0 <IMM> shifter-op ;
{ register 12 } ! Rd
} sinsn ;
: AND BIN: 0000 addr1 ;
: EOR BIN: 0001 addr1 ;
: SUB BIN: 0010 addr1 ;
: RSB BIN: 0011 addr1 ;
: ADD BIN: 0100 addr1 ;
: ADC BIN: 0101 addr1 ;
: SBC BIN: 0110 addr1 ;
: RSC BIN: 0111 addr1 ;
: ORR BIN: 1100 addr1 ;
: BIC BIN: 1110 addr1 ;
PRIVATE>
: MOV f swap BIN: 1101 addr1 ;
: MVN f swap BIN: 1111 addr1 ;
: AND ( Rd Rn shifter-op -- ) BIN: 0000 addr1 ;
: EOR ( Rd Rn shifter-op -- ) BIN: 0001 addr1 ;
: SUB ( Rd Rn shifter-op -- ) BIN: 0010 addr1 ;
: RSB ( Rd Rn shifter-op -- ) BIN: 0011 addr1 ;
: ADD ( Rd Rn shifter-op -- ) BIN: 0100 addr1 ;
: ADC ( Rd Rn shifter-op -- ) BIN: 0101 addr1 ;
: SBC ( Rd Rn shifter-op -- ) BIN: 0110 addr1 ;
: RSC ( Rd Rn shifter-op -- ) BIN: 0111 addr1 ;
: ORR ( Rd Rn shifter-op -- ) BIN: 1100 addr1 ;
: BIC ( Rd Rn shifter-op -- ) BIN: 1110 addr1 ;
: MOV ( Rd shifter-op -- ) [ f ] dip BIN: 1101 addr1 ;
: MVN ( Rd shifter-op -- ) [ f ] dip BIN: 1111 addr1 ;
! These always update the condition code flags
: (CMP) >r f -rot r> S addr1 ;
<PRIVATE
: TST BIN: 1000 (CMP) ;
: TEQ BIN: 1001 (CMP) ;
: CMP BIN: 1010 (CMP) ;
: CMN BIN: 1011 (CMP) ;
: (CMP) ( Rn shifter-op opcode -- ) [ f ] 3dip S addr1 ;
PRIVATE>
: TST ( Rn shifter-op -- ) BIN: 1000 (CMP) ;
: TEQ ( Rn shifter-op -- ) BIN: 1001 (CMP) ;
: CMP ( Rn shifter-op -- ) BIN: 1010 (CMP) ;
: CMN ( Rn shifter-op -- ) BIN: 1011 (CMP) ;
! Multiply instructions
: (MLA) ( Rd Rm Rs Rn a -- )
<PRIVATE
: (MLA) ( Rd Rm Rs Rn a -- )
{
21
{ register 12 }
@ -168,9 +204,6 @@ M: integer shifter-op 0 <IMM> shifter-op ;
{ 1 4 }
} sinsn ;
: MUL ( Rd Rm Rs -- ) f 0 (MLA) ;
: MLA ( Rd Rm Rs Rn -- ) 1 (MLA) ;
: (S/UMLAL) ( RdLo RdHi Rm Rs s a -- )
{
{ 1 23 }
@ -184,8 +217,15 @@ M: integer shifter-op 0 <IMM> shifter-op ;
{ 1 4 }
} sinsn ;
: SMLAL 1 1 (S/UMLAL) ; : SMULL 1 0 (S/UMLAL) ;
: UMLAL 0 1 (S/UMLAL) ; : UMULL 0 0 (S/UMLAL) ;
PRIVATE>
: MUL ( Rd Rm Rs -- ) f 0 (MLA) ;
: MLA ( Rd Rm Rs Rn -- ) 1 (MLA) ;
: SMLAL ( RdLo RdHi Rm Rs -- ) 1 1 (S/UMLAL) ;
: SMULL ( RdLo RdHi Rm Rs -- ) 1 0 (S/UMLAL) ;
: UMLAL ( RdLo RdHi Rm Rs -- ) 0 1 (S/UMLAL) ;
: UMULL ( RdLo RdHi Rm Rs -- ) 0 0 (S/UMLAL) ;
! Miscellaneous arithmetic instructions
: CLZ ( Rd Rm -- )
@ -203,39 +243,21 @@ M: integer shifter-op 0 <IMM> shifter-op ;
! Status register acess instructions
! Load and store instructions
<PRIVATE
GENERIC: addressing-mode-2 ( addressing-mode -- n )
TUPLE: addressing p u w ;
: <addressing> ( delegate p u w -- addressing )
{
set-delegate
set-addressing-p
set-addressing-u
set-addressing-w
} addressing construct ;
TUPLE: addressing base p u w ;
C: <addressing> addressing
M: addressing addressing-mode-2
{
addressing-p addressing-u addressing-w delegate
} get-slots addressing-mode-2
{ [ p>> ] [ u>> ] [ w>> ] [ base>> addressing-mode-2 ] } cleave
{ 0 21 23 24 } bitfield ;
M: integer addressing-mode-2 ;
M: object addressing-mode-2 shifter-op { { 1 25 } 0 } bitfield ;
! Offset
: <+> 1 1 0 <addressing> ;
: <-> 1 0 0 <addressing> ;
! Pre-indexed
: <!+> 1 1 1 <addressing> ;
: <!-> 1 0 1 <addressing> ;
! Post-indexed
: <+!> 0 1 0 <addressing> ;
: <-!> 0 0 0 <addressing> ;
: addr2 ( Rd Rn addressing-mode b l -- )
{
{ 1 26 }
@ -246,16 +268,32 @@ M: object addressing-mode-2 shifter-op { { 1 25 } 0 } bitfield ;
{ register 12 }
} insn ;
: LDR 0 1 addr2 ;
: LDRB 1 1 addr2 ;
: STR 0 0 addr2 ;
: STRB 1 0 addr2 ;
PRIVATE>
! Offset
: <+> ( base -- addressing ) 1 1 0 <addressing> ;
: <-> ( base -- addressing ) 1 0 0 <addressing> ;
! Pre-indexed
: <!+> ( base -- addressing ) 1 1 1 <addressing> ;
: <!-> ( base -- addressing ) 1 0 1 <addressing> ;
! Post-indexed
: <+!> ( base -- addressing ) 0 1 0 <addressing> ;
: <-!> ( base -- addressing ) 0 0 0 <addressing> ;
: LDR ( Rd Rn addressing-mode -- ) 0 1 addr2 ;
: LDRB ( Rd Rn addressing-mode -- ) 1 1 addr2 ;
: STR ( Rd Rn addressing-mode -- ) 0 0 addr2 ;
: STRB ( Rd Rn addressing-mode -- ) 1 0 addr2 ;
! We might have to simulate these instructions since older ARM
! chips don't have them.
SYMBOL: have-BX?
SYMBOL: have-BLX?
<PRIVATE
GENERIC# (BX) 1 ( Rm l -- )
M: register (BX) ( Rm l -- )
@ -270,24 +308,21 @@ M: register (BX) ( Rm l -- )
{ register 0 }
} insn ;
M: word (BX) 0 swap (BX) rc-relative-arm-3 rel-word ;
PRIVATE>
M: label (BX) 0 swap (BX) rc-relative-arm-3 label-fixup ;
: BX ( Rm -- ) have-BX? get [ 0 (BX) ] [ [ PC ] dip MOV ] if ;
: BX have-BX? get [ 0 (BX) ] [ PC swap MOV ] if ;
: BLX have-BLX? get [ 1 (BX) ] [ LR PC MOV BX ] if ;
: BLX ( Rm -- ) have-BLX? get [ 1 (BX) ] [ LR PC MOV BX ] if ;
! More load and store instructions
<PRIVATE
GENERIC: addressing-mode-3 ( addressing-mode -- n )
: b>n/n ( b -- n n ) dup -4 shift swap HEX: f bitand ;
: b>n/n ( b -- n n ) [ -4 shift ] [ HEX: f bitand ] bi ;
M: addressing addressing-mode-3
[ addressing-p ] keep
[ addressing-u ] keep
[ addressing-w ] keep
delegate addressing-mode-3
{ [ p>> ] [ u>> ] [ w>> ] [ base>> addressing-mode-3 ] } cleave
{ 0 21 23 24 } bitfield ;
M: integer addressing-mode-3
@ -318,10 +353,12 @@ M: object addressing-mode-3
{ register 12 }
} insn ;
: LDRH 1 1 0 addr3 ;
: LDRSB 0 1 1 addr3 ;
: LDRSH 1 1 1 addr3 ;
: STRH 1 0 0 addr3 ;
PRIVATE>
: LDRH ( Rn Rd addressing-mode -- ) 1 1 0 addr3 ;
: LDRSB ( Rn Rd addressing-mode -- ) 0 1 1 addr3 ;
: LDRSH ( Rn Rd addressing-mode -- ) 1 1 1 addr3 ;
: STRH ( Rn Rd addressing-mode -- ) 1 0 0 addr3 ;
! Load and store multiple instructions

View File

@ -51,8 +51,9 @@ CONSTANT: rs-reg 14
0 3 LOAD32 rc-absolute-ppc-2/2 rt-stack-chain jit-rel
4 3 0 LWZ
1 4 0 STW
0 3 LOAD32 rc-absolute-ppc-2/2 rt-primitive jit-rel
3 MTCTR
4 0 swap LOAD32 rc-absolute-ppc-2/2 rt-vm jit-rel
0 5 LOAD32 rc-absolute-ppc-2/2 rt-primitive jit-rel
5 MTCTR
BCTR
] jit-primitive jit-define
@ -254,8 +255,9 @@ CONSTANT: rs-reg 14
[
3 ds-reg 0 LWZ
ds-reg dup 4 SUBI
4 3 quot-xt-offset LWZ
4 MTCTR
4 0 swap LOAD32 rc-absolute-ppc-2/2 rt-vm jit-rel
5 3 quot-xt-offset LWZ
5 MTCTR
BCTR
] \ (call) define-sub-primitive

View File

@ -230,12 +230,6 @@ M: ppc %copy ( dst src rep -- )
} case
] if ;
M: ppc %unbox-float ( dst src -- ) float-offset LFD ;
M:: ppc %box-float ( dst src temp -- )
dst 16 float temp %allot
src dst float-offset STFD ;
GENERIC: float-function-param* ( dst src -- )
M: spill-slot float-function-param* [ 1 ] dip n>> spill@ LFD ;
@ -264,9 +258,12 @@ M: ppc %double>single-float double-rep %copy ;
! VMX/AltiVec not supported yet
M: ppc %zero-vector-reps { } ;
M: ppc %fill-vector-reps { } ;
M: ppc %gather-vector-2-reps { } ;
M: ppc %gather-vector-4-reps { } ;
M: ppc %shuffle-vector-reps { } ;
M: ppc %compare-vector-reps drop { } ;
M: ppc %test-vector-reps { } ;
M: ppc %add-vector-reps { } ;
M: ppc %saturated-add-vector-reps { } ;
M: ppc %add-sub-vector-reps { } ;
@ -286,6 +283,7 @@ M: ppc %and-vector-reps { } ;
M: ppc %andn-vector-reps { } ;
M: ppc %or-vector-reps { } ;
M: ppc %xor-vector-reps { } ;
M: ppc %not-vector-reps { } ;
M: ppc %shl-vector-reps { } ;
M: ppc %shr-vector-reps { } ;
M: ppc %horizontal-shl-vector-reps { } ;
@ -397,13 +395,13 @@ M: ppc %alien-cell LWZ ;
M: ppc %alien-float LFS ;
M: ppc %alien-double LFD ;
M: ppc %set-alien-integer-1 swapd STB ;
M: ppc %set-alien-integer-2 swapd STH ;
M: ppc %set-alien-integer-1 -rot STB ;
M: ppc %set-alien-integer-2 -rot STH ;
M: ppc %set-alien-cell swapd STW ;
M: ppc %set-alien-cell -rot STW ;
M: ppc %set-alien-float swapd STFS ;
M: ppc %set-alien-double swapd STFD ;
M: ppc %set-alien-float -rot STFS ;
M: ppc %set-alien-double -rot STFD ;
: load-zone-ptr ( reg -- )
"nursery" %load-vm-field-addr ;
@ -466,6 +464,7 @@ M:: ppc %load-gc-root ( gc-root register -- )
M:: ppc %call-gc ( gc-root-count temp -- )
3 1 gc-root-base local@ ADDI
gc-root-count 4 LI
5 %load-vm-addr
"inline_gc" f %alien-invoke ;
M: ppc %prologue ( n -- )
@ -614,13 +613,14 @@ M: ppc %prepare-unbox ( -- )
M: ppc %unbox ( n rep func -- )
! Value must be in r3
4 %load-vm-addr
! Call the unboxer
f %alien-invoke
! Store the return value on the C stack
over [ [ reg-class-of return-reg ] keep %save-param-reg ] [ 2drop ] if ;
M: ppc %unbox-long-long ( n func -- )
! Value must be in r3:r4
4 %load-vm-addr
! Call the unboxer
f %alien-invoke
! Store the return value on the C stack
@ -633,15 +633,17 @@ M: ppc %unbox-large-struct ( n c-type -- )
! Value must be in r3
! Compute destination address and load struct size
[ [ 4 1 ] dip local@ ADDI ] [ heap-size 5 LI ] bi*
6 %load-vm-addr
! Call the function
"to_value_struct" f %alien-invoke ;
M: ppc %box ( n rep func -- )
M:: ppc %box ( n rep func -- )
! If the source is a stack location, load it into freg #0.
! If the source is f, then we assume the value is already in
! freg #0.
[ over [ 0 over reg-class-of param-reg swap %load-param-reg ] [ 2drop ] if ] dip
f %alien-invoke ;
n [ 0 rep reg-class-of param-reg rep %load-param-reg ] when*
rep double-rep? 5 4 ? %load-vm-addr
func f %alien-invoke ;
M: ppc %box-long-long ( n func -- )
[
@ -649,6 +651,7 @@ M: ppc %box-long-long ( n func -- )
[ [ 3 1 ] dip local@ LWZ ]
[ [ 4 1 ] dip cell + local@ LWZ ] bi
] when*
5 %load-vm-addr
] dip f %alien-invoke ;
: struct-return@ ( n -- n )
@ -663,6 +666,7 @@ M: ppc %box-large-struct ( n c-type -- )
! If n = f, then we're boxing a returned struct
! Compute destination address and load struct size
[ [ 3 1 ] dip struct-return@ ADDI ] [ heap-size 4 LI ] bi*
5 %load-vm-addr
! Call the function
"box_value_struct" f %alien-invoke ;
@ -682,9 +686,12 @@ M: ppc %alien-invoke ( symbol dll -- )
[ 11 ] 2dip %alien-global 11 MTLR BLRL ;
M: ppc %alien-callback ( quot -- )
3 swap %load-reference "c_to_factor" f %alien-invoke ;
3 swap %load-reference
4 %load-vm-addr
"c_to_factor" f %alien-invoke ;
M: ppc %prepare-alien-indirect ( -- )
3 %load-vm-addr
"unbox_alien" f %alien-invoke
15 3 MR ;
@ -695,6 +702,7 @@ M: ppc %callback-value ( ctype -- )
! Save top of data stack
3 ds-reg 0 LWZ
3 1 0 local@ STW
3 %load-vm-addr
! Restore data/call/retain stacks
"unnest_stacks" f %alien-invoke
! Restore top of data stack
@ -710,21 +718,25 @@ M: ppc return-struct-in-registers? ( c-type -- ? )
M: ppc %box-small-struct ( c-type -- )
#! Box a <= 16-byte struct returned in r3:r4:r5:r6
heap-size 7 LI
8 %load-vm-addr
"box_medium_struct" f %alien-invoke ;
: %unbox-struct-1 ( -- )
! Alien must be in r3.
4 %load-vm-addr
"alien_offset" f %alien-invoke
3 3 0 LWZ ;
: %unbox-struct-2 ( -- )
! Alien must be in r3.
4 %load-vm-addr
"alien_offset" f %alien-invoke
4 3 4 LWZ
3 3 0 LWZ ;
: %unbox-struct-4 ( -- )
! Alien must be in r3.
4 %load-vm-addr
"alien_offset" f %alien-invoke
6 3 12 LWZ
5 3 8 LWZ
@ -732,9 +744,11 @@ M: ppc %box-small-struct ( c-type -- )
3 3 0 LWZ ;
M: ppc %nest-stacks ( -- )
3 %load-vm-addr
"nest_stacks" f %alien-invoke ;
M: ppc %unnest-stacks ( -- )
3 %load-vm-addr
"unnest_stacks" f %alien-invoke ;
M: ppc %unbox-small-struct ( size -- )

View File

@ -474,13 +474,6 @@ M: x86 %double>single-float CVTSD2SS ;
M: x86 %integer>float CVTSI2SD ;
M: x86 %float>integer CVTTSD2SI ;
M: x86 %unbox-float ( dst src -- )
float-offset [+] MOVSD ;
M:: x86 %box-float ( dst src temp -- )
dst 16 float temp %allot
dst float-offset [+] src MOVSD ;
: %cmov-float= ( dst src -- )
[
"no-move" define-label
@ -561,16 +554,6 @@ M: x86 %compare-float-ordered-branch ( label src1 src2 cc -- )
M: x86 %compare-float-unordered-branch ( label src1 src2 cc -- )
\ UCOMISD (%compare-float-branch) ;
M:: x86 %box-vector ( dst src rep temp -- )
dst rep rep-size 2 cells + byte-array temp %allot
16 tag-fixnum dst 1 byte-array tag-number %set-slot-imm
dst byte-array-offset [+]
src rep %copy ;
M:: x86 %unbox-vector ( dst src rep -- )
dst src byte-array-offset [+]
rep %copy ;
MACRO: available-reps ( alist -- )
! Each SSE version adds new representations and supports
! all old ones
@ -592,6 +575,19 @@ M: x86 %zero-vector-reps
{ sse2? { double-2-rep char-16-rep uchar-16-rep short-8-rep ushort-8-rep int-4-rep uint-4-rep longlong-2-rep ulonglong-2-rep } }
} available-reps ;
M: x86 %fill-vector
{
{ double-2-rep [ dup [ XORPD ] [ CMPEQPD ] 2bi ] }
{ float-4-rep [ dup [ XORPS ] [ CMPEQPS ] 2bi ] }
[ drop dup PCMPEQB ]
} case ;
M: x86 %fill-vector-reps
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep char-16-rep uchar-16-rep short-8-rep ushort-8-rep int-4-rep uint-4-rep longlong-2-rep ulonglong-2-rep } }
} available-reps ;
: unsign-rep ( rep -- rep' )
{
{ uint-4-rep int-4-rep }
@ -725,6 +721,117 @@ M: x86 %shuffle-vector-reps
{ sse2? { double-2-rep int-4-rep uint-4-rep longlong-2-rep ulonglong-2-rep } }
} available-reps ;
:: compare-float-v-operands ( dst src1 src2 temp rep cc -- dst' src' rep cc' )
cc { cc> cc>= cc/> cc/>= } member?
[ dst src2 src1 rep two-operand rep cc swap-cc ]
[ dst src1 src2 rep two-operand rep cc ] if ;
: (%compare-float-vector) ( dst src rep double single -- )
[ double-2-rep eq? ] 2dip if ; inline
: %compare-float-vector ( dst src1 src2 temp rep cc -- )
compare-float-v-operands {
{ cc< [ [ CMPLTPD ] [ CMPLTPS ] (%compare-float-vector) ] }
{ cc<= [ [ CMPLEPD ] [ CMPLEPS ] (%compare-float-vector) ] }
{ cc= [ [ CMPEQPD ] [ CMPEQPS ] (%compare-float-vector) ] }
{ cc<>= [ [ CMPORDPD ] [ CMPORDPS ] (%compare-float-vector) ] }
{ cc/< [ [ CMPNLTPD ] [ CMPNLTPS ] (%compare-float-vector) ] }
{ cc/<= [ [ CMPNLEPD ] [ CMPNLEPS ] (%compare-float-vector) ] }
{ cc/= [ [ CMPNEQPD ] [ CMPNEQPS ] (%compare-float-vector) ] }
{ cc/<>= [ [ CMPUNORDPD ] [ CMPUNORDPS ] (%compare-float-vector) ] }
} case ;
:: compare-int-v-operands ( dst src1 src2 temp rep cc -- not-dst/f cmp-dst src' rep cc' )
cc order-cc :> occ
occ {
{ cc= [ f dst src1 src2 rep two-operand rep cc= ] }
{ cc/= [ dst temp src1 src2 rep two-operand rep cc= ] }
{ cc<= [ dst temp src1 src2 rep two-operand rep cc> ] }
{ cc< [ f dst src2 src1 rep two-operand rep cc> ] }
{ cc> [ f dst src1 src2 rep two-operand rep cc> ] }
{ cc>= [ dst temp src2 src1 rep two-operand rep cc> ] }
} case ;
:: (%compare-int-vector) ( dst src rep int64 int32 int16 int8 -- )
rep unsign-rep :> rep'
dst src rep' {
{ longlong-2-rep [ int64 call ] }
{ int-4-rep [ int32 call ] }
{ short-8-rep [ int16 call ] }
{ char-16-rep [ int8 call ] }
} case ; inline
:: %compare-int-vector ( dst src1 src2 temp rep cc -- )
dst src1 src2 temp rep cc compare-int-v-operands :> cc' :> rep :> src' :> cmp-dst :> not-dst
cmp-dst src' rep cc' {
{ cc= [ [ PCMPEQQ ] [ PCMPEQD ] [ PCMPEQW ] [ PCMPEQB ] (%compare-int-vector) ] }
{ cc> [ [ PCMPGTQ ] [ PCMPGTD ] [ PCMPGTW ] [ PCMPGTB ] (%compare-int-vector) ] }
} case
not-dst [ cmp-dst rep %not-vector ] when* ;
M: x86 %compare-vector ( dst src1 src2 temp rep cc -- )
over float-vector-rep?
[ %compare-float-vector ]
[ %compare-int-vector ] if ;
: %compare-vector-eq-reps ( -- reps )
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep char-16-rep uchar-16-rep short-8-rep ushort-8-rep int-4-rep uint-4-rep } }
{ sse4.1? { longlong-2-rep ulonglong-2-rep } }
} available-reps ;
: %compare-vector-unord-reps ( -- reps )
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep } }
} available-reps ;
: %compare-vector-ord-reps ( -- reps )
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep char-16-rep short-8-rep int-4-rep } }
{ sse4.1? { longlong-2-rep } }
} available-reps ;
M: x86 %compare-vector-reps
{
{ [ dup { cc= cc/= } memq? ] [ drop %compare-vector-eq-reps ] }
{ [ dup { cc<>= cc/<>= } memq? ] [ drop %compare-vector-unord-reps ] }
[ drop %compare-vector-ord-reps ]
} cond ;
:: %test-vector-mask ( dst temp mask vcc -- )
vcc {
{ vcc-any [ dst dst TEST dst temp \ CMOVNE %boolean ] }
{ vcc-none [ dst dst TEST dst temp \ CMOVE %boolean ] }
{ vcc-all [ dst mask CMP dst temp \ CMOVE %boolean ] }
{ vcc-notall [ dst mask CMP dst temp \ CMOVNE %boolean ] }
} case ;
: %move-vector-mask ( dst src rep -- mask )
{
{ double-2-rep [ MOVMSKPD HEX: 3 ] }
{ float-4-rep [ MOVMSKPS HEX: f ] }
[ drop PMOVMSKB HEX: ffff ]
} case ;
M:: x86 %test-vector ( dst src temp rep vcc -- )
dst src rep %move-vector-mask :> mask
dst temp mask vcc %test-vector-mask ;
:: %test-vector-mask-branch ( label temp mask vcc -- )
vcc {
{ vcc-any [ temp temp TEST label JNE ] }
{ vcc-none [ temp temp TEST label JE ] }
{ vcc-all [ temp mask CMP label JE ] }
{ vcc-notall [ temp mask CMP label JNE ] }
} case ;
M:: x86 %test-vector-branch ( label src temp rep vcc -- )
temp src rep %move-vector-mask :> mask
label temp mask vcc %test-vector-mask-branch ;
M: x86 %test-vector-reps
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep char-16-rep uchar-16-rep short-8-rep ushort-8-rep int-4-rep uint-4-rep longlong-2-rep ulonglong-2-rep } }
} available-reps ;
M: x86 %add-vector ( dst src1 src2 rep -- )
[ two-operand ] keep
{
@ -1011,6 +1118,16 @@ M: x86 %xor-vector-reps
{ sse2? { double-2-rep char-16-rep uchar-16-rep short-8-rep ushort-8-rep int-4-rep uint-4-rep longlong-2-rep ulonglong-2-rep } }
} available-reps ;
M:: x86 %not-vector ( dst src rep -- )
dst rep %fill-vector
dst dst src rep %xor-vector ;
M: x86 %not-vector-reps
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep char-16-rep uchar-16-rep short-8-rep ushort-8-rep int-4-rep uint-4-rep longlong-2-rep ulonglong-2-rep } }
} available-reps ;
M: x86 %shl-vector ( dst src1 src2 rep -- )
[ two-operand ] keep
{

View File

@ -39,14 +39,14 @@ HELP: with-delimiter
ARTICLE: "csv" "Comma-separated-values parsing and writing"
"The " { $vocab-link "csv" } " vocabulary can read and write CSV (comma-separated-value) files." $nl
"Reading a csv file:"
{ $subsection file>csv }
{ $subsections file>csv }
"Writing a csv file:"
{ $subsection csv>file }
{ $subsections csv>file }
"Changing the delimiter from a comma:"
{ $subsection with-delimiter }
{ $subsections with-delimiter }
"Reading from a stream:"
{ $subsection csv }
{ $subsections csv }
"Writing to a stream:"
{ $subsection write-csv } ;
{ $subsections write-csv } ;
ABOUT: "csv"

View File

@ -31,8 +31,10 @@ HELP: statement
HELP: result-set
{ $description "An object encapsulating a raw SQL result object. There are two ways in which a result set can be accessed, but they are specific to the database backend in use."
{ $subsection "db-random-access-result-set" }
{ $subsection "db-sequential-result-set" }
{ $subsections
"db-random-access-result-set"
"db-sequential-result-set"
}
} ;
HELP: new-result-set
@ -177,14 +179,16 @@ HELP: with-transaction
ARTICLE: "db" "Database library"
"Accessing a database:"
{ $subsection "db-custom-database-combinators" }
{ $subsections "db-custom-database-combinators" }
"Higher-level database help:"
{ $vocab-subsection "Database types" "db.types" }
{ $vocab-subsection "High-level tuple/database integration" "db.tuples" }
"Low-level database help:"
{ $subsection "db-protocol" }
{ $subsection "db-result-sets" }
{ $subsection "db-lowlevel-tutorial" }
{ $subsections
"db-protocol"
"db-result-sets"
"db-lowlevel-tutorial"
}
"Supported database backends:"
{ $vocab-subsection "SQLite" "db.sqlite" }
{ $vocab-subsection "PostgreSQL" "db.postgresql" } ;
@ -193,62 +197,78 @@ ARTICLE: "db-random-access-result-set" "Random access result sets"
"Random-access result sets do not have to be traversed in order. For instance, PostgreSQL's result set object can be accessed as a matrix with i,j coordinates."
$nl
"Databases which work in this way must provide methods for the following traversal words:"
{ $subsection #rows }
{ $subsection #columns }
{ $subsection row-column }
{ $subsection row-column-typed } ;
{ $subsections
#rows
#columns
row-column
row-column-typed
} ;
ARTICLE: "db-sequential-result-set" "Sequential result sets"
"Sequential result sets can be iterated one element after the next. SQLite's result sets offer this method of traversal."
$nl
"Databases which work in this way must provide methods for the following traversal words:"
{ $subsection more-rows? }
{ $subsection advance-row }
{ $subsection row-column }
{ $subsection row-column-typed } ;
{ $subsections
more-rows?
advance-row
row-column
row-column-typed
} ;
ARTICLE: "db-result-sets" "Result sets"
"Result sets are the encapsulated, database-specific results from a SQL query."
$nl
"Two possible protocols for iterating over result sets exist:"
{ $subsection "db-random-access-result-set" }
{ $subsection "db-sequential-result-set" }
{ $subsections
"db-random-access-result-set"
"db-sequential-result-set"
}
"Query the number of rows or columns:"
{ $subsection #rows }
{ $subsection #columns }
{ $subsections
#rows
#columns
}
"Traversing a result set:"
{ $subsection advance-row }
{ $subsection more-rows? }
{ $subsections
advance-row
more-rows?
}
"Pulling out a single row of results:"
{ $subsection row-column }
{ $subsection row-column-typed } ;
{ $subsections
row-column
row-column-typed
} ;
ARTICLE: "db-protocol" "Low-level database protocol"
"The high-level protocol (see " { $vocab-link "db.tuples" } ") uses this low-level protocol for executing statements and queries." $nl
"Opening a database:"
{ $subsection db-open }
{ $subsections db-open }
"Closing a database:"
{ $subsection db-close }
{ $subsections db-close }
"Creating statements:"
{ $subsection <simple-statement> }
{ $subsection <prepared-statement> }
{ $subsections
<simple-statement>
<prepared-statement>
}
"Using statements with the database:"
{ $subsection prepare-statement }
{ $subsection bind-statement* }
{ $subsection low-level-bind }
{ $subsections
prepare-statement
bind-statement*
low-level-bind
}
"Performing a query:"
{ $subsection query-results }
{ $subsections query-results }
"Handling query results:"
{ $subsection "db-result-sets" }
{ $subsections "db-result-sets" }
;
! { $subsection bind-tuple }
ARTICLE: "db-lowlevel-tutorial" "Low-level database tutorial"
"Although Factor makes integrating a database with its object system easy (see " { $vocab-link "db.tuples" } "), sometimes you may want to write SQL directly and get the results back as arrays of strings, for instance, when interfacing with a legacy database that doesn't easily map to " { $snippet "tuples" } "." $nl
"Executing a SQL command:"
{ $subsection sql-command }
{ $subsections sql-command }
"Executing a query directly:"
{ $subsection sql-query }
{ $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 """

View File

@ -154,52 +154,58 @@ HELP: count-tuples
ARTICLE: "db-tuples" "High-level tuple/database integration"
"Start with a tutorial:"
{ $subsection "db-tuples-tutorial" }
{ $subsections "db-tuples-tutorial" }
"Database types supported:"
{ $subsection "db.types" }
{ $subsections "db.types" }
"Useful words:"
{ $subsection "db-tuples-words" }
{ $subsections "db-tuples-words" }
"For porting db.tuples to other databases:"
{ $subsection "db-tuples-protocol" }
{ $subsections "db-tuples-protocol" }
;
ARTICLE: "db-tuples-words" "High-level tuple/database words"
"Making tuples work with a database:"
{ $subsection define-persistent }
{ $subsections define-persistent }
"Creating tables:"
{ $subsection create-table }
{ $subsection ensure-table }
{ $subsection ensure-tables }
{ $subsection recreate-table }
{ $subsections
create-table
ensure-table
ensure-tables
recreate-table
}
"Dropping tables:"
{ $subsection drop-table }
{ $subsections drop-table }
"Inserting a tuple:"
{ $subsection insert-tuple }
{ $subsections insert-tuple }
"Updating a tuple:"
{ $subsection update-tuple }
{ $subsections update-tuple }
"Deleting tuples:"
{ $subsection delete-tuples }
{ $subsections delete-tuples }
"Querying tuples:"
{ $subsection select-tuple }
{ $subsection select-tuples }
{ $subsection count-tuples } ;
{ $subsections
select-tuple
select-tuples
count-tuples
} ;
ARTICLE: "db-tuples-protocol" "Tuple database protocol"
"Creating a table:"
{ $subsection create-sql-statement }
{ $subsections create-sql-statement }
"Dropping a table:"
{ $subsection drop-sql-statement }
{ $subsections drop-sql-statement }
"Inserting a tuple:"
{ $subsection <insert-db-assigned-statement> }
{ $subsection <insert-user-assigned-statement> }
{ $subsections
<insert-db-assigned-statement>
<insert-user-assigned-statement>
}
"Updating a tuple:"
{ $subsection <update-tuple-statement> }
{ $subsections <update-tuple-statement> }
"Deleting tuples:"
{ $subsection <delete-tuples-statement> }
{ $subsections <delete-tuples-statement> }
"Selecting tuples:"
{ $subsection <select-by-slots-statement> }
{ $subsections <select-by-slots-statement> }
"Counting tuples:"
{ $subsection <count-statement> } ;
{ $subsections <count-statement> } ;
ARTICLE: "db-tuples-tutorial" "Tuple database tutorial"
"Let's make a tuple and store it in a database. To follow along, click on each code example and run it in the listener. If you forget to run an example, just start at the top and run them all again in order." $nl

View File

@ -157,32 +157,42 @@ HELP: unknown-modifier
ARTICLE: "db.types" "Database types"
"The " { $vocab-link "db.types" } " vocabulary maps Factor types to database types." $nl
"Primary keys:"
{ $subsection +db-assigned-id+ }
{ $subsection +user-assigned-id+ }
{ $subsection +random-id+ }
{ $subsections
+db-assigned-id+
+user-assigned-id+
+random-id+
}
"Null and boolean types:"
{ $subsection NULL }
{ $subsection BOOLEAN }
{ $subsections
NULL
BOOLEAN
}
"Text types:"
{ $subsection VARCHAR }
{ $subsection TEXT }
{ $subsections
VARCHAR
TEXT
}
"Number types:"
{ $subsection INTEGER }
{ $subsection BIG-INTEGER }
{ $subsection SIGNED-BIG-INTEGER }
{ $subsection UNSIGNED-BIG-INTEGER }
{ $subsection DOUBLE }
{ $subsection REAL }
{ $subsections
INTEGER
BIG-INTEGER
SIGNED-BIG-INTEGER
UNSIGNED-BIG-INTEGER
DOUBLE
REAL
}
"Calendar types:"
{ $subsection DATE }
{ $subsection DATETIME }
{ $subsection TIME }
{ $subsection TIMESTAMP }
{ $subsections
DATE
DATETIME
TIME
TIMESTAMP
}
"Factor byte-arrays:"
{ $subsection BLOB }
{ $subsections BLOB }
"Arbitrary Factor objects:"
{ $subsection FACTOR-BLOB }
{ $subsections FACTOR-BLOB }
"Factor URLs:"
{ $subsection URL } ;
{ $subsections URL } ;
ABOUT: "db.types"

View File

@ -6,23 +6,29 @@ IN: debugger
ARTICLE: "debugger" "The debugger"
"Caught errors can be logged in human-readable form:"
{ $subsection print-error }
{ $subsection try }
{ $subsections
print-error
try
}
"User-defined errors can have customized printed representation by implementing a generic word:"
{ $subsection error. }
{ $subsections error. }
"A number of words facilitate interactive debugging of errors:"
{ $subsection :error }
{ $subsection :s }
{ $subsection :r }
{ $subsection :c }
{ $subsection :get }
{ $subsections
:error
:s
:r
:c
:get
}
"Most types of errors are documented, and the documentation is instantly accessible:"
{ $subsection :help }
{ $subsections :help }
"If the error was restartable, a list of restarts is also printed, and a numbered restart can be invoked:"
{ $subsection :1 }
{ $subsection :2 }
{ $subsection :3 }
{ $subsection :res }
{ $subsections
:1
:2
:3
:res
}
"You can read more about error handling in " { $link "errors" } "."
$nl
"Note that in Factor, the debugger is a tool for printing and inspecting errors, not for walking through code. For the latter, see " { $link "ui-walker" } "." ;

View File

@ -5,8 +5,8 @@ ARTICLE: "definitions.icons" "Definition icons"
"The " { $vocab-link "definitions.icons" } " vocabulary associates common definition types with icons."
{ $definition-icons }
"Looking up the icon associated with a definition:"
{ $subsection definition-icon }
{ $subsections definition-icon }
"Defining new icons:"
{ $subsection POSTPONE: ICON: } ;
{ $subsections POSTPONE: ICON: } ;
ABOUT: "definitions.icons"

View File

@ -44,13 +44,17 @@ $nl
"Unlike " { $link "tuple-subclassing" } ", which expresses " { $emphasis "is-a" } " relationships by statically including the methods and slots of the superclass in all subclasses, consultation forwards generic word calls to another distinct object."
$nl
"Defining new protocols:"
{ $subsection POSTPONE: PROTOCOL: }
{ $subsection define-protocol }
{ $subsections
POSTPONE: PROTOCOL:
define-protocol
}
"Defining new protocols consisting of slot accessors:"
{ $subsection POSTPONE: SLOT-PROTOCOL: }
{ $subsections POSTPONE: SLOT-PROTOCOL: }
"Defining consultation:"
{ $subsection POSTPONE: CONSULT: }
{ $subsection define-consult }
{ $subsections
POSTPONE: CONSULT:
define-consult
}
"Every tuple class has an associated protocol consisting of all of its slot accessor methods. The " { $vocab-link "delegate.protocols" } " vocabulary defines formal protocols for the various informal protocols used in the Factor core, such as " { $link "sequence-protocol" } ", " { $link "assocs-protocol" } " or " { $link "stream-protocol" } ;
ABOUT: "delegate"

View File

@ -99,31 +99,39 @@ ARTICLE: "deques" "Deques"
"The " { $vocab-link "deques" } " vocabulary implements the deque data structure which has constant-time insertion and removal of elements at both ends."
$nl
"Deques must be instances of a mixin class:"
{ $subsection deque }
{ $subsections deque }
"Deques must implement a protocol."
$nl
"Querying the deque:"
{ $subsection peek-front }
{ $subsection peek-back }
{ $subsection deque-empty? }
{ $subsection deque-member? }
{ $subsections
peek-front
peek-back
deque-empty?
deque-member?
}
"Adding and removing elements:"
{ $subsection push-front* }
{ $subsection push-back* }
{ $subsection pop-front* }
{ $subsection pop-back* }
{ $subsection clear-deque }
{ $subsections
push-front*
push-back*
pop-front*
pop-back*
clear-deque
}
"Working with node objects output by " { $link push-front* } " and " { $link push-back* } ":"
{ $subsection delete-node }
{ $subsection node-value }
{ $subsections
delete-node
node-value
}
"Utility operations built in terms of the above:"
{ $subsection push-front }
{ $subsection push-all-front }
{ $subsection push-back }
{ $subsection push-all-back }
{ $subsection pop-front }
{ $subsection pop-back }
{ $subsection slurp-deque }
{ $subsections
push-front
push-all-front
push-back
push-all-back
pop-front
pop-back
slurp-deque
}
"When using a deque as a queue, the convention is to queue elements with " { $link push-front } " and deque them with " { $link pop-back } "." ;
ABOUT: "deques"

View File

@ -42,17 +42,21 @@ $nl
"The two main supported operations are equating two elements, which joins their equivalence classes, and checking if two elements belong to the same equivalence class. Both operations have the time complexity of the inverse Ackermann function, which for all intents and purposes is constant time."
$nl
"The class of disjoint sets:"
{ $subsection disjoint-set }
{ $subsections disjoint-set }
"Creating new disjoint sets:"
{ $subsection <disjoint-set> }
{ $subsection assoc>disjoint-set }
{ $subsections
<disjoint-set>
assoc>disjoint-set
}
"Queries:"
{ $subsection equiv? }
{ $subsection equiv-set-size }
{ $subsections
equiv?
equiv-set-size
}
"Adding elements:"
{ $subsection add-atom }
{ $subsections add-atom }
"Equating elements:"
{ $subsection equate }
{ $subsections equate }
"Additionally, disjoint sets implement the " { $link clone } " generic word." ;
ABOUT: "disjoint-sets"

View File

@ -6,22 +6,28 @@ ARTICLE: "dlists" "Double-linked lists"
"A double-linked list is the canonical implementation of a " { $link deque } "."
$nl
"Double-linked lists form a class:"
{ $subsection dlist }
{ $subsection dlist? }
{ $subsections
dlist
dlist?
}
"Constructing a double-linked list:"
{ $subsection <dlist> }
{ $subsections <dlist> }
"Double-linked lists support all the operations of the deque protocol (" { $link "deques" } ") as well as the following."
$nl
"Iterating over elements:"
{ $subsection dlist-each }
{ $subsection dlist-find }
{ $subsection dlist-filter }
{ $subsection dlist-any? }
{ $subsections
dlist-each
dlist-find
dlist-filter
dlist-any?
}
"Deleting a node matching a predicate:"
{ $subsection delete-node-if* }
{ $subsection delete-node-if }
{ $subsections
delete-node-if*
delete-node-if
}
"Search deque implementation:"
{ $subsection <hashed-dlist> } ;
{ $subsections <hashed-dlist> } ;
ABOUT: "dlists"

View File

@ -93,32 +93,45 @@ HELP: clear-doc
ARTICLE: "documents" "Documents"
"The " { $vocab-link "documents" } " vocabulary implements " { $emphasis "documents" } ", which are models storing a passage of text as a sequence of lines. Operations are defined for operating on subranges of the text, and " { $link "ui.gadgets.editors" } " can display these models."
{ $subsection document }
{ $subsection <document> }
{ $subsections
document
<document>
}
"Getting and setting the contents of the entire document:"
{ $subsection doc-string }
{ $subsection set-doc-string }
{ $subsection clear-doc }
{ $subsections
doc-string
set-doc-string
clear-doc
}
"Getting and setting subranges:"
{ $subsection doc-line }
{ $subsection doc-lines }
{ $subsection doc-range }
{ $subsection set-doc-range }
{ $subsection remove-doc-range }
{ $subsections
doc-line
doc-lines
doc-range
set-doc-range
remove-doc-range
}
"A combinator:"
{ $subsection each-line }
{ $subsection "document-locs" }
{ $subsection "documents.elements" }
{ $subsections each-line }
"More info:"
{ $subsections
"document-locs"
"documents.elements"
}
{ $see-also "ui.gadgets.editors" } ;
ARTICLE: "document-locs" "Document locations"
"Locations in the document are represented as a line/column number pair, with both indices being zero-based. There are some words for manipulating locations:"
{ $subsection +col }
{ $subsection +line }
{ $subsection =col }
{ $subsection =line }
{ $subsections
+col
+line
=col
=line
}
"Miscellaneous words for working with locations:"
{ $subsection lines-equal? }
{ $subsection validate-loc } ;
{ $subsections
lines-equal?
validate-loc
} ;
ABOUT: "documents"

View File

@ -37,14 +37,18 @@ ARTICLE: "documents.elements" "Document elements"
"Document elements, defined in the " { $vocab-link "documents.elements" } " vocabulary, overlay a hierarchy of structure on top of the flat sequence of characters presented by the document."
$nl
"The different types of document elements correspond to the standard editing taxonomy:"
{ $subsection char-elt }
{ $subsection one-word-elt }
{ $subsection word-elt }
{ $subsection one-line-elt }
{ $subsection line-elt }
{ $subsection doc-elt }
{ $subsections
char-elt
one-word-elt
word-elt
one-line-elt
line-elt
doc-elt
}
"New locations can be created out of existing ones by finding the start or end of a document element nearest to a given location."
{ $subsection prev-elt }
{ $subsection next-elt } ;
{ $subsections
prev-elt
next-elt
} ;
ABOUT: "documents.elements"

View File

@ -4,15 +4,15 @@ IN: editors
ARTICLE: "editor" "Editor integration"
"Factor development is best done with one of the supported editors; this allows you to quickly jump to definitions from the Factor environment."
{ $subsection edit }
{ $subsections edit }
"Depending on the editor you are using, you must load one of the child vocabularies of the " { $vocab-link "editors" } " vocabulary, for example " { $vocab-link "editors.emacs" } ":"
{ $code "USE: editors.emacs" }
"If you intend to always use the same editor, it helps to have it load during stage 2 bootstrap. Place the code to load and possibly configure it in the " { $link "factor-boot-rc" } "."
$nl
"Editor integration vocabularies store a quotation in a global variable when loaded:"
{ $subsection edit-hook }
{ $subsections edit-hook }
"If a syntax error was thrown while loading a source file, you can jump to the location of the error in your editor:"
{ $subsection :edit } ;
{ $subsections :edit } ;
ABOUT: "editor"

View File

@ -60,11 +60,15 @@ ARTICLE: "environment" "Environment variables"
"The " { $vocab-link "environment" } " vocabulary interfaces to the platform-dependent mechanism for setting environment variables." $nl
"Windows CE has no concept of environment variables, so these words are undefined on that platform." $nl
"Reading environment variables:"
{ $subsection os-env }
{ $subsection os-envs }
{ $subsections
os-env
os-envs
}
"Writing environment variables:"
{ $subsection set-os-env }
{ $subsection unset-os-env }
{ $subsection set-os-envs } ;
{ $subsections
set-os-env
unset-os-env
set-os-envs
} ;
ABOUT: "environment"

View File

@ -17,7 +17,9 @@ HELP: eval>string
ARTICLE: "eval" "Evaluating strings at runtime"
"The " { $vocab-link "eval" } " vocabulary implements support for evaluating strings at runtime."
{ $subsection POSTPONE: eval( }
{ $subsection eval>string } ;
{ $subsections
POSTPONE: eval(
eval>string
} ;
ABOUT: "eval"

View File

@ -19,34 +19,40 @@ HELP: (write-farkup)
ARTICLE: "farkup-ast" "Farkup syntax tree nodes"
"The " { $link parse-farkup } " word outputs a tree of nodes corresponding to the Farkup syntax of the input string. This tree can be programatically traversed and mutated before being passed on to " { $link write-farkup } "."
{ $subsection heading1 }
{ $subsection heading2 }
{ $subsection heading3 }
{ $subsection heading4 }
{ $subsection strong }
{ $subsection emphasis }
{ $subsection superscript }
{ $subsection subscript }
{ $subsection inline-code }
{ $subsection paragraph }
{ $subsection list-item }
{ $subsection unordered-list }
{ $subsection ordered-list }
{ $subsection table }
{ $subsection table-row }
{ $subsection link }
{ $subsection image }
{ $subsection code } ;
{ $subsections
heading1
heading2
heading3
heading4
strong
emphasis
superscript
subscript
inline-code
paragraph
list-item
unordered-list
ordered-list
table
table-row
link
image
code
} ;
ARTICLE: "farkup" "Farkup"
"The " { $vocab-link "farkup" } " vocabulary implements Farkup (Factor mARKUP), a simple markup language. Farkup was loosely based on the markup languages employed by MediaWiki and " { $url "http://reddit.com" } "."
$nl
"The main entry points for converting Farkup to HTML:"
{ $subsection convert-farkup }
{ $subsection write-farkup }
{ $subsections
convert-farkup
write-farkup
}
"The syntax tree of a piece of Farkup can also be inspected and modified:"
{ $subsection parse-farkup }
{ $subsection (write-farkup) }
{ $subsection "farkup-ast" } ;
{ $subsections
parse-farkup
(write-farkup)
"farkup-ast"
} ;
ABOUT: "farkup"

View File

@ -26,16 +26,22 @@ HELP: font-with-foreground
ARTICLE: "fonts" "Fonts"
"The " { $vocab-link "fonts" } " vocabulary implements a data type for fonts that other vocabularies, for example " { $link "ui" } ", can use. A font combines a font name, size, style, and color information into a single object."
{ $subsection font }
{ $subsection <font> }
{ $subsections
font
<font>
}
"Modifying fonts:"
{ $subsection font-with-foreground }
{ $subsection font-with-background }
{ $subsections
font-with-foreground
font-with-background
}
"Useful constants:"
{ $subsection monospace-font }
{ $subsection sans-serif-font }
{ $subsection serif-font }
{ $subsections
monospace-font
sans-serif-font
serif-font
}
"A data type for font metrics. The " { $vocab-link "fonts" } " vocabulary does not provide any means of computing font metrics, it simply defines a common data type that other vocabularies, such as " { $vocab-link "ui.text" } " may use:"
{ $subsection metrics } ;
{ $subsections metrics } ;
ABOUT: "fonts"

View File

@ -129,10 +129,11 @@ HELP: strftime
ARTICLE: "formatting" "Formatted printing"
"The " { $vocab-link "formatting" } " vocabulary is used for formatted printing."
{ $subsection printf }
{ $subsection sprintf }
{ $subsection strftime }
;
{ $subsections
printf
sprintf
strftime
} ;
ABOUT: "formatting"

View File

@ -78,17 +78,21 @@ ARTICLE: "fry" "Fried quotations"
"The " { $vocab-link "fry" } " vocabulary implements " { $emphasis "fried quotation" } ". Conceptually, fried quotations are quotations with “holes” (more formally, " { $emphasis "fry specifiers" } "), and the holes are filled in when the fried quotation is pushed on the stack."
$nl
"Fried quotations are started by a special parsing word:"
{ $subsection POSTPONE: '[ }
{ $subsections POSTPONE: '[ }
"There are two types of fry specifiers; the first can hold a value, and the second “splices” a quotation, as if it were inserted without surrounding brackets:"
{ $subsection _ }
{ $subsection @ }
{ $subsections
_
@
}
"The holes are filled in with the top of stack going in the rightmost hole, the second item on the stack going in the second hole from the right, and so on."
{ $subsection "fry.examples" }
{ $subsection "fry.philosophy" }
{ $subsections
"fry.examples"
"fry.philosophy"
}
"Fry is implemented as a parsing word which reads a quotation and scans for occurrences of " { $link _ } " and " { $link @ } "; these words are not actually executed, and doing so raises an error (this can happen if they're accidentally used outside of a fry)."
$nl
"Fried quotations can also be constructed without using a parsing word; this is useful when meta-programming:"
{ $subsection fry }
{ $subsections fry }
"Fried quotations are an abstraction on top of the " { $link "compositional-combinators" } "; their use is encouraged over the combinators, because often the fry form is shorter and clearer than the combinator form." ;
ABOUT: "fry"

View File

@ -81,12 +81,14 @@ ARTICLE: "furnace.actions.page.example" "Furnace page action example"
ARTICLE: "furnace.actions.page" "Furnace page actions"
"Page actions implement the common case of an action that simply serves a Chloe template in response to a GET request."
{ $subsection page-action }
{ $subsection <page-action> }
{ $subsections
page-action
<page-action>
}
"When using a page action, instead of setting the " { $slot "display" } " slot, the " { $slot "template" } " slot is set instead. The " { $slot "init" } ", " { $slot "authorize" } ", " { $slot "validate" } " and " { $slot "submit" } " slots can still be set as usual."
$nl
"The " { $slot "template" } " slot of a " { $link page-action } " contains a pair with shape " { $snippet "{ responder name }" } ", where " { $snippet "responder" } " is a responder class, usually a subclass of " { $link dispatcher } ", and " { $snippet "name" } " is the name of a template file, without the " { $snippet ".xml" } " extension, relative to the directory containing the responder's vocabulary source file."
{ $subsection "furnace.actions.page.example" } ;
{ $subsections "furnace.actions.page.example" } ;
ARTICLE: "furnace.actions.config" "Furnace action configuration"
"Actions have the following slots:"
@ -104,10 +106,10 @@ ARTICLE: "furnace.actions.validation" "Form validation with actions"
"The action code is set up so that the " { $slot "init" } " quotation can validate query parameters, and the " { $slot "validate" } " quotation can validate POST parameters."
$nl
"A word to validate parameters and make them available as HTML form values (see " { $link "html.forms.values" } "); typically this word is invoked from the " { $slot "init" } " and " { $slot "validate" } " quotations:"
{ $subsection validate-params }
{ $subsections validate-params }
"The above word expects an association list mapping parameter names to validator quotations; validator quotations can use the words in the "
"Custom validation logic can invoke a word when validation fails; " { $link validate-params } " invokes this word for you:"
{ $subsection validation-failed }
{ $subsections validation-failed }
"If validation fails, no more action code is executed, and the client is redirected back to the originating page, where validation errors can be displayed. Note that validation errors are rendered automatically by the " { $link "html.components" } " words, and in particular, " { $link "html.templates.chloe" } " use these words." ;
ARTICLE: "furnace.actions.lifecycle" "Furnace action lifecycle"
@ -133,7 +135,7 @@ ARTICLE: "furnace.actions.lifecycle" "Furnace action lifecycle"
ARTICLE: "furnace.actions.impl" "Furnace actions implementation"
"The following parametrized constructor should be called from constructors for subclasses of " { $link action } ":"
{ $subsection new-action } ;
{ $subsections new-action } ;
ARTICLE: "furnace.actions" "Furnace actions"
"The " { $vocab-link "furnace.actions" } " vocabulary implements a type of responder, called an " { $emphasis "action" } ", which handles the form validation lifecycle."
@ -141,18 +143,18 @@ $nl
"Other than form validation capability, actions are also often simpler to use than implementing new responders directly, since creating a new class is not required, and the action dispatches on the request type (GET, HEAD, or POST)."
$nl
"The class of actions:"
{ $subsection action }
{ $subsections action }
"Creating a new action:"
{ $subsection <action> }
{ $subsections <action> }
"Once created, an action needs to be configured; typically the creation and configuration of an action is encapsulated into a single word:"
{ $subsection "furnace.actions.config" }
{ $subsections "furnace.actions.config" }
"Validating forms with actions:"
{ $subsection "furnace.actions.validation" }
{ $subsections "furnace.actions.validation" }
"More about the form validation lifecycle:"
{ $subsection "furnace.actions.lifecycle" }
{ $subsections "furnace.actions.lifecycle" }
"A convenience class:"
{ $subsection "furnace.actions.page" }
{ $subsections "furnace.actions.page" }
"Low-level features:"
{ $subsection "furnace.actions.impl" } ;
{ $subsections "furnace.actions.impl" } ;
ABOUT: "furnace.actions"

Some files were not shown because too many files have changed in this diff Show More