hyln9 / ikarus

Optimizing incremental native-code compiler for R6RS scheme. This is a forked repository.
https://launchpad.net/ikarus
Other
5 stars 0 forks source link

port-position on custom ports give wrong answers #153

Closed hyln9 closed 10 years ago

hyln9 commented 10 years ago

I think you got some of the arithmetic in accounting for custom port buffers backwards.

$ ./src/ikarus -b ./scheme/ikarus.boot Ikarus Scheme version 0.0.3+ (revision 1549, build 2008-07-23)

(define p (let ([pos 0]) (make-custom-binary-input-port "foo" (lambda (bv s c) (set! pos (+ pos c)) c) (lambda () pos) (lambda (x) (set! pos x)) #f))) (port-position p) 0 (get-u8 p) 255 (port-position p) 257

The last result should have been 1.

Launchpad Details: #LP251642 Michael D. Adams - 2008-07-24 18:05:01 -0400

hyln9 commented 10 years ago

On Jul 24, 2008, at 3:05 PM, Michael D. Adams wrote:

I think you got some of the arithmetic in accounting for custom port buffers backwards.

I agree that this is incorrect, but what's the correct behavior?

On the one hand, the IO system can fully keep track of the position since it knows how many bytes have been read into the buffer and how many bytes have been consumed by get-u8, so, the port position is always known. (this is how the file-based ports know their position; they never use lseek or whatever to compute the current position) So, can port-position simply bypass the given procedure and always return some internally computed value?

Either way, we can get this to work for binary ports since the given procedure is required to return an integer and with some arithmetic we can get the right answer. But what about textual ports? Since the get-position procedure may return "a single value" without any restrictions on what that value may be, we cannot use that value to compute the actual position of the port. It seems that we cannot buffer custom textual ports. But we have to buffer at least one character to support lookahead-char! In that case, we have to get the port position before we do a lookahead-char, cache it just in case we get asked for it, and throw it away when we do a get-char. So, can the implementation call the supplied get-position procedure before lookahead-char and even if the user did not call port-positon?

Any ideas for how to resolve this interesting problem?

Launchpad Details: #LPC Abdulaziz Ghuloum - 2008-07-24 23:51:58 -0400

hyln9 commented 10 years ago

Example: no implementation of R6RS runs the following program:

!r6rs

(import (rnrs)) (let ([p (let ([pos 0]) (define-record-type P (fields pos)) (make-custom-textual-input-port "foo" (lambda (s i c) (set! pos (+ pos c)) c) (lambda () (make-P pos)) (lambda (x) (set! pos (P-pos x))) (lambda () (display "done\n"))))]) (lookahead-char p) (port-position p))

Launchpad Details: #LPC Abdulaziz Ghuloum - 2008-07-25 00:20:47 -0400

hyln9 commented 10 years ago

Counting is fixed in revision 1553, though all issues are still standing.

Launchpad Details: #LPC Abdulaziz Ghuloum - 2008-07-25 01:34:00 -0400

hyln9 commented 10 years ago

Yes, the custom ports interface has problems. For binary custom ports where both get-position and set-position are provided it is possible (though ikcy) to work around the problems. This is one area that you, Kent, and Will Clinger agree on. You just kind of have to work make it work where you can and not worry about the rest.

Launchpad Details: #LPC Michael D. Adams - 2008-07-25 17:53:18 -0400

hyln9 commented 10 years ago

Closing since I fixed it for the simple case that you mentioned.

Launchpad Details: #LPC Abdulaziz Ghuloum - 2008-07-29 10:44:43 -0400