(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?) ((set-cdr!) set-cdr!) ((car) car)) (lambda (thing lst) (letrec-values (((r!) (lambda (prev) (if (null? (cdr prev)) (begin lst) (if (eq? thing (car (cdr prev))) (begin (set-cdr! prev (cdr (cdr prev))) lst) (begin (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?) ) )