t3x.org / sketchy / library / strtonum.html
SketchyLISP
Reference
  Copyright (C) 2007
Nils M Holm

string->number

Conformance: R5RS Scheme (Restrictions: Takes only integer arguments. )

Purpose: Convert a string to a number. Radix must be in the range 2..16. If no radix is given, 10 is assumed. If the given string does not hold the representation of a valid integer, #f is returned.

Arguments:
STR - string
RADIX - optional radix

Implementation:

(define (string->number str . radix)
  (letrec
    ((digits
       (string->list "0123456789abcdef"))
     ; Find the value of a digit.
     (value
       (lambda (x)
         (letrec
           ((v (lambda (x d n)
             (cond ((null? d) 17)
               ((char=? (car d) x) n)
               (else (v x (cdr d) (+ n 1)))))))
           (v (char-downcase x) digits 0))))
     ; Convert an unsigned number
     (conv
       (lambda (lst res rdx)
         (cond ((null? lst) res)
           (else (let ((dval (value (car lst))))
                   (and (< dval rdx)
                        (conv (cdr lst)
                          (+ (value (car lst))
                             (* res rdx))
                          rdx)))))))
     ; Convert a signed number
     (sconv
       (lambda (lst res rdx)
         (cond ((null? lst) #f)
           ((char=? (car lst) #\+)
             (conv (cdr lst) res rdx))
           ((char=? (car lst) #\-)
             (- (conv (cdr lst) res rdx)))
           (else (conv lst res rdx)))))
     ; Get the radix
     (get-radix
       (lambda ()
         (cond ((null? radix) 10)
           ((< 1 (car radix) 17) (car radix))
           (else (bottom '(bad radix in string->number)))))))
    (let ((r (get-radix)))
      (cond ((= r 10)
          (let ((n (read-from-string str)))
            (cond ((and (pair? n) (number? (car n)))
                (+ (car n) 0))
              (else #f))))
        (else (sconv (string->list str) 0 r))))))

Example:

(string->number "-7777" 8) 
=> -4095

See also:
number->string.