1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-06 15:40:29 +02:00
Commit graph

9315 commits

Author SHA1 Message Date
Mark H Weaver
9b9ef10cf0 Improve handling of signed zeroes
* libguile/numbers.c (scm_abs): (abs -0.0) now returns 0.0.  Previously
  it returned -0.0.  Also move the REALP case above the BIGP case,
  and consider it SCM_LIKELY to be REALP if not INUMP.
  (scm_difference): (- 0 0.0) now returns -0.0.  Previously it returned
  0.0.  Also make sure that (- 0 0.0+0.0i) will return -0.0-0.0i.

* test-suite/tests/numbers.test (abs, -): Add test cases, and change
  some tests to use `eqv?' instead of `=', in order to test exactness
  and distinguish signed zeroes.
2011-02-02 21:28:18 +01:00
Mark H Weaver
8deddc948d Trigonometric functions return exact numbers in some cases
* libguile/numbers.c (scm_sin, scm_cos, scm_tan, scm_asin, scm_acos,
  scm_atan, scm_sinh, scm_cosh, scm_tanh, scm_sys_asinh, scm_sys_acosh,
  scm_sys_atanh): Return an exact result in some cases.

* test-suite/tests/numbers.test: Add test cases.

* NEWS: Add NEWS entry
2011-02-02 21:26:35 +01:00
Mark H Weaver
2e2743113a Fix min' and max' handling of NaNs, infinities, and signed zeroes
* libguile/numbers.c (scm_min, scm_max): Properly order the real
  infinities and NaNs, per R6RS, and also take care to handle signed
  zeroes properly.  Note that this ordering is different than that of
  `<', `>', `<=', and `>=', which return #f if any argument is a real
  NaN, and consider the real zeroes to be equal.  The relevant real
  infinity (-inf.0 for min, +inf.0 for max) beats everything, including
  NaNs, and NaNs beat everything else.  Previously these were handled
  improperly in some cases, e.g.:
  (min 1/2 +nan.0) now returns +nan.0 (previously returned 0.5),
  (max 1/2 +nan.0) now returns +nan.0 (previously returned 0.5),
  (min -inf.0 +nan.0) now returns -inf.0 (previously returned +nan.0),
  (max +inf.0 +nan.0) now returns +inf.0 (previously returned +nan.0),
  (min -0.0  0.0) now returns -0.0 (previously returned  0.0),
  (max  0.0 -0.0) now returns  0.0 (previously returned -0.0),
  (max  0   -0.0) now returns  0.0 (previously returned -0.0),
  (max -0.0  0  ) now returns  0.0 (previously returned -0.0).

* test-suite/tests/numbers.test (min, max): Add many more test cases
  relating to NaNs, infinities, and signed zeroes.  Change most existing
  test cases to use `eqv?' instead of `=', in order to check exactness.
2011-02-02 21:21:21 +01:00
Ludovic Courtès
6851d3be80 Change `scm_encoding_error' to pass the port and faulty character.
* libguile/strings.c (scm_encoding_error): Remove the `from', `to', and
  `string_or_bv' parameters; add `port' and `chr'.
  (scm_to_stringn): Update accordingly.

* libguile/strings.h (scm_encoding_error): Update accordingly.

* libguile/ports.c (scm_ungetc): Update accordingly.

* libguile/print.c (iprin1, scm_write_char): Update accordingly.

* test-suite/tests/encoding-escapes.test ("display output
  errors")["ultima", "Rashomon"]: Check the arguments of
  `encoding-error'.
  ["tekniko"]: New test.

* test-suite/tests/ports.test ("string ports")["wrong encoding"]: Adjust
  to new `encoding-error' arguments.
2011-02-02 18:06:29 +01:00
Ludovic Courtès
7174bc08dd Upon port encoding error, always write as much as possible.
* libguile/print.c (display_string): Upon error, always write the
  OUTPUT_LEN bytes of output, regardless of the conversion strategy.
2011-02-02 18:06:29 +01:00
Ludovic Courtès
c62da8f891 Have read-char' & co. throw to decoding-error'.
* libguile/ports.c (scm_read_char): Mention `decoding-error' in the
  docstring.
  (get_codepoint): Change to return an error code; add `codepoint'
  output parameter.  Don't raise an error from here.
  (scm_getc): Raise an error with `scm_decoding_error' if
  `get_codepoint' returns an error.
  (scm_peek_char): Likewise.  Update docstring.

* libguile/strings.c (scm_decoding_error_key): New variable.
  (scm_decoding_error): New function.
  (scm_from_stringn): Use `scm_decoding_error' instead of
  `scm_encoding_error'.

* libguile/strings.h (scm_decoding_error): New declaration.

* test-suite/tests/ports.test ("string ports")["read-char, wrong
  encoding, error"]: Change to expect `decoding-error'.  Make sure PORT
  points past the error.
  ["read-char, wrong encoding, escape"]: Likewise.
  ["peek-char, wrong encoding, error"]: New test.

* test-suite/tests/r6rs-ports.test ("7.2.11 Binary
  Output")["put-bytevector with wrong-encoding string port"]: Change to
  expect `decoding-error'.
  ("8.2.6  Input and output ports")["transcoded-port [error handling
  mode = raise]"]: Likewise.

* test-suite/tests/rdelim.test ("read-line")["decoding error", "decoding
  error, substitute"]: New tests.

* doc/ref/api-io.texi (Reading): Update documentation of `read-char' and
  `peek-char'.
  (Line/Delimited): Update documentation of `read-line'.
2011-02-02 18:06:28 +01:00
Ludovic Courtès
2d5ef30918 Fix typo.
* libguile/srfi-1.c (scm_srfi1_concatenate_x): Fix `FUNC_NAME'.
2011-02-02 18:06:28 +01:00
Mark H Weaver
7f41099e99 Move comment about trig functions back where it belongs
* libguile/numbers.c: Move a comment about the trigonometric functions
  next to those functions.  At some point they became separated, when
  scm_expt was placed between them.
2011-02-01 21:11:31 +01:00
Mark H Weaver
5e7918077a Handle products with exact 0 differently
* libguile/numbers.c (scm_product): Handle exact 0 differently.  A
  product containing an exact 0 now returns an exact 0 if and only if
  the other arguments are all exact.  An inexact zero is returned if and
  only if the other arguments are all finite but not all exact.  If an
  infinite or NaN value is present, a NaN value is returned.
  Previously, any product containing an exact 0 yielded an exact 0,
  regardless of the other arguments.

  A note on the rationale for (* 0 0.0) returning 0.0 and not exact 0:
  The exactness propagation rules allow us to return an exact result in
  the presence of inexact arguments only if the values of the inexact
  arguments do not affect the result.  In this case, the value of the
  inexact argument _does_ affect the result, because an infinite or NaN
  value causes the result to be a NaN.

  A note on the rationale for (* 0 +inf.0) being a NaN and not exact 0:
  The R6RS requires that (/ 0 0.0) return a NaN value, and that (/ 0.0)
  return +inf.0.  We would like (/ x y) to be the same as (* x (/ y)),
  and in particular, for (/ 0 0.0) to be the same as (* 0 (/ 0.0)),
  which reduces to (* 0 +inf.0).  Therefore (* 0 +inf.0) should return
  a NaN.

* test-suite/tests/numbers.test: Add many multiplication tests.

* NEWS: Add NEWS entry.
2011-02-01 21:11:12 +01:00
Mark H Weaver
605f698026 Fix bugs in `rationalize'
* libguile/numbers.c (scm_rationalize): Fix bugs.  Previously, it
  returned exact integers unmodified, although that was incorrect if
  the epsilon was at least 1 or inexact, e.g. (rationalize 4 1) should
  return 3 per R5RS and R6RS, but previously it returned 4.  Also
  handle cases involving infinities and NaNs properly, per R6RS.

* test-suite/tests/numbers.test: Add test cases for `rationalize'.

* NEWS: Add NEWS entry
2011-02-01 21:08:52 +01:00
Mark H Weaver
bfe1f03aac Improve extensibility of expt' and integer-expt'
* libguile/numbers.c (scm_integer_expt): No longer require that the
  first argument be a number, in order to improve extensibility.  This
  allows us to efficiently raise arbitrary objects to an integer power
  as long as we can multiply those objects.  For example, this allows us
  to efficiently exponentiate matrices if we define only multiplication
  methods for matrices.  Note also that scm_expt calls this procedure
  whenever the exponent is an integer, regardless of the type of the
  first argument.  Also rearrange the order in which we test special
  cases.

* test-suite/tests/numbers.test (expt, integer-expt): Comment out tests
  that required `(expt #t 0)' and `(integer-expt #t 0)' to throw
  exceptions.  Add tests for (expt #t 2) and `(integer-expt #t 2)
  instead.

* NEWS: Add NEWS entry
2011-01-31 21:58:27 +01:00
Mark H Weaver
ac6ce16bc9 Rename {euclidean,centered}_quo_rem to {euclidean,centered}_divide
* libguile/numbers.c (euclidean_quo_rem): Rename to euclidean_divide.
  (centered_quo_rem): Rename to {euclidean,centered}_divide.

* libguile/numbers.h: Rename euclidean_quo_rem to euclidean_divide and
  centered_quo_rem to centered_divide.

* doc/ref/api-data.texi: Rename euclidean_quo_rem to euclidean_divide and
  centered_quo_rem to centered_divide.
2011-01-31 20:22:42 +01:00
Ludovic Courtès
6e0975603e Add `pointer?'.
* libguile/foreign.c (scm_pointer_p): New function.
* libguile/foreign.h (scm_pointer_p): New declaration.
* module/system/foreign.scm: Export `pointer?'.

* test-suite/tests/foreign.test ("null pointer")["pointer?"]: New
  test.
  ("make-pointer")["pointer?"]: New test.

* doc/ref/api-foreign.texi (Foreign Variables): Document `pointer?'.
2011-01-30 23:29:30 +01:00
Ludovic Courtès
690a0112e5 Remove the "has finalizer?" bit from pointer objects.
* libguile/foreign.h (SCM_POINTER_HAS_FINALIZER): Remove.

* libguile/foreign.c (scm_from_pointer): Store nothing more than
  `scm_tc7_pointer' in the type slot.
2011-01-30 23:29:30 +01:00
Mark H Weaver
2519490c50 Improve extensibility of core numeric procedures
* libguile/numbers.c (scm_quotient, scm_remainder, scm_modulo,
  scm_zero_p, scm_positive_p, scm_negative_p, scm_real_part,
  scm_imag_part, scm_numerator, scm_denominator, scm_magnitude,
  scm_angle, scm_exact_to_inexact): Change from SCM_GPROC to
  SCM_PRIMITIVE_GENERIC.  As a side effect, all of these procedures now
  have documentation strings.

  (scm_exact_p, scm_inexact_p, scm_odd_p, scm_even_p, scm_finite_p,
  scm_inf_p, scm_nan_p, scm_expt, scm_inexact_to_exact, scm_log,
  scm_log10, scm_exp, scm_sqrt): Change from SCM_DEFINE to
  SCM_PRIMITIVE_GENERIC, and make sure the code allows these functions
  to be extended in practice.

  (scm_real_part, scm_imag_part, scm_numerator, scm_denominator,
  scm_inexact_to_exact): Simplify type dispatch code.

  (scm_sqrt): Rename formal argument from x to z, since complex numbers
  are supported.

  (scm_abs): Fix empty FUNC_NAME.

* libguile/numbers.h (scm_finite_p): Add missing prototype.

  (scm_inf_p, scm_nan_p): Rename formal parameter from n to x, since
  the domain is the real numbers.

* test-suite/tests/numbers.test: Test for documentation strings.  Change
  from `expect-fail' to `pass-if' for several of these, and add tests
  for others.  Also add other tests for `real-part' and `imag-part',
  which previously had none.
2011-01-30 23:06:07 +01:00
Mark H Weaver
ff62c16828 Add two new sets of fast quotient and remainder operators
* libguile/numbers.c (scm_euclidean_quo_and_rem, scm_euclidean_quotient,
  scm_euclidean_remainder, scm_centered_quo_and_rem,
  scm_centered_quotient, scm_centered_remainder): New extensible
  procedures `euclidean/', `euclidean-quotient', `euclidean-remainder',
  `centered/', `centered-quotient', `centered-remainder'.

* libguile/numbers.h: Add function prototypes.

* module/rnrs/base.scm: Remove incorrect stub implementations of `div',
  `mod', `div-and-mod', `div0', `mod0', and `div0-and-mod0'.  Instead do
  renaming imports of `euclidean-quotient', `euclidean-remainder',
  `euclidean/', `centered-quotient', `centered-remainder', and
  `centered/', which are equivalent to the R6RS operators.

* module/rnrs/arithmetic/fixnums.scm (fxdiv, fxmod, fxdiv-and-mod,
  fxdiv0, fxmod0, fxdiv0-and-mod0): Remove redundant checks for division
  by zero and unnecessary complexity.
  (fx+/carry): Remove unneeded calls to `inexact->exact'.

* module/rnrs/arithmetic/flonums.scm (fldiv, flmod, fldiv-and-mod,
  fldiv0, flmod0, fldiv0-and-mod0): Remove redundant checks for division
  by zero and unnecessary complexity.  Remove unneeded calls to
  `inexact->exact' and `exact->inexact'

* test-suite/tests/numbers.test: (test-eqv?): New internal predicate for
  comparing numerical outputs with expected values.

  Add extensive test code for `euclidean/', `euclidean-quotient',
  `euclidean-remainder', `centered/', `centered-quotient',
  `centered-remainder'.

* test-suite/tests/r6rs-arithmetic-fixnums.test: Fix some broken test
  cases, and remove `unresolved' test markers for `fxdiv', `fxmod',
  `fxdiv-and-mod', `fxdiv0', `fxmod0', and `fxdiv0-and-mod0'.

* test-suite/tests/r6rs-arithmetic-flonums.test: Remove `unresolved'
  test markers for `fldiv', `flmod', `fldiv-and-mod', `fldiv0',
  `flmod0', and `fldiv0-and-mod0'.

* doc/ref/api-data.texi (Arithmetic): Document `euclidean/',
  `euclidean-quotient', `euclidean-remainder', `centered/',
  `centered-quotient', and `centered-remainder'.

  (Operations on Integer Values): Add cross-references to `euclidean/'
  et al, from `quotient', `remainder', and `modulo'.

* doc/ref/r6rs.texi (rnrs base): Improve documentation for `div', `mod',
  `div-and-mod', `div0', `mod0', and `div0-and-mod0'.  Add
  cross-references to `euclidean/' et al.

* NEWS: Add NEWS entry.
2011-01-30 23:00:38 +01:00
Mark H Weaver
a16982ca4f Add SCM_LIKELY and SCM_UNLIKELY for optimization
* libguile/numbers.c (scm_abs, scm_quotient, scm_remainder, scm_modulo):
  Add SCM_LIKELY and SCM_UNLIKELY in several places for optimization.

  (scm_remainder): Add comment about C99 "%" semantics.
  Strip away a redundant set of braces.
2011-01-30 23:00:27 +01:00
Mark H Weaver
c960e55600 Infinities and NaNs are no longer rational
* libguile/numbers.c (scm_rational_p): Return #f for infinities and
  NaNs, per R6RS.  Previously it returned #t for real infinities
  and NaNs.  They are still considered real by scm_real `real?'
  however, per R6RS.  Also simplify the code.

  (scm_real_p): New implementation to reflect the fact that the
  rationals and reals are no longer the same set.  Previously it just
  called scm_rational_p.

  (scm_integer_p): Simplify the code.

* test-suite/tests/numbers.test: Add test cases for `rational?'
  and `real?' applied to infinities and NaNs.

* doc/ref/api-data.texi (Real and Rational Numbers): Update docs to
  reflect the fact that infinities and NaNs are no longer rational, and
  that `real?'  no longer implies `rational?'.  Improve discussion of
  infinities and NaNs.

* NEWS: Add NEWS entries, and combine with an earlier entry about
  infinities no longer being integers.
2011-01-30 13:08:53 +01:00
Mark H Weaver
2e6e1933b4 equal?' and eqv?' are now equivalent for numbers
Change `equal?' to work like `eqv?' for numbers.
Previously they worked differently in some cases, e.g.
when comparing signed zeroes or NaNs.  For example,
(equal? 0.0 -0.0) returned #t but (eqv? 0.0 -0.0)
returned #f, and (equal? +nan.0 +nan.0) returned #f
but (eqv? +nan.0 +nan.0) returned #t.

* libguile/numbers.c (scm_real_equalp, scm_bigequal,
  scm_complex_equalp, scm_i_fraction_equalp): Move to eq.c.

* libguile/eq.c (scm_real_equalp): Compare flonums using
  real_eqv instead of ==, so that NaNs are now considered
  equal, and to distinguish signed zeroes.

  (scm_complex_equalp): Compare real and imaginary
  components using real_eqv instead of ==, so that NaNs are
  now considered equal, and to distinguish signed zeroes.

  (scm_bigequal): Use scm_i_bigcmp instead of duplicating it.

  (real_eqv): Test for NaNs using isnan(x) instead of
  (x != x), and use SCM_UNLIKELY for optimization.

  (scm_eqv_p): Use scm_bigequal, scm_real_equalp,
  scm_complex_equalp, and scm_i_fraction_equalp to compare
  numbers, instead of inline code.  Those predicates now do
  what scm_eqv_p formerly did internally.  Replace if
  statements with switch statements, as is done in
  scm_equal_p.  Remove useless code to check equality of
  fractions with different SCM_CELL_TYPEs; this was for a
  tentative "lazy reduction bit" which was never developed.

  (scm_eqv_p, scm_equal_p): Remove useless code to check
  equality between inexact reals and non-real complex numbers
  with zero imaginary part.  Such numbers do not exist,
  because the current code is careful to never create them.

* test-suite/tests/numbers.test: Add test cases for
  `eqv?' and `equal?'.  Change existing test case for
  `(equal? +nan.0 +nan.0)' to expect #t instead of #f.

* NEWS: Add NEWS entries.
2011-01-30 13:08:47 +01:00
Ludovic Courtès
0c247c332b Add missing include for MinGW.
* libguile/ports.h: Include <unistd.h>.
2011-01-29 22:28:48 +01:00
Ludovic Courtès
e91f21dc10 Make inet-ntop' and inet-pton' available even when !HAVE_IPV6.
* libguile/socket.c (scm_inet_pton, scm_inet_ntop): Move out of `#ifdef
  HAVE_IPV6' and conditionalize the IPv6-specific bits.  Reported by
  Jan Nieuwenhuizen <janneke@gnu.org>.
2011-01-29 22:26:42 +01:00
Ludovic Courtès
d21a1dc841 Have recv!', send', etc. accept a bytevector.
* libguile/socket.c (scm_recv, scm_send, scm_recvfrom, scm_sendto):
  Expect the buffer to be a bytevector.  Move the string-handling
  code under `#if SCM_ENABLE_DEPRECATED == 1' and issue a deprecation
  warning.

* test-suite/tests/socket.test ("AF_UNIX/SOCK_DGRAM")["sendto",
  "sendto/sockaddr"]: Adjust accordingly.

* doc/ref/posix.texi (Network Sockets and Communication): Update
  documentation of `recv!', `send', `recvfrom!', and `sendto'.
2011-01-29 21:36:59 +01:00
Mark H Weaver
b5c40589ec Fix bugs when negating SCM_MOST_POSITIVE_FIXNUM+1
* libguile/numbers.c (scm_difference, scm_product):
  Fix bugs when negating SCM_MOST_POSITIVE_FIXNUM+1,
  aka -SCM_MOST_NEGATIVE_FIXNUM.  Previously, these cases
  failed to normalize the result to a fixnum, causing
  `=', `eqv?' and `equal?' to fail, e.g.:
  (= most-negative-fixnum (- 0 (- most-negative-fixnum)))
  (= most-negative-fixnum (* -1 (- most-negative-fixnum)))
  (= most-negative-fixnum (* (- most-negative-fixnum) -1))

* test-suite/test/numbers.test: Add test cases to detect
  bugs when negating SCM_MOST_POSITIVE_FIXNUM+1 and
  SCM_MOST_NEGATIVE_FIXNUM by various methods.
2011-01-28 13:52:46 +01:00
Andy Wingo
10391e06e0 domain of inf?, finite?, nan? is the real numbers
* libguile/numbers.c (scm_inf_p, scm_finite_p, scm_nan_p): The domain of
  these functions is the real numbers.  Error on other input.

* doc/ref/api-data.texi (Reals and Rationals): Update the documentation
  accordingly.

* test-suite/tests/numbers.test ("finite?", "inf?"): Update tests.
2011-01-28 13:43:37 +01:00
Mark H Weaver
a4955a0412 Remove useless code from do_divide
* libguile/numbers.c (do_divide): Remove code which handled a case
  that never occurs: a zero bignum.
2011-01-28 12:26:23 +01:00
Mark H Weaver
41df63cf16 Optimize scm_exact_p by making use of SCM_INEXACTP
* libguile/numbers.c (scm_exact_p): Optimize by making use of the
  SCM_INEXACTP macro.
  (scm_inexact_p): Move it next to scm_exact_p, and add else's.

* test-suite/tests/numbers.test: Add test cases for `exact?'
  and `inexact?' applied to infinities and NaNs.
2011-01-28 12:24:24 +01:00
Mark H Weaver
7112615f73 Implement finite?' in core and fix R6RS finite?' and `infinite?'
* libguile/numbers.c (scm_finite_p): Add new predicate `finite?' from
  R6RS to guile core, which returns #t if and only if its argument is
  neither infinite nor a NaN.  Note that this is not the same as (not
  (inf? x)) or (not (infinite? x)), since NaNs are neither finite nor
  infinite.

* test-suite/tests/numbers.test: Add test cases for `finite?'.

* module/rnrs/base.scm: Import `inf?' as `infinite?' instead of
  reimplementing it.  Previously, the R6RS implementation of
  `infinite?' did not detect non-real complex infinities, nor did it
  throw exceptions for non-numbers.  (Note that NaNs _are_ considered
  numbers by scheme, despite their name).

  Import `finite?' instead of reimplementing it.  Previously, the R6RS
  implementation of `finite?' returned #t for both NaNs and non-real
  complex infinities, in violation of R6RS.

* NEWS: Add NEWS entries, and reorganize existing numerics-related
  entries together under one subheading.

* doc/ref/api-data.texi (Real and Rational Numbers): Add docs for
  `finite?' and scm_finite_p.
2011-01-28 12:21:14 +01:00
Mark H Weaver
cff5fa3384 Add SCM_INUM1 to numbers.h, and make use of it and SCM_INUM0 in numbers.c
* libguile/numbers.h: Add SCM_INUM1, a name for the fixnum 1.  This is
  analogous to SCM_INUM0, a name for 0, which already existed.

* libguile/numbers.c: Change occurrences of SCM_I_MAKINUM (0) and
  SCM_I_MAKINUM (1) to SCM_INUM0 and SCM_INUM1, respectively.
2011-01-28 12:18:12 +01:00
Mark H Weaver
b56c252b52 Fix incorrect FUNC_NAME for scm_current_processor_count
* libguile/posix.c (scm_current_processor_count):
  Fix incorrect FUNC_NAME (was s_scm_total_processor_count)
2011-01-28 12:16:16 +01:00
Andy Wingo
6ce3666ff2 for mmap objcodes, store the fd in the third word, as a scheme int
This leaves space for native code.

* libguile/objcodes.h (SCM_OBJCODE_NATIVE_CODE)
  (SCM_SET_OBJCODE_NATIVE_CODE): Reserve the fourth word of objcode for
  "native code", whatever that means.

* libguile/objcodes.c: Update a comment.
  (make_objcode_by_mmap): Put the fd in the third word.
2011-01-27 13:11:02 +01:00
Andy Wingo
f9654187b1 objcode type is an enumeration, not flags
* libguile/objcodes.h (SCM_OBJCODE_TYPE_MMAP)
  (SCM_OBJCODE_TYPE_BYTEVECTOR, SCM_OBJCODE_TYPE_SLICE)
  (SCM_OBJCODE_TYPE_STATIC): Enumerate objcode types instead of
  expressing them as flags.
  (SCM_OBJCODE_TYPE): Type is held in bits 8-15.
  (SCM_OBJCODE_FLAGS): Flags are now shifted by 16 bits, not 8.
  (SCM_MAKE_OBJCODE_TAG): New helper.

* libguile/continuations.c (STATIC_OBJCODE_TAG):
* libguile/control.c (STATIC_OBJCODE_TAG):
* libguile/foreign.c (STATIC_OBJCODE_TAG):
* libguile/gsubr.c (STATIC_OBJCODE_TAG):
* libguile/smob.c (STATIC_OBJCODE_TAG):
* libguile/objcodes.c (make_objcode_by_mmap, scm_c_make_objcode_slice)
  (scm_bytecode_to_objcode): : Use SCM_MAKE_OBJCODE_TAG.
2011-01-27 13:08:01 +01:00
Andy Wingo
dce0252bf2 fix error handling in variable-ref family of instructions
* libguile/vm-i-system.c (variable-ref, variable-set, variable-bound?):
  Check that the argument is actually a variable.  Thanks to Kevin
  Holmes for the report.

* libguile/vm-engine.c (vm_engine): Error handling down here.

* THANKS: Update.
2011-01-27 10:49:51 +01:00
Ludovic Courtès
4914fe1963 Use scm_from_latin1_stringn' in objcodes.c'.
* libguile/objcodes.c (make_objcode_by_mmap): Use
  `scm_from_latin1_stringn', not `scm_from_locale_stringn', to display
  the invalid cookie in the error case.
2011-01-27 00:16:54 +01:00
Ludovic Courtès
a7ea441163 Fix buffer overflow in `read-line'.
* libguile/rdelim.c (SCM_DEFINE): Compare INDEX to LINE_BUFFER_SIZE, not
  `sizeof (buf)'.
2011-01-27 00:15:58 +01:00
Ludovic Courtès
e578faea20 Tweak `read-line'.
* libguile/rdelim.c (LINE_BUFFER_SIZE): Set to 1 KiB instead of 4 KiB.
  (scm_read_line): Initialize STRING to #f so we actually use the fast
  path.
2011-01-26 23:03:17 +01:00
Andy Wingo
1cc0b6adde fix error-handling of apply to non-list
* libguile/vm-engine.c (vm_error_apply_to_non_list): Sync registers
  before erroring. Fix type of finish_args.  Thanks to Hans Aberg for
  the report.
2011-01-26 21:44:12 +01:00
Ludovic Courtès
a2c36371ce Rewrite read-line' in terms of scm_getc'.
As a result `read-line' handles decoding and decoding errors the same
way as `scm_getc'.  It's also simpler and free of `malloc' calls.

* libguile/rdelim.c (scm_do_read_line): Remove.
  (scm_read_line): Rewrite as a loop that calls `scm_getc'.

* test-suite/tests/rdelim.test: New file.
* test-suite/Makefile.am (SCM_TESTS): Add `tests/rdelim.test'.
2011-01-26 00:29:51 +01:00
Ludovic Courtès
cc540d0bbd Have `scm_getc' honor the port's conversion strategy.
* libguile/ports.c (get_codepoint): Reset `pt->input_cd' upon failure.
  If `pt->ilseq_handler' is `SCM_ICONVEH_QUESTION_MARK', then return a
  question mark.
  [failure]: Use `scm_encoding_error' when raising an error.

* test-suite/lib.scm (exception:encoding-error): Adjust regexp.

* test-suite/tests/ports.test ("string ports")["read-char, wrong
  encoding, error", "read-char, wrong encoding, escape", "read-char,
  wrong encoding, substitute"]: New tests.
2011-01-26 00:29:51 +01:00
Ludovic Courtès
647dc1ac23 Add `scm_{to,from}_utf32_string'.
* libguile/strings.c (scm_from_utf32_string, scm_from_utf32_stringn,
  scm_to_utf32_string, scm_to_utf32_stringn): New functions.

* libguile/strings.h (scm_from_utf32_string, scm_from_utf32_stringn,
  scm_to_utf32_string, scm_to_utf32_stringn): New declarations.

* doc/ref/api-data.texi (Conversion to/from C): Document
  `scm_{to,from}_{utf8,utf32}_stringn'.
2011-01-26 00:29:50 +01:00
Ludovic Courtès
e9a35a965b Optimize `scm_{to,from}_latin1_string'.
* libguile/strings.c (scm_from_latin1_stringn): Directly return a narrow
  string instead of going through `scm_from_stringn'.
  (scm_to_latin1_stringn): Directly return a copy of STR's raw bytes when
  it's narrow.
2011-01-26 00:29:50 +01:00
Ludovic Courtès
da288f50bf Remove useless branches in the port code.
* libguile/ports.c (scm_i_get_port_encoding): Remove useless `if'.
  (scm_set_port_encoding_x): Remove redundant `find_valid_encoding'
  call.
2011-01-24 23:15:18 +01:00
Ludovic Courtès
d9544bf012 Always initialize a port's encoding name.
* libguile/ports.c (scm_i_set_port_encoding_x): Always initialize
  PT->encoding to something non-NULL.  This fixes callers of
  `scm_encoding_error' such that they always pass a non-NULL encoding
  name.  Reported by Matei Conovici.
2011-01-24 23:15:18 +01:00
Ludovic Courtès
4325620f6d Rewrite scm_lfwrite_substr' in terms of scm_display'.
* libguile/ports.c (scm_lfwrite_substr): Rewrite in terms of
  `scm_display'.
2011-01-23 01:26:07 +01:00
Ludovic Courtès
a917871527 Remove `scm_lfwrite_str'.
* libguile/ports.c (scm_lfwrite_str): Remove.

* libguile/ports.h (scm_lfwrite_str): Remove declaration.

* libguile/numbers.c (scm_i_print_fraction): Use `scm_display' instead
  of `scm_lfwrite_str'.
2011-01-23 01:14:51 +01:00
Ludovic Courtès
31d4d02be7 Hide the string escaping hacks.
* libguile/strings.c (scm_i_unistring_escapes_to_guile_escapes): Rename
  to...
  (unistring_escapes_to_guile_escapes): ... this.  Make `static'.
  (scm_i_unistring_escapes_to_r6rs_escapes): Rename to...
  (unistring_escapes_to_r6rs_escapes): ... this.  Make `static'.

* libguile/strings.h (scm_i_unistring_escapes_to_guile_escapes,
  scm_i_unistring_escapes_to_r6rs_escapes): Remove declarations.
2011-01-23 00:37:25 +01:00
Ludovic Courtès
f4bc4e5934 Rewrite read-char', display', etc. using iconv calls instead of libunistring.
Thanks to Bruno Haible for his suggestions.  See
<http://lists.gnu.org/archive/html/bug-libunistring/2010-09/msg00007.html>,
for details.

* libguile/ports.c (register_finalizer_for_port): Always register a
  finalizer for PORT.
  (finalize_port): Close ENTRY->input_cd and ENTRY->output_cd.
  (scm_new_port_table_entry): Initialize the `input_cd' and `output_cd'
  fields.
  (utf8_to_codepoint): New function.
  (get_codepoint): Rewrite to use `iconv' instead of libunistring.
  (scm_i_set_port_encoding_x): Initialize the `input_cd' and `output_cd'
  fields.
  (update_port_lf): Move upward.  Use `switch' instead of `if's.

* libguile/ports.h (scm_t_port)[input_cd, output_cd]: New fields.

* libguile/print.c (codepoint_to_utf8, display_string): New functions.
  (display_character): Use `display_string'.
  (write_combining_character): Likewise.
  (iprin1): Use `display_string' instead of `scm_lfwrite_str', and
  `display_character' instead of `scm_putc'.
  (write_character): Likewise.
  (write_character_escaped): New function.

* test-suite/tests/encoding-escapes.test ("display output
  escapes")["Rashomon"]: Use lower-case escapes.
  ["fake escape"]: New test.
2011-01-23 00:37:25 +01:00
Andy Wingo
8e43ed5d0b infinities are no longer integers
* libguile/numbers.c (scm_is_integer): Infinities are not integers, per
  the R6RS.
  (scm_even_p, scm_odd_p): Passing an infinity to even? or odd? is an
  error.

* test-suite/tests/numbers.test ("integer?"): Adapt test.
  ("expt"): Add tests for +inf.0 and -inf.0 exponents.

* NEWS: Add NEWS entries.
2011-01-23 00:06:24 +01:00
Andy Wingo
cde24ce12b scm_with_guile calls GC_call_with_gc_active
* configure.ac: Check for GC_call_with_gc_active.

* libguile/threads.h (scm_i_thread): Remove "top", as it's not used.

* libguile/threads.c (with_gc_inactive, with_gc_active): Define shims to
  GC_do_blocking and GC_call_with_gc_active.
  (scm_i_init_thread_for_guile): Don't do thread base adjustment here,
  do it in scm_i_with_guile_and_parent.  The previous logic would never
  be run.
  (scm_i_with_guile_and_parent): If we enter Guile mode, leave it too.
  Take care of adjusting the thread stack base here too.  Also, call
  with_gc_active.
  (scm_without_guile): Refactor.
2011-01-22 19:55:31 +01:00
Andy Wingo
684d664e39 implement r6rs hungry escaped EOL
* libguile/private-options.h (SCM_HUNGRY_EOL_ESCAPES_P): New private
  option.
* libguile/read.c: Define SCM_HUNGRY_EOL_ESCAPES_P, defaulting to #f.
  (skip_intraline_whitespace): New helper.
  (scm_read_string): If SCM_HUNGRY_EOL_ESCAPES_P,
  skip_intraline_whitespace after an escaped EOL.

* test-suite/tests/reader.test ("read-options"): Add test.
2011-01-21 09:24:32 +01:00
Mark H Weaver
01c7284ae5 Fix bugs in expt and integer-expt
* libguile/numbers.c (scm_expt): Fix bug that caused expt to throw an
  exception whenever the base was exact and the exponent was an
  inexact integer, e.g. (expt 5 6.0).

  (scm_expt): Fix bug that caused expt to introduce spurious imaginary
  parts in the result when the base was an inexact negative real and
  the exponent was an integer, e.g. (expt -1.0 2)

  (scm_integer_expt, scm_expt): Change behavior of (integer-expt 0 -1),
  and therefore also (expt 0 -1), to return NaN, per R6RS (actually,
  R6RS says we should throw an exception or return an "unspecified
  number object", but for now we use NaN).  Formerly we returned 0, per
  R5RS. R5RS claims that 0^x=0 for all non-zero x, but that's
  mathematically incorrect, and probably an oversight.

  (scm_integer_expt): Consistently throw a wrong-argument-type exception
  when the exponent is inexact.  Formerly, it didn't always check this
  if the base was 0, 1, or -1.

* test-suite/tests/numbers.test ("integer-expt", "expt"): Add tests.
2011-01-20 23:28:37 +01:00