diff --git a/TODO.txt b/TODO.txt index 4c1135462b..78b1e0d41c 100644 --- a/TODO.txt +++ b/TODO.txt @@ -3,7 +3,8 @@ - callback scheduling issue - error popup obscures input area - ui docs -- vocab popup: sort +- test factor on linux/ppc +- auto-generate error-index + 0.88: diff --git a/core/debugger.facts b/core/debugger.facts index 66e0323dfe..555b8d9950 100644 --- a/core/debugger.facts +++ b/core/debugger.facts @@ -37,24 +37,23 @@ HELP: try { $description "Calls the quotation. If it throws an error, logs the error to the default stream and restores the data stack." } ; HELP: expired-error. -{ $values { "obj" "an error" } } { $error-description "Thrown by " { $link alien-address } " and " { $link alien-invoke } " if an " { $link alien } " object passed in as a parameter has expired. Alien objects expire if they are saved an image which is subsequently loaded; this prevents a certain class of programming errors, usually attempts to use uninitialized objects, since holding a C address is meaningless between sessions." } { $notes "You can check if an alien object has expired by calling " { $link expired? } "." } ; HELP: io-error. -{ $values { "error" "an object" } } { $error-description "Thrown by the C streams I/O primitives if an I/O error occurs." } ; HELP: undefined-word-error. -{ $values { "obj" "an object" } } { $error-description "Thrown if an attempt is made to call a word which was defined by " { $link POSTPONE: DEFER: } "." } ; HELP: type-check-error. -{ $values { "obj" "an object" } } { $error-description "Thrown by various primitives if one of the inputs does not have the expected type. Generic words throw " { $link no-method } " and " { $link no-math-method } " errors in such cases instead." } ; +HELP: divide-by-zero-error. +{ $error-description "This error is thrown when " { $link / } " or " { $link /i } " is called with with a zero denominator." } +{ $see-also "division-by-zero" } ; + HELP: signal-error. -{ $values { "obj" "an object" } } { $error-description "Thrown by the runtime when a Unix signal is received. While signal numbers are system-specific, the following are relatively standard:" { $list @@ -66,27 +65,21 @@ HELP: signal-error. } ; HELP: negative-array-size-error. -{ $values { "obj" "an object" } } { $error-description "Thrown by " { $link } ", " { $link } ", " { $link } " and " { $link } " if a negative capacity is specified." } ; HELP: c-string-error. -{ $values { "obj" "an object" } } { $error-description "Thrown by " { $link alien-invoke } " and various primitives if a string containing null bytes, or characters with values higher than 255 is passed in where a C string is expected. See " { $link "c-strings" } "." } ; HELP: ffi-error. -{ $values { "obj" "an object" } } { $error-description "Thrown by " { $link dlopen } " and " { $link dlsym } " if a problem occurs while loading a native library or looking up a symbol. See " { $link "alien" } "." } ; HELP: heap-scan-error. -{ $values { "obj" "an object" } } { $error-description "Thrown if " { $link next-object } " is called outside of a " { $link begin-scan } "/" { $link end-scan } " pair." } ; HELP: undefined-symbol-error. -{ $values { "obj" "an object" } } { $error-description "Thrown if a previously-compiled " { $link alien-invoke } " call refers to a native library symbol which no longer exists." } ; HELP: user-interrupt. -{ $values { "obj" "an object" } } { $error-description "Thrown by the " { $snippet "t" } " command in the FEP." } ; HELP: datastack-underflow. diff --git a/core/errors.factor b/core/errors.factor index 5f11ff2c6a..b6af228a58 100644 --- a/core/errors.factor +++ b/core/errors.factor @@ -59,7 +59,7 @@ M: condition compute-restarts PREDICATE: array kernel-error ( obj -- ? ) dup first \ kernel-error eq? [ - second 0 18 between? + second 0 19 between? ] [ drop f ] if ; diff --git a/core/handbook/handbook.facts b/core/handbook/handbook.facts index 2a95169e5b..1e54c84307 100644 --- a/core/handbook/handbook.facts +++ b/core/handbook/handbook.facts @@ -66,7 +66,6 @@ ARTICLE: "primitive-index" "Primitive index" { $outliner [ all-words [ primitive? ] subset ] } ; ARTICLE: "error-index" "Error index" -{ $subsection /0 } { $subsection alien-callback-error } { $subsection alien-invoke-error } { $subsection assert } @@ -84,6 +83,7 @@ ARTICLE: "error-index" "Error index" { $subsection condition } { $subsection datastack-overflow. } { $subsection datastack-underflow. } +{ $subsection divide-by-zero-error. } { $subsection empty-queue } { $subsection expired-error. } { $subsection ffi-error. } diff --git a/core/math/integer.factor b/core/math/integer.factor index 637b6e4539..fb2a7a1378 100644 --- a/core/math/integer.factor +++ b/core/math/integer.factor @@ -42,12 +42,9 @@ IN: math-internals : fraction> ( a b -- a/b ) dup 1 number= [ drop ] [ (fraction>) ] if ; inline -TUPLE: /0 ; -: /0 ( -- * ) throw ; - M: integer / dup zero? [ - /0 + /i ] [ dup 0 < [ [ neg ] 2apply ] when 2dup gcd nip tuck /i >r /i r> fraction> diff --git a/core/math/integer.facts b/core/math/integer.facts index 78503adaa7..9ebebc571e 100644 --- a/core/math/integer.facts +++ b/core/math/integer.facts @@ -212,7 +212,3 @@ HELP: bignum-shift ( x y -- z ) { $values { "x" "a bignum" } { "y" "a bignum" } { "z" "a bignum" } } { $description "Primitive version of " { $link shift } "." } { $warning "This word does not perform type checking, and passing objects of the wrong type can crash the runtime. User code should call the generic word " { $link shift } " instead." } ; - -HELP: /0 -{ $error-description "This error is thrown when " { $link / } " is called with two integer inputs, the denominator being zero." } -{ $notes "Floating point division by zero does not raise an error at all, whereas integer division by zero in " { $link /i } " typically raises an operating system signal (see " { $link signal-error. } ")." } ; diff --git a/core/test/collections/hashtables.factor b/core/test/collections/hashtables.factor index b1816c051a..6e2df4ee4f 100644 --- a/core/test/collections/hashtables.factor +++ b/core/test/collections/hashtables.factor @@ -9,6 +9,7 @@ USE: sequences-internals USE: hashtables USE: io USE: prettyprint +USE: errors [ "hi" V{ 1 2 3 } hash ] unit-test-fails diff --git a/core/test/kernel.factor b/core/test/kernel.factor index efb36b0409..b6cb453eb8 100644 --- a/core/test/kernel.factor +++ b/core/test/kernel.factor @@ -25,7 +25,7 @@ sequences test errors math-internals ; [ [ \ + = ] ] [ \ + [ = ] curry ] unit-test ! Make sure we report the correct error on stack underflow -[ { kernel-error 11 f f } ] +[ { kernel-error 12 f f } ] [ [ clear drop ] catch ] unit-test [ -7 ] unit-test-fails diff --git a/core/test/parser.factor b/core/test/parser.factor index 9df93fb55d..2f96bae8dc 100644 --- a/core/test/parser.factor +++ b/core/test/parser.factor @@ -96,7 +96,7 @@ unit-test "cont" set [ "\ + 1 2 3 4" - + parse-interactive "cont" get continue-with ] catch "0 :res" eval diff --git a/core/tools/errors.factor b/core/tools/errors.factor index 120f819dcd..aee7baec81 100644 --- a/core/tools/errors.factor +++ b/core/tools/errors.factor @@ -20,6 +20,9 @@ words definitions ; "Object type: " write dup fourth class . "Expected type: " write third type>class . ; +: divide-by-zero-error. ( obj -- ) + "Division by zero" print drop ; + : signal-error. ( obj -- ) "Operating system signal " write third . ; @@ -70,6 +73,7 @@ DEFER: objc-error. ( alien -- ) io-error. undefined-word-error. type-check-error. + divide-by-zero-error. signal-error. negative-array-size-error. c-string-error. @@ -106,9 +110,6 @@ M: no-method error. M: no-math-method summary drop "No suitable arithmetic method" ; -M: /0 summary - drop "Division by zero" ; - M: bad-escape summary drop "Invalid escape code" ; diff --git a/core/tools/word-tools.factor b/core/tools/word-tools.factor index 6c756bc9f9..4df47eaa3e 100644 --- a/core/tools/word-tools.factor +++ b/core/tools/word-tools.factor @@ -51,4 +51,4 @@ generic completion ; [ word-name ] swap completions ; : apropos ( str -- ) - all-words word-completions [ summary ] each ; + all-words word-completions [ summary print ] each ; diff --git a/core/ui/tools/search.factor b/core/ui/tools/search.factor index 9fea970028..d84f7bef2f 100644 --- a/core/ui/tools/search.factor +++ b/core/ui/tools/search.factor @@ -119,7 +119,7 @@ M: live-search focusable-child* live-search-field ; "Word search" show-titled-popup ; : show-vocab-words ( workspace vocab -- ) - "" over words + "" over words natural-sort "Words in " rot append show-titled-popup ; : show-help-search ( workspace -- ) diff --git a/vm/bignum.c b/vm/bignum.c index 26589d6927..6f3329a86e 100644 --- a/vm/bignum.c +++ b/vm/bignum.c @@ -169,7 +169,7 @@ s48_bignum_divide(bignum_type numerator, bignum_type denominator, { if (BIGNUM_ZERO_P (denominator)) { - raise(SIGFPE); + divide_by_zero_error(); return; } if (BIGNUM_ZERO_P (numerator)) @@ -241,7 +241,7 @@ s48_bignum_quotient(bignum_type numerator, bignum_type denominator) { if (BIGNUM_ZERO_P (denominator)) { - raise(SIGFPE); + divide_by_zero_error(); return (BIGNUM_OUT_OF_BAND); } if (BIGNUM_ZERO_P (numerator)) @@ -294,7 +294,7 @@ s48_bignum_remainder(bignum_type numerator, bignum_type denominator) { if (BIGNUM_ZERO_P (denominator)) { - raise(SIGFPE); + divide_by_zero_error(); return (BIGNUM_OUT_OF_BAND); } if (BIGNUM_ZERO_P (numerator)) diff --git a/vm/run.c b/vm/run.c index 6b47d86293..ca3b476dc9 100644 --- a/vm/run.c +++ b/vm/run.c @@ -350,7 +350,12 @@ void type_error(CELL type, CELL tagged) general_error(ERROR_TYPE,tag_fixnum(type),tagged,true); } +void divide_by_zero_error(void) +{ + general_error(ERROR_DIVIDE_BY_ZERO,F,F,true); +} + void memory_error(void) { - general_error(ERROR_MEMORY,F,F,false); + general_error(ERROR_MEMORY,F,F,true); } diff --git a/vm/run.h b/vm/run.h index dda8f44f2e..033c6389af 100644 --- a/vm/run.h +++ b/vm/run.h @@ -155,6 +155,7 @@ typedef enum ERROR_IO, ERROR_UNDEFINED_WORD, ERROR_TYPE, + ERROR_DIVIDE_BY_ZERO, ERROR_SIGNAL, ERROR_NEGATIVE_ARRAY_SIZE, ERROR_C_STRING, @@ -193,6 +194,7 @@ void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks); void memory_protection_error(CELL addr, int signal); void signal_error(int signal); void type_error(CELL type, CELL tagged); +void divide_by_zero_error(void); void memory_error(void); void primitive_throw(void); void primitive_die(void);