(module simply-scheme mzscheme (require (lib "trace.ss")) (define simply-scheme:* *) (define simply-scheme:+ +) (define simply-scheme:- -) (define simply-scheme:/ /) (define simply-scheme:< <) (define simply-scheme:<= <=) (define simply-scheme:= =) (define simply-scheme:> >) (define simply-scheme:>= >=) (define simply-scheme:abs abs) (define simply-scheme:acos acos) (define simply-scheme:asin asin) (define simply-scheme:atan atan) (define simply-scheme:ceiling ceiling) (define simply-scheme:close-input-port close-input-port) (define simply-scheme:close-output-port close-output-port) (define simply-scheme:cos cos) (define simply-scheme:equal? equal?) (define simply-scheme:even? even?) (define simply-scheme:exp exp) (define simply-scheme:expt expt) (define simply-scheme:floor floor) (define simply-scheme:gcd gcd) (define simply-scheme:integer? integer?) (define simply-scheme:lcm lcm) (define simply-scheme:list-ref list-ref) (define simply-scheme:log log) (define simply-scheme:make-vector make-vector) (define simply-scheme:max max) (define simply-scheme:min min) (define simply-scheme:modulo modulo) (define simply-scheme:negative? negative?) (define simply-scheme:number->string number->string) (define simply-scheme:number? number?) (define simply-scheme:odd? odd?) (define simply-scheme:open-input-file open-input-file) (define simply-scheme:open-output-file open-output-file) (define simply-scheme:positive? positive?) (define simply-scheme:quotient quotient) (define simply-scheme:random random) (define simply-scheme:read-line read-line) (define simply-scheme:read-string read-string) (define simply-scheme:remainder remainder) (define simply-scheme:round round) (define simply-scheme:sin sin) (define simply-scheme:sqrt sqrt) (define simply-scheme:tan tan) (define simply-scheme:truncate truncate) (define simply-scheme:vector-ref vector-ref) (define simply-scheme:vector-set! vector-set!) (define simply-scheme:zero? zero?) (if (simply-scheme:equal? 'foo (symbol->string 'foo)) (error "Simply.scm already loaded!!") #f) (if (char=? #\+ (string-ref (simply-scheme:number->string 1.0) 0)) (let-values (((old-ns) simply-scheme:number->string) ((char=?) char=?) ((string-ref) string-ref) ((substring) substring) ((string-length) string-length)) (set! simply-scheme:number->string (lambda args (let-values (((result) (apply old-ns args))) (if (char=? #\+ (string-ref result 0)) (substring result 1 (string-length result)) result))))) 'no-problem) (set! simply-scheme:number->string (let-values (((old-ns) simply-scheme:number->string) ((string?) string?)) (lambda args (if (string? (car args)) (car args) (apply old-ns args))))) (define-values (whoops) (let-values (((string?) string?) ((string-append) string-append) ((error) error) ((cons) cons) ((map) map) ((apply) apply)) (letrec-values (((error-printform) (lambda (x) (if (string? x) (string-append "\"" x "\"") x)))) (lambda (string . args) (apply error (cons string (map error-printform args))))))) (if (if (inexact? (simply-scheme:round (simply-scheme:sqrt 2))) (exact? 1) #f) (let-values (((old-round) simply-scheme:round) ((inexact->exact) inexact->exact)) (set! simply-scheme:round (lambda (number) (inexact->exact (old-round number))))) 'no-problem) (if (inexact? (simply-scheme:* 0.25 4)) (let-values (((rem) simply-scheme:remainder) ((quo) simply-scheme:quotient) ((inexact->exact) inexact->exact) ((integer?) simply-scheme:integer?)) (set! simply-scheme:remainder (lambda (x y) (rem (if (integer? x) (inexact->exact x) x) (if (integer? y) (inexact->exact y) y)))) (set! simply-scheme:quotient (lambda (x y) (quo (if (integer? x) (inexact->exact x) x) (if (integer? y) (inexact->exact y) y))))) 'done) (set! simply-scheme:random (let-values (((*seed*) 1) ((quotient) simply-scheme:quotient) ((modulo) simply-scheme:modulo) ((+) simply-scheme:+) ((-) simply-scheme:-) ((*) simply-scheme:*) ((>) simply-scheme:>)) (lambda (x) (let-values (((hi) (quotient *seed* 127773))) (let-values (((low) (modulo *seed* 127773))) (let-values (((test) (- (* 16807 low) (* 2836 hi)))) (if (> test 0) (set! *seed* test) (set! *seed* (#%app + test (#%datum . 2147483647))))))) (modulo *seed* x)))) (define-values (word?) (let-values (((number?) simply-scheme:number?) ((symbol?) symbol?) ((string?) string?)) (lambda (x) (let-values (((or-part) (symbol? x))) (if or-part or-part (let-values (((or-part) (number? x))) (if or-part or-part (string? x)))))))) (define-values (sentence?) (let-values (((null?) null?) ((pair?) pair?) ((word?) word?) ((car) car) ((cdr) cdr)) (letrec-values (((list-of-words?) (lambda (l) (if (null? l) (begin #t) (if (pair? l) (begin (if (word? (car l)) (list-of-words? (cdr l)) #f)) (begin #f)))))) list-of-words?))) (define-values (empty?) (let-values (((null?) null?) ((string?) string?) ((string=?) string=?)) (lambda (x) (let-values (((or-part) (null? x))) (if or-part or-part (if (string? x) (string=? x "") #f)))))) (define-values (char-rank) (let-values (((*the-char-ranks*) (simply-scheme:make-vector 256 3)) ((=) simply-scheme:=) ((+) simply-scheme:+) ((string-ref) string-ref) ((string-length) string-length) ((vector-set!) simply-scheme:vector-set!) ((char->integer) char->integer) ((symbol->string) symbol->string) ((vector-ref) simply-scheme:vector-ref)) (letrec-values (((rank-string) (lambda (str rank) (letrec-values (((helper) (lambda (i len) (if (= i len) 'done (begin (vector-set! *the-char-ranks* (char->integer (string-ref str i)) rank) (helper (+ i 1) len)))))) (helper 0 (string-length str)))))) (rank-string (symbol->string 'abcdefghijklmnopqrstuvwxyz) 0) (rank-string "!$%&*/:<=>?~_^" 0) (rank-string "+-." 1) (rank-string "0123456789" 2) (lambda (char) (vector-ref *the-char-ranks* (char->integer char)))))) (define-values (string->word) (let-values (((=) simply-scheme:=) ((<=) simply-scheme:<=) ((+) simply-scheme:+) ((-) simply-scheme:-) ((char-rank) char-rank) ((string-ref) string-ref) ((string-length) string-length) ((string=?) string=?) ((not) not) ((char=?) char=?) ((string->number) string->number) ((string->symbol) string->symbol)) (lambda (string) (letrec-values (((subsequents?) (lambda (string i length) (if (= i length) (begin #t) (if (<= (char-rank (string-ref string i)) 2) (begin (subsequents? string (+ i 1) length)) (begin #f))))) ((special-id?) (lambda (string) (let-values (((or-part) (string=? string "+"))) (if or-part or-part (let-values (((or-part) (string=? string "-"))) (if or-part or-part (string=? string "..."))))))) ((ok-symbol?) (lambda (string) (if (string=? string "") #f (let-values (((rank1) (char-rank (string-ref string 0)))) (if (= rank1 0) (begin (subsequents? string 1 (string-length string))) (if (= rank1 1) (begin (special-id? string)) (begin #f))))))) ((nn-helper) (lambda (string i len seen-point?) (if (= i len) (begin (if seen-point? (not (char=? (string-ref string (- len 1)) #\0)) #t)) (if (char=? #\. (string-ref string i)) (begin (if seen-point? (begin #f) (if (= (+ i 2) len) (begin #t) (begin (nn-helper string (+ i 1) len #t))))) (if (= 2 (char-rank (string-ref string i))) (begin (nn-helper string (+ i 1) len seen-point?)) (begin #f)))))) ((narrow-number?) (lambda (string) (if (string=? string "") #f (let-values (((c0) (string-ref string 0))) (let-values (((start) 0)) (let-values (((len) (string-length string))) (let-values (((cn) (string-ref string (- len 1)))) (if (if (char=? c0 #\-) (not (= len 1)) #f) (begin (set! start (#%datum . 1)) (set! c0 (#%app string-ref string (#%datum . 1)))) #f) (if (not (= (char-rank cn) 2)) (begin #f) (if (char=? c0 #\.) (begin #f) (if (char=? c0 #\0) (begin (if (= len 1) (begin #t) (if (= len 2) (begin #f) (if (char=? (string-ref string (+ start 1)) #\.) (begin (nn-helper string (+ start 2) len #t)) (begin #f))))) (begin (nn-helper string start len #f))))))))))))) (if (narrow-number? string) (begin (string->number string)) (if (ok-symbol? string) (begin (string->symbol string)) (begin string))))))) (define-values (char->word) (let-values (((=) simply-scheme:=) ((char-rank) char-rank) ((make-string) make-string) ((string->symbol) string->symbol) ((string->number) string->number) ((char=?) char=?)) (lambda (char) (let-values (((rank) (char-rank char)) ((string) (make-string 1 char))) (if (= rank 0) (begin (string->symbol string)) (if (= rank 2) (begin (string->number string)) (if (char=? char #\+) (begin '+) (if (char=? char #\-) (begin '-) (begin string))))))))) (define-values (word->string) (let-values (((number?) simply-scheme:number?) ((string?) string?) ((number->string) simply-scheme:number->string) ((symbol->string) symbol->string)) (lambda (wd) (if (string? wd) (begin wd) (if (number? wd) (begin (number->string wd)) (begin (symbol->string wd))))))) (define-values (count) (let-values (((word?) word?) ((string-length) string-length) ((word->string) word->string) ((length) length)) (lambda (stuff) (if (word? stuff) (string-length (word->string stuff)) (length stuff))))) (define-values (word) (let-values (((string->word) string->word) ((apply) apply) ((string-append) string-append) ((map) map) ((word?) word?) ((word->string) word->string) ((whoops) whoops)) (lambda x (string->word (apply string-append (map (lambda (arg) (if (word? arg) (word->string arg) (whoops "Invalid argument to WORD: " arg))) x)))))) (define-values (se) (let-values (((pair?) pair?) ((null?) null?) ((word?) word?) ((car) car) ((cons) cons) ((cdr) cdr) ((whoops) whoops)) (letrec-values (((paranoid-append) (lambda (a original-a b) (if (null? a) (begin b) (if (word? (car a)) (begin (cons (car a) (paranoid-append (cdr a) original-a b))) (begin (whoops "Argument to SENTENCE not a word or sentence" original-a)))))) ((combine-two) (lambda (a b) (if (pair? a) (begin (paranoid-append a a b)) (if (null? a) (begin b) (if (word? a) (begin (cons a b)) (begin (whoops "Argument to SENTENCE not a word or sentence:" a))))))) ((real-se) (lambda (args) (if (null? args) '() (combine-two (car args) (real-se (cdr args))))))) (lambda args (real-se args))))) (define-values (sentence) se) (define-values (first) (let-values (((pair?) pair?) ((char->word) char->word) ((string-ref) string-ref) ((word->string) word->string) ((car) car) ((empty?) empty?) ((whoops) whoops) ((word?) word?)) (letrec-values (((word-first) (lambda (wd) (char->word (string-ref (word->string wd) 0))))) (lambda (x) (if (pair? x) (begin (car x)) (if (empty? x) (begin (whoops "Invalid argument to FIRST: " x)) (if (word? x) (begin (word-first x)) (begin (whoops "Invalid argument to FIRST: " x))))))))) (define-values (last) (let-values (((pair?) pair?) ((-) simply-scheme:-) ((word->string) word->string) ((char->word) char->word) ((string-ref) string-ref) ((string-length) string-length) ((empty?) empty?) ((cdr) cdr) ((car) car) ((whoops) whoops) ((word?) word?)) (letrec-values (((word-last) (lambda (wd) (let-values (((s) (word->string wd))) (char->word (string-ref s (- (string-length s) 1)))))) ((list-last) (lambda (lst) (if (empty? (cdr lst)) (car lst) (list-last (cdr lst)))))) (lambda (x) (if (pair? x) (begin (list-last x)) (if (empty? x) (begin (whoops "Invalid argument to LAST: " x)) (if (word? x) (begin (word-last x)) (begin (whoops "Invalid argument to LAST: " x))))))))) (define-values (bf) (let-values (((pair?) pair?) ((substring) substring) ((string-length) string-length) ((string->word) string->word) ((word->string) word->string) ((cdr) cdr) ((empty?) empty?) ((whoops) whoops) ((word?) word?)) (letrec-values (((string-bf) (lambda (s) (substring s 1 (string-length s)))) ((word-bf) (lambda (wd) (string->word (string-bf (word->string wd)))))) (lambda (x) (if (pair? x) (begin (cdr x)) (if (empty? x) (begin (whoops "Invalid argument to BUTFIRST: " x)) (if (word? x) (begin (word-bf x)) (begin (whoops "Invalid argument to BUTFIRST: " x))))))))) (define-values (butfirst) bf) (define-values (bl) (let-values (((pair?) pair?) ((-) simply-scheme:-) ((cdr) cdr) ((cons) cons) ((car) car) ((substring) substring) ((string-length) string-length) ((string->word) string->word) ((word->string) word->string) ((empty?) empty?) ((whoops) whoops) ((word?) word?)) (letrec-values (((list-bl) (lambda (list) (if (null? (cdr list)) '() (cons (car list) (list-bl (cdr list)))))) ((string-bl) (lambda (s) (substring s 0 (- (string-length s) 1)))) ((word-bl) (lambda (wd) (string->word (string-bl (word->string wd)))))) (lambda (x) (if (pair? x) (begin (list-bl x)) (if (empty? x) (begin (whoops "Invalid argument to BUTLAST: " x)) (if (word? x) (begin (word-bl x)) (begin (whoops "Invalid argument to BUTLAST: " x))))))))) (define-values (butlast) bl) (define-values (item) (let-values (((>) simply-scheme:>) ((-) simply-scheme:-) ((<) simply-scheme:<) ((integer?) simply-scheme:integer?) ((list-ref) simply-scheme:list-ref) ((char->word) char->word) ((string-ref) string-ref) ((word->string) word->string) ((not) not) ((whoops) whoops) ((count) count) ((word?) word?) ((list?) list?)) (letrec-values (((word-item) (lambda (n wd) (char->word (string-ref (word->string wd) (- n 1)))))) (lambda (n stuff) (if (not (integer? n)) (begin (whoops "Invalid first argument to ITEM (must be an integer): " n)) (if (< n 1) (begin (whoops "Invalid first argument to ITEM (must be positive): " n)) (if (> n (count stuff)) (begin (whoops "No such item: " n stuff)) (if (word? stuff) (begin (word-item n stuff)) (if (list? stuff) (begin (list-ref stuff (- n 1))) (begin (whoops "Invalid second argument to ITEM: " stuff))))))))))) (set! simply-scheme:equal? (let-values (((vector-length) vector-length) ((=) simply-scheme:=) ((vector-ref) simply-scheme:vector-ref) ((+) simply-scheme:+) ((string?) string?) ((symbol?) symbol?) ((null?) null?) ((pair?) pair?) ((car) car) ((cdr) cdr) ((eq?) eq?) ((string=?) string=?) ((symbol->string) symbol->string) ((number?) simply-scheme:number?) ((string->word) string->word) ((vector?) vector?) ((eqv?) eqv?)) (letrec-values (((vector-equal?) (lambda (v1 v2) (let-values (((len1) (vector-length v1)) ((len2) (vector-length v2))) (letrec-values (((helper) (lambda (i) (if (= i len1) #t (if (simply-scheme:equal? (vector-ref v1 i) (vector-ref v2 i)) (helper (+ i 1)) #f))))) (if (= len1 len2) (helper 0) #f)))))) (lambda (x y) (if (null? x) (begin (null? y)) (if (null? y) (begin #f) (if (pair? x) (begin (if (pair? y) (if (simply-scheme:equal? (car x) (car y)) (simply-scheme:equal? (cdr x) (cdr y)) #f) #f)) (if (pair? y) (begin #f) (if (symbol? x) (begin (let-values (((or-part) (if (symbol? y) (eq? x y) #f))) (if or-part or-part (if (string? y) (string=? (symbol->string x) y) #f)))) (if (symbol? y) (begin (if (string? x) (string=? x (symbol->string y)) #f)) (if (number? x) (begin (let-values (((or-part) (if (number? y) (= x y) #f))) (if or-part or-part (if (string? y) (let-values (((possible-num) (string->word y))) (if (number? possible-num) (= x possible-num) #f)) #f)))) (if (number? y) (begin (if (string? x) (let-values (((possible-num) (string->word x))) (if (number? possible-num) (= possible-num y) #f)) #f)) (if (string? x) (begin (if (string? y) (string=? x y) #f)) (if (string? y) (begin #f) (if (vector? x) (begin (if (vector? y) (vector-equal? x y) #f)) (if (vector? y) (begin #f) (begin (eqv? x y)))))))))))))))))) (define-values (member?) (let-values (((>) simply-scheme:>) ((-) simply-scheme:-) ((<) simply-scheme:<) ((null?) null?) ((symbol?) symbol?) ((eq?) eq?) ((car) car) ((not) not) ((symbol->string) symbol->string) ((string=?) string=?) ((cdr) cdr) ((equal?) simply-scheme:equal?) ((word->string) word->string) ((string-length) string-length) ((whoops) whoops) ((string-ref) string-ref) ((char=?) char=?) ((list?) list?) ((number?) simply-scheme:number?) ((empty?) empty?) ((word?) word?) ((string?) string?)) (letrec-values (((symbol-in-list?) (lambda (symbol string lst) (if (null? lst) (begin #f) (let-values (((g174) (if (symbol? (car lst)) (eq? symbol (car lst)) #f))) (if g174 g174 (if (string? (car lst)) (begin (if (not string) (begin (symbol-in-list? symbol (symbol->string symbol) lst)) (if (string=? string (car lst)) (begin #t) (begin (symbol-in-list? symbol string (cdr lst)))))) (begin (symbol-in-list? symbol string (cdr lst))))))))) ((word-in-list?) (lambda (wd lst) (if (null? lst) (begin #f) (if (equal? wd (car lst)) (begin #t) (begin (word-in-list? wd (cdr lst))))))) ((word-in-word?) (lambda (small big) (let-values (((one-letter-str) (word->string small))) (if (> (string-length one-letter-str) 1) (whoops "Invalid arguments to MEMBER?: " small big) (let-values (((big-str) (word->string big))) (char-in-string? (string-ref one-letter-str 0) big-str (- (string-length big-str) 1))))))) ((char-in-string?) (lambda (char string i) (if (< i 0) (begin #f) (if (char=? char (string-ref string i)) (begin #t) (begin (char-in-string? char string (- i 1)))))))) (lambda (x stuff) (if (empty? stuff) (begin #f) (if (word? stuff) (begin (word-in-word? x stuff)) (if (not (list? stuff)) (begin (whoops "Invalid second argument to MEMBER?: " stuff)) (if (symbol? x) (begin (symbol-in-list? x #f stuff)) (if (let-values (((or-part) (number? x))) (if or-part or-part (string? x))) (begin (word-in-list? x stuff)) (begin (whoops "Invalid first argument to MEMBER?: " x))))))))))) (define-values (before?) (let-values (((not) not) ((word?) word?) ((whoops) whoops) ((string<?) string<?) ((word->string) word->string)) (lambda (wd1 wd2) (if (not (word? wd1)) (begin (whoops "Invalid first argument to BEFORE? (not a word): " wd1)) (if (not (word? wd2)) (begin (whoops "Invalid second argument to BEFORE? (not a word): " wd2)) (begin (string<? (word->string wd1) (word->string wd2)))))))) (define-values (filter) (let-values (((null?) null?) ((car) car) ((cons) cons) ((cdr) cdr) ((not) not) ((procedure?) procedure?) ((whoops) whoops) ((list?) list?)) (lambda (pred l) (letrec-values (((real-filter) (lambda (l) (if (null? l) (begin '()) (if (pred (car l)) (begin (cons (car l) (real-filter (cdr l)))) (begin (real-filter (cdr l)))))))) (if (not (procedure? pred)) (begin (whoops "Invalid first argument to FILTER (not a procedure): " pred)) (if (not (list? l)) (begin (whoops "Invalid second argument to FILTER (not a list): " l)) (begin (real-filter l)))))))) (define-values (keep) (let-values (((+) simply-scheme:+) ((=) simply-scheme:=) ((pair?) pair?) ((substring) substring) ((char->word) char->word) ((string-ref) string-ref) ((string-set!) string-set!) ((word->string) word->string) ((string-length) string-length) ((string->word) string->word) ((make-string) make-string) ((procedure?) procedure?) ((whoops) whoops) ((word?) word?) ((null?) null?)) (lambda (pred w-or-s) (letrec-values (((keep-string) (lambda (in i out out-len len) (if (= i len) (begin (substring out 0 out-len)) (if (pred (char->word (string-ref in i))) (begin (string-set! out out-len (string-ref in i)) (keep-string in (+ i 1) out (+ out-len 1) len)) (begin (keep-string in (+ i 1) out out-len len)))))) ((keep-word) (lambda (wd) (let-values (((string) (word->string wd))) (let-values (((len) (string-length string))) (string->word (keep-string string 0 (make-string len) 0 len))))))) (if (not (procedure? pred)) (begin (whoops "Invalid first argument to KEEP (not a procedure): " pred)) (if (pair? w-or-s) (begin (filter pred w-or-s)) (if (word? w-or-s) (begin (keep-word w-or-s)) (if (null? w-or-s) (begin '()) (begin (whoops "Bad second argument to KEEP (not a word or sentence): " w-or-s)))))))))) (define-values (appearances) (let-values (((count) count) ((keep) keep) ((equal?) simply-scheme:equal?)) (lambda (item aggregate) (count (keep (lambda (element) (equal? item element)) aggregate))))) (define-values (every) (let-values (((=) simply-scheme:=) ((+) simply-scheme:+) ((se) se) ((char->word) char->word) ((string-ref) string-ref) ((empty?) empty?) ((first) first) ((bf) bf) ((not) not) ((procedure?) procedure?) ((whoops) whoops) ((word?) word?) ((word->string) word->string) ((string-length) string-length)) (lambda (fn stuff) (letrec-values (((string-every) (lambda (string i length) (if (= i length) '() (se (fn (char->word (string-ref string i))) (string-every string (+ i 1) length))))) ((sent-every) (lambda (sent) (if (empty? sent) sent (se (fn (first sent)) (sent-every (bf sent))))))) (if (not (procedure? fn)) (begin (whoops "Invalid first argument to EVERY (not a procedure):" fn)) (if (word? stuff) (begin (let-values (((string) (word->string stuff))) (string-every string 0 (string-length string)))) (begin (sent-every stuff)))))))) (define-values (accumulate) (let-values (((not) not) ((empty?) empty?) ((bf) bf) ((first) first) ((procedure?) procedure?) ((whoops) whoops) ((member) member) ((list) list)) (lambda (combiner stuff) (letrec-values (((real-accumulate) (lambda (stuff) (if (empty? (bf stuff)) (first stuff) (combiner (first stuff) (real-accumulate (bf stuff))))))) (if (not (procedure? combiner)) (begin (whoops "Invalid first argument to ACCUMULATE (not a procedure):" combiner)) (if (not (empty? stuff)) (begin (real-accumulate stuff)) (if (member combiner (list simply-scheme:+ simply-scheme:* word se)) (begin (combiner)) (begin (whoops "Can't accumulate empty input with that combiner"))))))))) (define-values (reduce) (let-values (((null?) null?) ((cdr) cdr) ((car) car) ((not) not) ((procedure?) procedure?) ((whoops) whoops) ((member) member) ((list) list)) (lambda (combiner stuff) (letrec-values (((real-reduce) (lambda (stuff) (if (null? (cdr stuff)) (car stuff) (combiner (car stuff) (real-reduce (cdr stuff))))))) (if (not (procedure? combiner)) (begin (whoops "Invalid first argument to REDUCE (not a procedure):" combiner)) (if (not (null? stuff)) (begin (real-reduce stuff)) (if (member combiner (list simply-scheme:+ simply-scheme:* word se append)) (begin (combiner)) (begin (whoops "Can't reduce empty input with that combiner"))))))))) (define-values (repeated) (let-values (((=) simply-scheme:=) ((-) simply-scheme:-)) (lambda (fn number) (if (= number 0) (lambda (x) x) (lambda (x) ((repeated fn (- number 1)) (fn x))))))) (define-values (make-node) cons) (define-values (datum) car) (define-values (children) cdr) (define-values (show) (let-values (((=) simply-scheme:=) ((length) length) ((display) display) ((car) car) ((newline) newline) ((not) not) ((output-port?) output-port?) ((apply) apply) ((whoops) whoops)) (lambda args (if (= (length args) 1) (begin (display (car args)) (newline)) (if (= (length args) 2) (begin (if (not (output-port? (car (cdr args)))) (whoops "Invalid second argument to SHOW (not an output port): " (car (cdr args))) (void)) (apply display args) (newline (car (cdr args)))) (begin (whoops "Incorrect number of arguments to procedure SHOW"))))))) (define-values (show-line) (let-values (((>=) simply-scheme:>=) ((length) length) ((whoops) whoops) ((null?) null?) ((current-output-port) current-output-port) ((car) car) ((not) not) ((list?) list?) ((display) display) ((for-each) for-each) ((cdr) cdr) ((newline) newline)) (lambda (line . args) (if (>= (length args) 2) (whoops "Too many arguments to show-line") (let-values (((port) (if (null? args) (current-output-port) (car args)))) (if (not (list? line)) (begin (whoops "Invalid argument to SHOW-LINE (not a list):" line)) (if (null? line) (begin #f) (begin (display (car line) port) (for-each (lambda (wd) (display " " port) (display wd port)) (cdr line))))) (newline port)))))) (set! simply-scheme:read-string (let-values (((read-char) read-char) ((eqv?) eqv?) ((apply) apply) ((string-append) string-append) ((substring) substring) ((reverse) reverse) ((cons) cons) ((>=) simply-scheme:>=) ((+) simply-scheme:+) ((string-set!) string-set!) ((length) length) ((whoops) whoops) ((null?) null?) ((current-input-port) current-input-port) ((car) car) ((cdr) cdr) ((eof-object?) eof-object?) ((list) list) ((make-string) make-string) ((peek-char) peek-char)) (letrec-values (((read-string-helper) (lambda (chars all-length chunk-length port) (let-values (((char) (read-char port)) ((string) (car chars))) (if (let-values (((or-part) (eof-object? char))) (if or-part or-part (eqv? char #\newline))) (begin (apply string-append (reverse (cons (substring (car chars) 0 chunk-length) (cdr chars))))) (if (>= chunk-length 80) (begin (let-values (((newstring) (make-string 80))) (string-set! newstring 0 char) (read-string-helper (cons newstring chars) (+ all-length 1) 1 port))) (begin (string-set! string chunk-length char) (read-string-helper chars (+ all-length 1) (+ chunk-length 1) port)))))))) (lambda args (if (>= (length args) 2) (whoops "Too many arguments to read-string") (let-values (((port) (if (null? args) (current-input-port) (car args)))) (if (eof-object? (peek-char port)) (read-char port) (read-string-helper (list (make-string 80)) 0 0 port)))))))) (set! simply-scheme:read-line (let-values (((=) simply-scheme:=) ((list) list) ((string->word) string->word) ((substring) substring) ((char-whitespace?) char-whitespace?) ((string-ref) string-ref) ((+) simply-scheme:+) ((string-length) string-length) ((apply) apply) ((read-string) simply-scheme:read-string)) (lambda args (letrec-values (((tokenize) (lambda (string) (letrec-values (((helper) (lambda (i start len) (if (= i len) (begin (if (= i start) '() (list (string->word (substring string start i))))) (if (char-whitespace? (string-ref string i)) (begin (if (= i start) (helper (+ i 1) (+ i 1) len) (cons (string->word (substring string start i)) (helper (+ i 1) (+ i 1) len)))) (begin (helper (+ i 1) start len))))))) (if (eof-object? string) string (helper 0 0 (string-length string))))))) (tokenize (apply read-string args)))))) (define-values (*the-open-inports*) '()) (define-values (*the-open-outports*) '()) (define-values (align) (let-values (((<) simply-scheme:<) ((abs) simply-scheme:abs) ((*) simply-scheme:*) ((expt) simply-scheme:expt) ((>=) simply-scheme:>=) ((-) simply-scheme:-) ((+) simply-scheme:+) ((=) simply-scheme:=) ((null?) null?) ((car) car) ((round) simply-scheme:round) ((number->string) simply-scheme:number->string) ((string-length) string-length) ((string-append) string-append) ((make-string) make-string) ((substring) substring) ((string-set!) string-set!) ((number?) simply-scheme:number?) ((word->string) word->string)) (lambda (obj width . rest) (letrec-values (((align-number) (lambda (obj width rest) (let-values (((sign) (< obj 0))) (let-values (((num) (abs obj))) (let-values (((prec) (if (null? rest) 0 (car rest)))) (let-values (((big) (round (* num (expt 10 prec))))) (let-values (((cvt0) (number->string big))) (let-values (((cvt) (if (< num 1) (string-append "0" cvt0) cvt0))) (let-values (((pos-str) (if (>= (string-length cvt0) prec) cvt (string-append (make-string (- prec (string-length cvt0)) #\0) cvt)))) (let-values (((string) (if sign (string-append "-" pos-str) pos-str))) (let-values (((length) (+ (string-length string) (if (= prec 0) 0 1)))) (let-values (((left) (- length (+ 1 prec)))) (let-values (((result) (if (= prec 0) string (string-append (substring string 0 left) "." (substring string left (- length 1)))))) (if (= length width) (begin result) (if (< length width) (begin (string-append (make-string (- width length) #\space) result)) (begin (let-values (((new) (substring result 0 width))) (string-set! new (- width 1) #\+) new))))))))))))))))) ((align-word) (lambda (string) (let-values (((length) (string-length string))) (if (= length width) (begin string) (if (< length width) (begin (string-append string (make-string (- width length) #\space))) (begin (let-values (((new) (substring string 0 width))) (string-set! new (- width 1) #\+) new)))))))) (if (number? obj) (align-number obj width rest) (align-word (word->string obj))))))) (set! simply-scheme:open-output-file (let-values (((oof) simply-scheme:open-output-file) ((cons) cons)) (lambda (filename) (let-values (((port) (oof filename))) (set! *the-open-outports* (#%app cons port (#%top . *the-open-outports*))) port)))) (set! simply-scheme:open-input-file (let-values (((oif) simply-scheme:open-input-file) ((cons) cons)) (lambda (filename) (let-values (((port) (oif filename))) (set! *the-open-inports* (#%app cons port (#%top . *the-open-inports*))) port)))) (define-values (remove) (let-values (((null?) null?) ((cdr) cdr) ((eq?) eq?) ((car) car)) (lambda (thing lst) (letrec-values (((r) (lambda (prev) (if (null? (cdr prev)) (begin lst) (if (eq? thing (car (cdr prev))) (begin (cons (car prev) (cdr (cdr prev)))) (begin (cons (car prev) (r (cdr prev))))))))) (if (null? lst) (begin lst) (if (eq? thing (car lst)) (begin (cdr lst)) (begin (r lst)))))))) (set! simply-scheme:close-input-port (let-values (((cip) simply-scheme:close-input-port) ((remove) remove)) (lambda (port) (set! *the-open-inports* (#%app remove port (#%top . *the-open-inports*))) (cip port)))) (set! simply-scheme:close-output-port (let-values (((cop) simply-scheme:close-output-port) ((remove) remove)) (lambda (port) (set! *the-open-outports* (#%app remove port (#%top . *the-open-outports*))) (cop port)))) (define-values (close-all-ports) (let-values (((for-each) for-each) ((close-input-port) simply-scheme:close-input-port) ((close-output-port) simply-scheme:close-output-port)) (lambda () (for-each close-input-port *the-open-inports*) (for-each close-output-port *the-open-outports*) 'closed))) (define-values (maybe-num) (let-values (((string?) string?) ((string->number) string->number)) (lambda (arg) (if (string? arg) (let-values (((num) (string->number arg))) (if num num arg)) arg)))) (define-values (logoize) (let-values (((apply) apply) ((map) map) ((maybe-num) maybe-num)) (lambda (fn) (lambda args (apply fn (map maybe-num args)))))) (define-values (logoize-1) (let-values (((maybe-num) maybe-num)) (lambda (fn) (lambda (x) (fn (maybe-num x)))))) (define-values (logoize-2) (let-values (((maybe-num) maybe-num)) (lambda (fn) (lambda (x y) (fn (maybe-num x) (maybe-num y)))))) (define-values (strings-are-numbers) (let-values (((are-they?) #f) ((real-*) simply-scheme:*) ((real-+) simply-scheme:+) ((real--) simply-scheme:-) ((real-/) simply-scheme:/) ((real-<) simply-scheme:<) ((real-<=) simply-scheme:<=) ((real-=) simply-scheme:=) ((real->) simply-scheme:>) ((real->=) simply-scheme:>=) ((real-abs) simply-scheme:abs) ((real-acos) simply-scheme:acos) ((real-asin) simply-scheme:asin) ((real-atan) simply-scheme:atan) ((real-ceiling) simply-scheme:ceiling) ((real-cos) simply-scheme:cos) ((real-even?) simply-scheme:even?) ((real-exp) simply-scheme:exp) ((real-expt) simply-scheme:expt) ((real-floor) simply-scheme:floor) ((real-align) align) ((real-gcd) simply-scheme:gcd) ((real-integer?) simply-scheme:integer?) ((real-item) item) ((real-lcm) simply-scheme:lcm) ((real-list-ref) simply-scheme:list-ref) ((real-log) simply-scheme:log) ((real-make-vector) simply-scheme:make-vector) ((real-max) simply-scheme:max) ((real-min) simply-scheme:min) ((real-modulo) simply-scheme:modulo) ((real-negative?) simply-scheme:negative?) ((real-number?) simply-scheme:number?) ((real-odd?) simply-scheme:odd?) ((real-positive?) simply-scheme:positive?) ((real-quotient) simply-scheme:quotient) ((real-random) simply-scheme:random) ((real-remainder) simply-scheme:remainder) ((real-repeated) repeated) ((real-round) simply-scheme:round) ((real-sin) simply-scheme:sin) ((real-sqrt) simply-scheme:sqrt) ((real-tan) simply-scheme:tan) ((real-truncate) simply-scheme:truncate) ((real-vector-ref) simply-scheme:vector-ref) ((real-vector-set!) simply-scheme:vector-set!) ((real-zero?) simply-scheme:zero?) ((maybe-num) maybe-num) ((number->string) simply-scheme:number->string) ((cons) cons) ((car) car) ((cdr) cdr) ((eq?) eq?) ((show) show) ((logoize) logoize) ((logoize-1) logoize-1) ((logoize-2) logoize-2) ((not) not) ((whoops) whoops)) (lambda (yesno) (if (if are-they? (eq? yesno #t) #f) (begin (show "Strings are already numbers")) (if (eq? yesno #t) (begin (set! are-they? (#%datum . #t)) (set! simply-scheme:* (logoize real-*)) (set! simply-scheme:+ (logoize real-+)) (set! simply-scheme:- (logoize real--)) (set! simply-scheme:/ (logoize real-/)) (set! simply-scheme:< (logoize real-<)) (set! simply-scheme:<= (logoize real-<=)) (set! simply-scheme:= (logoize real-=)) (set! simply-scheme:> (logoize real->)) (set! simply-scheme:>= (logoize real->=)) (set! simply-scheme:abs (logoize-1 real-abs)) (set! simply-scheme:acos (logoize-1 real-acos)) (set! simply-scheme:asin (logoize-1 real-asin)) (set! simply-scheme:atan (logoize real-atan)) (set! simply-scheme:ceiling (logoize-1 real-ceiling)) (set! simply-scheme:cos (logoize-1 real-cos)) (set! simply-scheme:even? (logoize-1 real-even?)) (set! simply-scheme:exp (logoize-1 real-exp)) (set! simply-scheme:expt (logoize-2 real-expt)) (set! simply-scheme:floor (logoize-1 real-floor)) (set! align (#%app logoize (#%top . align))) (set! simply-scheme:gcd (logoize real-gcd)) (set! simply-scheme:integer? (logoize-1 real-integer?)) (set! item (lambda (n stuff) (#%app real-item (#%app maybe-num n) stuff))) (set! simply-scheme:lcm (logoize real-lcm)) (set! simply-scheme:list-ref (lambda (lst k) (real-list-ref lst (maybe-num k)))) (set! simply-scheme:log (logoize-1 real-log)) (set! simply-scheme:max (logoize real-max)) (set! simply-scheme:min (logoize real-min)) (set! simply-scheme:modulo (logoize-2 real-modulo)) (set! simply-scheme:negative? (logoize-1 real-negative?)) (set! simply-scheme:number? (logoize-1 real-number?)) (set! simply-scheme:odd? (logoize-1 real-odd?)) (set! simply-scheme:positive? (logoize-1 real-positive?)) (set! simply-scheme:quotient (logoize-2 real-quotient)) (set! simply-scheme:random (logoize real-random)) (set! simply-scheme:remainder (logoize-2 real-remainder)) (set! simply-scheme:round (logoize-1 real-round)) (set! simply-scheme:sin (logoize-1 real-sin)) (set! simply-scheme:sqrt (logoize-1 real-sqrt)) (set! simply-scheme:tan (logoize-1 real-tan)) (set! simply-scheme:truncate (logoize-1 real-truncate)) (set! simply-scheme:zero? (logoize-1 real-zero?)) (set! simply-scheme:vector-ref (lambda (vec i) (real-vector-ref vec (maybe-num i)))) (set! simply-scheme:vector-set! (lambda (vec i val) (real-vector-set! vec (maybe-num i) val))) (set! simply-scheme:make-vector (lambda (num . args) (apply real-make-vector (cons (maybe-num num) args)))) (set! simply-scheme:list-ref (lambda (lst i) (real-list-ref lst (maybe-num i)))) (set! repeated (lambda (fn n) (#%app real-repeated fn (#%app maybe-num n))))) (if (if (not are-they?) (not yesno) #f) (begin (show "Strings are already not numbers")) (if (not yesno) (begin (set! are-they? (#%datum . #f)) (set! simply-scheme:* real-*) (set! simply-scheme:+ real-+) (set! simply-scheme:- real--) (set! simply-scheme:/ real-/) (set! simply-scheme:< real-<) (set! simply-scheme:<= real-<=) (set! simply-scheme:= real-=) (set! simply-scheme:> real->) (set! simply-scheme:>= real->=) (set! simply-scheme:abs real-abs) (set! simply-scheme:acos real-acos) (set! simply-scheme:asin real-asin) (set! simply-scheme:atan real-atan) (set! simply-scheme:ceiling real-ceiling) (set! simply-scheme:cos real-cos) (set! simply-scheme:even? real-even?) (set! simply-scheme:exp real-exp) (set! simply-scheme:expt real-expt) (set! simply-scheme:floor real-floor) (set! align real-align) (set! simply-scheme:gcd real-gcd) (set! simply-scheme:integer? real-integer?) (set! item real-item) (set! simply-scheme:lcm real-lcm) (set! simply-scheme:list-ref real-list-ref) (set! simply-scheme:log real-log) (set! simply-scheme:max real-max) (set! simply-scheme:min real-min) (set! simply-scheme:modulo real-modulo) (set! simply-scheme:odd? real-odd?) (set! simply-scheme:quotient real-quotient) (set! simply-scheme:random real-random) (set! simply-scheme:remainder real-remainder) (set! simply-scheme:round real-round) (set! simply-scheme:sin real-sin) (set! simply-scheme:sqrt real-sqrt) (set! simply-scheme:tan real-tan) (set! simply-scheme:truncate real-truncate) (set! simply-scheme:zero? real-zero?) (set! simply-scheme:positive? real-positive?) (set! simply-scheme:negative? real-negative?) (set! simply-scheme:number? real-number?) (set! simply-scheme:vector-ref real-vector-ref) (set! simply-scheme:vector-set! real-vector-set!) (set! simply-scheme:make-vector real-make-vector) (set! simply-scheme:list-ref real-list-ref) (set! item real-item) (set! repeated real-repeated)) (begin (whoops "Strings-are-numbers: give a #t or a #f")))))) are-they?))) (strings-are-numbers #t) (provide (all-from-except mzscheme * + - / < <= = > >= abs acos asin atan ceiling close-input-port close-output-port cos equal? even? exp expt floor gcd integer? lcm list-ref log make-vector max min modulo negative? number->string number? odd? open-input-file open-output-file positive? quotient random read-line read-string remainder round sin sqrt tan truncate vector-ref vector-set! zero?) (all-from (lib "trace.ss")) (rename simply-scheme:* *) *the-open-inports* *the-open-outports* (rename simply-scheme:+ +) (rename simply-scheme:- -) (rename simply-scheme:/ /) (rename simply-scheme:< <) (rename simply-scheme:<= <=) (rename simply-scheme:= =) (rename simply-scheme:> >) (rename simply-scheme:>= >=) (rename simply-scheme:abs abs) accumulate (rename simply-scheme:acos acos) align appearances (rename simply-scheme:asin asin) (rename simply-scheme:atan atan) before? bf bl butfirst butlast (rename simply-scheme:ceiling ceiling) char->word char-rank children close-all-ports (rename simply-scheme:close-input-port close-input-port) (rename simply-scheme:close-output-port close-output-port) (rename simply-scheme:cos cos) count datum empty? (rename simply-scheme:equal? equal?) (rename simply-scheme:even? even?) every (rename simply-scheme:exp exp) (rename simply-scheme:expt expt) filter first (rename simply-scheme:floor floor) (rename simply-scheme:gcd gcd) (rename simply-scheme:integer? integer?) item keep last (rename simply-scheme:lcm lcm) (rename simply-scheme:list-ref list-ref) (rename simply-scheme:log log) logoize logoize-1 logoize-2 make-node (rename simply-scheme:make-vector make-vector) (rename simply-scheme:max max) maybe-num member? (rename simply-scheme:min min) (rename simply-scheme:modulo modulo) (rename simply-scheme:negative? negative?) (rename simply-scheme:number->string number->string) (rename simply-scheme:number? number?) (rename simply-scheme:odd? odd?) (rename simply-scheme:open-input-file open-input-file) (rename simply-scheme:open-output-file open-output-file) (rename simply-scheme:positive? positive?) (rename simply-scheme:quotient quotient) (rename simply-scheme:random random) (rename simply-scheme:read-line read-line) (rename simply-scheme:read-string read-string) reduce (rename simply-scheme:remainder remainder) remove repeated (rename simply-scheme:round round) se sentence sentence? show show-line (rename simply-scheme:sin sin) (rename simply-scheme:sqrt sqrt) string->word strings-are-numbers (rename simply-scheme:tan tan) (rename simply-scheme:truncate truncate) (rename simply-scheme:vector-ref vector-ref) (rename simply-scheme:vector-set! vector-set!) whoops word word->string word? (rename simply-scheme:zero? zero?) ) )