switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
; -*- scheme -*-
|
2008-06-30 21:54:22 -04:00
|
|
|
; femtoLisp standard library
|
2009-01-04 21:45:21 -05:00
|
|
|
; by Jeff Bezanson (C) 2009
|
2008-08-29 22:56:46 -04:00
|
|
|
; Distributed under the BSD License
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-06 22:10:52 -04:00
|
|
|
(set! *syntax-environment* (table))
|
|
|
|
|
|
|
|
(set! set-syntax!
|
|
|
|
(lambda (s v) (put! *syntax-environment* s v)))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(set-syntax! 'define-macro
|
|
|
|
(lambda (form . body)
|
|
|
|
(list 'set-syntax! (list 'quote (car form))
|
2009-05-29 00:38:50 -04:00
|
|
|
(cons 'lambda (cons (cdr form) body)))))
|
2008-07-14 21:20:52 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define-macro (define form . body)
|
2009-01-31 20:53:58 -05:00
|
|
|
(if (symbol? form)
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(list 'set! form (car body))
|
2009-05-29 00:38:50 -04:00
|
|
|
(list 'set! (car form) (cons 'lambda (cons (cdr form) body)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-04-20 20:56:05 -04:00
|
|
|
(define (symbol-syntax s) (get *syntax-environment* s #f))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (map f lst)
|
2009-06-10 20:34:50 -04:00
|
|
|
((lambda (first acc)
|
|
|
|
(begin
|
|
|
|
(set! first acc)
|
|
|
|
(while (pair? lst)
|
|
|
|
(begin (set! acc
|
|
|
|
(cdr (set-cdr! acc (cons (f (car lst)) ()))))
|
|
|
|
(set! lst (cdr lst))))
|
|
|
|
(cdr first)))
|
|
|
|
() (list ())))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-02-09 00:38:40 -05:00
|
|
|
(define-macro (label name fn)
|
|
|
|
(list (list 'lambda (list name) (list 'set! name fn)) #f))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define-macro (let binds . body)
|
2009-02-05 22:41:24 -05:00
|
|
|
((lambda (lname)
|
|
|
|
(begin
|
|
|
|
(if (symbol? binds)
|
|
|
|
(begin (set! lname binds)
|
|
|
|
(set! binds (car body))
|
|
|
|
(set! body (cdr body))))
|
|
|
|
((lambda (thelambda theargs)
|
|
|
|
(cons (if lname
|
|
|
|
(list 'label lname thelambda)
|
|
|
|
thelambda)
|
|
|
|
theargs))
|
2009-05-29 00:38:50 -04:00
|
|
|
(cons 'lambda
|
|
|
|
(cons (map (lambda (c) (if (pair? c) (car c) c)) binds)
|
|
|
|
body))
|
2009-02-05 22:41:24 -05:00
|
|
|
(map (lambda (c) (if (pair? c) (cadr c) #f)) binds))))
|
|
|
|
#f))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-04-08 14:17:02 -04:00
|
|
|
(define-macro (letrec binds . body)
|
2009-05-29 00:38:50 -04:00
|
|
|
(cons (cons 'lambda (cons (map car binds)
|
|
|
|
(nconc (map (lambda (b) (cons 'set! b)) binds)
|
|
|
|
body)))
|
|
|
|
(map (lambda (x) #f) binds)))
|
|
|
|
|
|
|
|
(define-macro (cond . clauses)
|
|
|
|
(define (cond-clauses->if lst)
|
|
|
|
(if (atom? lst)
|
|
|
|
#f
|
|
|
|
(let ((clause (car lst)))
|
|
|
|
(if (or (eq? (car clause) 'else)
|
|
|
|
(eq? (car clause) #t))
|
2009-05-30 13:04:34 -04:00
|
|
|
(if (null? (cdr clause))
|
|
|
|
(car clause)
|
|
|
|
(cons 'begin (cdr clause)))
|
|
|
|
(if (null? (cdr clause))
|
|
|
|
; test by itself
|
|
|
|
(list 'or
|
|
|
|
(car clause)
|
|
|
|
(cond-clauses->if (cdr lst)))
|
|
|
|
(list 'if
|
|
|
|
(car clause)
|
|
|
|
(cons 'begin (cdr clause))
|
|
|
|
(cond-clauses->if (cdr lst))))))))
|
2009-05-29 00:38:50 -04:00
|
|
|
(cond-clauses->if clauses))
|
2009-04-08 14:17:02 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; standard procedures ---------------------------------------------------------
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (append . lsts)
|
2009-01-31 20:53:58 -05:00
|
|
|
(cond ((null? lsts) ())
|
2009-04-08 14:17:02 -04:00
|
|
|
((null? (cdr lsts)) (car lsts))
|
2009-06-06 17:15:54 -04:00
|
|
|
(#t (copy-list (car lsts)
|
|
|
|
(apply append (cdr lsts))))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (member item lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(cond ((atom? lst) #f)
|
2009-03-01 23:26:16 -05:00
|
|
|
((equal? (car lst) item) lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (member item (cdr lst)))))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (memv item lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(cond ((atom? lst) #f)
|
2009-03-01 23:26:16 -05:00
|
|
|
((eqv? (car lst) item) lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (memv item (cdr lst)))))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
|
|
|
|
(define (assoc item lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(cond ((atom? lst) #f)
|
2009-03-01 23:26:16 -05:00
|
|
|
((equal? (caar lst) item) (car lst))
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (assoc item (cdr lst)))))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (assv item lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(cond ((atom? lst) #f)
|
2009-03-01 23:26:16 -05:00
|
|
|
((eqv? (caar lst) item) (car lst))
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (assv item (cdr lst)))))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
|
2009-04-15 19:54:43 -04:00
|
|
|
(define (/= a b) (not (= a b)))
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (> a b) (< b a))
|
2009-04-15 19:54:43 -04:00
|
|
|
(define (<= a b) (or (< a b) (= a b)))
|
|
|
|
(define (>= a b) (or (< b a) (= a b)))
|
2009-03-11 22:47:34 -04:00
|
|
|
(define (negative? x) (< x 0))
|
|
|
|
(define (zero? x) (= x 0))
|
|
|
|
(define (positive? x) (> x 0))
|
|
|
|
(define (even? x) (= (logand x 1) 0))
|
|
|
|
(define (odd? x) (not (even? x)))
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (1+ n) (+ n 1))
|
|
|
|
(define (1- n) (- n 1))
|
2009-05-14 13:54:59 -04:00
|
|
|
(define (mod0 x y) (- x (* (div0 x y) y)))
|
|
|
|
(define (div x y) (+ (div0 x y)
|
|
|
|
(or (and (< x 0)
|
|
|
|
(or (and (< y 0) 1)
|
|
|
|
-1))
|
|
|
|
0)))
|
2009-05-13 21:30:25 -04:00
|
|
|
(define (mod x y) (- x (* (div x y) y)))
|
2009-05-14 13:54:59 -04:00
|
|
|
(define remainder mod0)
|
2009-05-07 22:52:25 -04:00
|
|
|
(define (random n)
|
|
|
|
(if (integer? n)
|
2009-05-13 21:30:25 -04:00
|
|
|
(mod (rand) n)
|
2009-05-07 22:52:25 -04:00
|
|
|
(* (rand.double) n)))
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (abs x) (if (< x 0) (- x) x))
|
2009-02-09 00:38:40 -05:00
|
|
|
(define (identity x) x)
|
2009-03-01 23:26:16 -05:00
|
|
|
(define (char? x) (eq? (typeof x) 'wchar))
|
2009-05-08 00:08:31 -04:00
|
|
|
(define (array? x) (or (vector? x)
|
|
|
|
(let ((t (typeof x)))
|
|
|
|
(and (pair? t) (eq? (car t) 'array)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
|
|
|
(define (caar x) (car (car x)))
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (cadr x) (car (cdr x)))
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (cdar x) (cdr (car x)))
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (cddr x) (cdr (cdr x)))
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (caaar x) (car (car (car x))))
|
|
|
|
(define (caadr x) (car (car (cdr x))))
|
|
|
|
(define (cadar x) (car (cdr (car x))))
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (caddr x) (car (cdr (cdr x))))
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (cdaar x) (cdr (car (car x))))
|
|
|
|
(define (cdadr x) (cdr (car (cdr x))))
|
|
|
|
(define (cddar x) (cdr (cdr (car x))))
|
|
|
|
(define (cdddr x) (cdr (cdr (cdr x))))
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (cadddr x) (car (cdr (cdr (cdr x)))))
|
|
|
|
|
|
|
|
; list utilities --------------------------------------------------------------
|
2008-06-30 21:54:22 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (every pred lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(or (atom? lst)
|
2008-06-30 21:54:22 -04:00
|
|
|
(and (pred (car lst))
|
|
|
|
(every pred (cdr lst)))))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (any pred lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(and (pair? lst)
|
2008-06-30 21:54:22 -04:00
|
|
|
(or (pred (car lst))
|
|
|
|
(any pred (cdr lst)))))
|
|
|
|
|
2009-01-31 20:53:58 -05:00
|
|
|
(define (list? a) (or (null? a) (and (pair? a) (list? (cdr a)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-04-08 14:17:02 -04:00
|
|
|
(define (list-tail lst n)
|
2008-06-30 21:54:22 -04:00
|
|
|
(if (<= n 0) lst
|
2009-04-08 14:17:02 -04:00
|
|
|
(list-tail (cdr lst) (- n 1))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-04-01 00:31:49 -04:00
|
|
|
(define (list-head lst n)
|
|
|
|
(if (<= n 0) ()
|
|
|
|
(cons (car lst)
|
|
|
|
(list-head (cdr lst) (- n 1)))))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (list-ref lst n)
|
2009-04-08 14:17:02 -04:00
|
|
|
(car (list-tail lst n)))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-03-04 22:48:17 -05:00
|
|
|
; bounded length test
|
|
|
|
; use this instead of (= (length lst) n), since it avoids unnecessary
|
|
|
|
; work and always terminates.
|
|
|
|
(define (length= lst n)
|
|
|
|
(cond ((< n 0) #f)
|
2009-06-06 17:15:54 -04:00
|
|
|
((= n 0) (atom? lst))
|
|
|
|
((atom? lst) (= n 0))
|
2009-03-04 22:48:17 -05:00
|
|
|
(else (length= (cdr lst) (- n 1)))))
|
|
|
|
|
2009-05-31 17:06:04 -04:00
|
|
|
(define (length> lst n)
|
|
|
|
(cond ((< n 0) lst)
|
|
|
|
((= n 0) (and (pair? lst) lst))
|
2009-06-06 17:15:54 -04:00
|
|
|
((atom? lst) (< n 0))
|
2009-05-31 17:06:04 -04:00
|
|
|
(else (length> (cdr lst) (- n 1)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-04-08 14:17:02 -04:00
|
|
|
(define (last-pair l)
|
2009-05-31 17:06:04 -04:00
|
|
|
(if (atom? (cdr l))
|
|
|
|
l
|
|
|
|
(last-pair (cdr l))))
|
|
|
|
|
|
|
|
(define (lastcdr l)
|
|
|
|
(if (atom? l)
|
|
|
|
l
|
|
|
|
(cdr (last-pair l))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (to-proper l)
|
|
|
|
(cond ((null? l) l)
|
|
|
|
((atom? l) (list l))
|
|
|
|
(else (cons (car l) (to-proper (cdr l))))))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (map! f lst)
|
2008-06-30 21:54:22 -04:00
|
|
|
(prog1 lst
|
2009-01-31 20:53:58 -05:00
|
|
|
(while (pair? lst)
|
2009-03-01 23:26:16 -05:00
|
|
|
(set-car! lst (f (car lst)))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(set! lst (cdr lst)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-29 00:38:50 -04:00
|
|
|
(define mapcar
|
|
|
|
(letrec ((mapcar-
|
|
|
|
(lambda (f lsts)
|
|
|
|
(cond ((null? lsts) (f))
|
|
|
|
((atom? (car lsts)) (car lsts))
|
|
|
|
(#t (cons (apply f (map car lsts))
|
|
|
|
(mapcar- f (map cdr lsts))))))))
|
|
|
|
(lambda (f . lsts) (mapcar- f lsts))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-29 00:38:50 -04:00
|
|
|
(define filter
|
|
|
|
(letrec ((filter-
|
|
|
|
(lambda (pred lst accum)
|
|
|
|
(cond ((null? lst) accum)
|
|
|
|
((pred (car lst))
|
|
|
|
(filter- pred (cdr lst) (cons (car lst) accum)))
|
|
|
|
(#t
|
|
|
|
(filter- pred (cdr lst) accum))))))
|
|
|
|
(lambda (pred lst) (filter- pred lst ()))))
|
|
|
|
|
|
|
|
(define separate
|
|
|
|
(letrec ((separate-
|
|
|
|
(lambda (pred lst yes no)
|
|
|
|
(cond ((null? lst) (cons yes no))
|
|
|
|
((pred (car lst))
|
|
|
|
(separate- pred (cdr lst) (cons (car lst) yes) no))
|
|
|
|
(#t
|
|
|
|
(separate- pred (cdr lst) yes (cons (car lst) no)))))))
|
|
|
|
(lambda (pred lst) (separate- pred lst () ()))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-31 17:06:04 -04:00
|
|
|
(define (count f l)
|
|
|
|
(define (count- f l n)
|
|
|
|
(if (null? l)
|
|
|
|
n
|
|
|
|
(count- f (cdr l) (if (f (car l))
|
|
|
|
(+ n 1)
|
|
|
|
n))))
|
|
|
|
(count- f l 0))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (nestlist f zero n)
|
|
|
|
(if (<= n 0) ()
|
|
|
|
(cons zero (nestlist f (f zero) (- n 1)))))
|
|
|
|
|
2008-06-30 21:54:22 -04:00
|
|
|
(define (foldr f zero lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(if (null? lst) zero
|
2008-06-30 21:54:22 -04:00
|
|
|
(f (car lst) (foldr f zero (cdr lst)))))
|
|
|
|
|
|
|
|
(define (foldl f zero lst)
|
2009-01-31 20:53:58 -05:00
|
|
|
(if (null? lst) zero
|
2008-06-30 21:54:22 -04:00
|
|
|
(foldl f (f (car lst) zero) (cdr lst))))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (reverse lst) (foldl cons () lst))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-31 17:06:04 -04:00
|
|
|
(define (reverse! l)
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(let ((prev ()))
|
2009-01-31 20:53:58 -05:00
|
|
|
(while (pair? l)
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(set! l (prog1 (cdr l)
|
2009-03-01 23:26:16 -05:00
|
|
|
(set-cdr! l (prog1 prev
|
|
|
|
(set! prev l))))))
|
2008-06-30 21:54:22 -04:00
|
|
|
prev))
|
|
|
|
|
2009-05-30 17:13:13 -04:00
|
|
|
(define (copy-tree l)
|
|
|
|
(if (atom? l) l
|
|
|
|
(cons (copy-tree (car l))
|
|
|
|
(copy-tree (cdr l)))))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (delete-duplicates lst)
|
|
|
|
(if (atom? lst)
|
|
|
|
lst
|
|
|
|
(let ((elt (car lst))
|
|
|
|
(tail (cdr lst)))
|
|
|
|
(if (member elt tail)
|
|
|
|
(delete-duplicates tail)
|
|
|
|
(cons elt
|
|
|
|
(delete-duplicates tail))))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; backquote -------------------------------------------------------------------
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-31 17:06:04 -04:00
|
|
|
(define (revappend l1 l2) (nconc (reverse l1) l2))
|
|
|
|
(define (nreconc l1 l2) (nconc (reverse! l1) l2))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (self-evaluating? x)
|
2009-01-31 20:53:58 -05:00
|
|
|
(or (and (atom? x)
|
|
|
|
(not (symbol? x)))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(and (constant? x)
|
2009-04-17 10:41:15 -04:00
|
|
|
(symbol? x)
|
|
|
|
(eq x (top-level-value x)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define-macro (backquote x) (bq-process x))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (bq-process x)
|
2009-05-29 22:52:22 -04:00
|
|
|
(define (splice-form? x)
|
|
|
|
(or (and (pair? x) (or (eq (car x) '*comma-at*)
|
|
|
|
(eq (car x) '*comma-dot*)))
|
|
|
|
(eq x '*comma*)))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(cond ((self-evaluating? x)
|
2009-01-31 20:53:58 -05:00
|
|
|
(if (vector? x)
|
2009-03-01 23:26:16 -05:00
|
|
|
(let ((body (bq-process (vector->list x))))
|
2008-06-30 21:54:22 -04:00
|
|
|
(if (eq (car body) 'list)
|
|
|
|
(cons vector (cdr body))
|
|
|
|
(list apply vector body)))
|
|
|
|
x))
|
2009-01-31 20:53:58 -05:00
|
|
|
((atom? x) (list 'quote x))
|
2008-06-30 21:54:22 -04:00
|
|
|
((eq (car x) 'backquote) (bq-process (bq-process (cadr x))))
|
|
|
|
((eq (car x) '*comma*) (cadr x))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
((not (any splice-form? x))
|
2008-06-30 21:54:22 -04:00
|
|
|
(let ((lc (lastcdr x))
|
|
|
|
(forms (map bq-bracket1 x)))
|
2009-01-31 20:53:58 -05:00
|
|
|
(if (null? lc)
|
2008-06-30 21:54:22 -04:00
|
|
|
(cons 'list forms)
|
2009-05-31 14:58:09 -04:00
|
|
|
(nconc (cons 'list* forms) (list (bq-process lc))))))
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (let ((p x) (q ()))
|
|
|
|
(while (and (pair? p)
|
|
|
|
(not (eq (car p) '*comma*)))
|
|
|
|
(set! q (cons (bq-bracket (car p)) q))
|
|
|
|
(set! p (cdr p)))
|
|
|
|
(let ((forms
|
|
|
|
(cond ((pair? p) (nreconc q (list (cadr p))))
|
2009-05-31 17:06:04 -04:00
|
|
|
((null? p) (reverse! q))
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (nreconc q (list (bq-process p)))))))
|
|
|
|
(if (null? (cdr forms))
|
|
|
|
(car forms)
|
|
|
|
(cons 'nconc forms)))))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (bq-bracket x)
|
2009-01-31 20:53:58 -05:00
|
|
|
(cond ((atom? x) (list list (bq-process x)))
|
2008-12-30 23:45:08 -05:00
|
|
|
((eq (car x) '*comma*) (list list (cadr x)))
|
2008-06-30 21:54:22 -04:00
|
|
|
((eq (car x) '*comma-at*) (list 'copy-list (cadr x)))
|
|
|
|
((eq (car x) '*comma-dot*) (cadr x))
|
2009-01-31 20:53:58 -05:00
|
|
|
(#t (list list (bq-process x)))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
|
|
|
; bracket without splicing
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (bq-bracket1 x)
|
2009-01-31 20:53:58 -05:00
|
|
|
(if (and (pair? x) (eq (car x) '*comma*))
|
2008-06-30 21:54:22 -04:00
|
|
|
(cadr x)
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(bq-process x)))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; standard macros -------------------------------------------------------------
|
|
|
|
|
2009-02-20 00:11:05 -05:00
|
|
|
(define (quote-value v)
|
|
|
|
(if (self-evaluating? v)
|
|
|
|
v
|
|
|
|
(list 'quote v)))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define-macro (let* binds . body)
|
2009-05-29 00:38:50 -04:00
|
|
|
(if (atom? binds) `((lambda () ,@body))
|
2009-04-01 18:23:19 -04:00
|
|
|
`((lambda (,(caar binds))
|
2009-05-29 00:38:50 -04:00
|
|
|
,@(if (pair? (cdr binds))
|
|
|
|
`((let* ,(cdr binds) ,@body))
|
|
|
|
body))
|
2009-04-01 18:23:19 -04:00
|
|
|
,(cadar binds))))
|
|
|
|
|
2009-05-20 20:56:25 -04:00
|
|
|
(define-macro (when c . body) (list 'if c (cons 'begin body) #f))
|
|
|
|
(define-macro (unless c . body) (list 'if c #f (cons 'begin body)))
|
2009-03-28 17:39:04 -04:00
|
|
|
|
2009-02-20 00:11:05 -05:00
|
|
|
(define-macro (case key . clauses)
|
2009-03-01 23:26:16 -05:00
|
|
|
(define (vals->cond key v)
|
2009-02-20 00:11:05 -05:00
|
|
|
(cond ((eq? v 'else) 'else)
|
|
|
|
((null? v) #f)
|
2009-06-10 20:34:50 -04:00
|
|
|
((symbol? v) `(eq? ,key ,(quote-value v)))
|
2009-03-13 10:54:48 -04:00
|
|
|
((atom? v) `(eqv? ,key ,(quote-value v)))
|
2009-02-20 00:11:05 -05:00
|
|
|
((null? (cdr v)) `(eqv? ,key ,(quote-value (car v))))
|
2009-06-10 20:34:50 -04:00
|
|
|
((every symbol? v)
|
|
|
|
`(memq ,key ',v))
|
2009-02-20 00:11:05 -05:00
|
|
|
(else `(memv ,key ',v))))
|
|
|
|
(let ((g (gensym)))
|
|
|
|
`(let ((,g ,key))
|
|
|
|
(cond ,@(map (lambda (clause)
|
2009-03-01 23:26:16 -05:00
|
|
|
(cons (vals->cond g (car clause))
|
2009-02-20 00:11:05 -05:00
|
|
|
(cdr clause)))
|
|
|
|
clauses)))))
|
|
|
|
|
2009-02-20 14:50:35 -05:00
|
|
|
(define-macro (do vars test-spec . commands)
|
|
|
|
(let ((loop (gensym))
|
|
|
|
(test-expr (car test-spec))
|
|
|
|
(vars (map car vars))
|
|
|
|
(inits (map cadr vars))
|
|
|
|
(steps (map (lambda (x)
|
|
|
|
(if (pair? (cddr x))
|
|
|
|
(caddr x)
|
|
|
|
(car x)))
|
|
|
|
vars)))
|
|
|
|
`(letrec ((,loop (lambda ,vars
|
|
|
|
(if ,test-expr
|
|
|
|
(begin
|
|
|
|
,@(cdr test-spec))
|
|
|
|
(begin
|
|
|
|
,@commands
|
|
|
|
(,loop ,@steps))))))
|
|
|
|
(,loop ,@inits))))
|
|
|
|
|
2009-02-20 00:11:05 -05:00
|
|
|
(define-macro (dotimes var . body)
|
|
|
|
(let ((v (car var))
|
|
|
|
(cnt (cadr var)))
|
|
|
|
`(for 0 (- ,cnt 1)
|
2009-05-29 00:38:50 -04:00
|
|
|
(lambda (,v) ,@body))))
|
2009-02-20 00:11:05 -05:00
|
|
|
|
|
|
|
(define (map-int f n)
|
|
|
|
(if (<= n 0)
|
|
|
|
()
|
|
|
|
(let ((first (cons (f 0) ()))
|
|
|
|
(acc ()))
|
|
|
|
(set! acc first)
|
|
|
|
(for 1 (- n 1)
|
|
|
|
(lambda (i)
|
2009-03-01 23:26:16 -05:00
|
|
|
(begin (set-cdr! acc (cons (f i) ()))
|
2009-02-20 00:11:05 -05:00
|
|
|
(set! acc (cdr acc)))))
|
|
|
|
first)))
|
|
|
|
|
|
|
|
(define (iota n) (map-int identity n))
|
|
|
|
|
2009-03-11 22:47:34 -04:00
|
|
|
(define (for-each f l)
|
2009-03-12 23:30:10 -04:00
|
|
|
(if (pair? l)
|
|
|
|
(begin (f (car l))
|
|
|
|
(for-each f (cdr l)))
|
|
|
|
#t))
|
2009-03-11 22:47:34 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; exceptions ------------------------------------------------------------------
|
|
|
|
|
2009-02-20 00:11:05 -05:00
|
|
|
(define (error . args) (raise (cons 'error args)))
|
|
|
|
|
|
|
|
(define-macro (throw tag value) `(raise (list 'thrown-value ,tag ,value)))
|
|
|
|
(define-macro (catch tag expr)
|
|
|
|
(let ((e (gensym)))
|
|
|
|
`(trycatch ,expr
|
|
|
|
(lambda (,e) (if (and (pair? ,e)
|
|
|
|
(eq (car ,e) 'thrown-value)
|
|
|
|
(eq (cadr ,e) ,tag))
|
|
|
|
(caddr ,e)
|
|
|
|
(raise ,e))))))
|
|
|
|
|
|
|
|
(define-macro (unwind-protect expr finally)
|
2009-05-05 00:01:06 -04:00
|
|
|
(let ((e (gensym))
|
|
|
|
(thk (gensym)))
|
|
|
|
`(let ((,thk (lambda () ,finally)))
|
|
|
|
(prog1 (trycatch ,expr
|
|
|
|
(lambda (,e) (begin (,thk) (raise ,e))))
|
|
|
|
(,thk)))))
|
2009-02-20 00:11:05 -05:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; debugging utilities ---------------------------------------------------------
|
2009-03-11 22:47:34 -04:00
|
|
|
|
2009-01-31 20:53:58 -05:00
|
|
|
(define-macro (assert expr) `(if ,expr #t (raise '(assert-failed ,expr))))
|
2008-06-30 21:54:22 -04:00
|
|
|
|
2009-05-29 00:38:50 -04:00
|
|
|
(define traced?
|
|
|
|
(letrec ((sample-traced-lambda (lambda args (begin (println (cons 'x args))
|
|
|
|
(apply #.apply args)))))
|
|
|
|
(lambda (f)
|
|
|
|
(equal? (function:code f)
|
|
|
|
(function:code sample-traced-lambda)))))
|
2009-05-12 21:13:40 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (trace sym)
|
2009-05-12 21:13:40 -04:00
|
|
|
(let* ((func (top-level-value sym))
|
|
|
|
(args (gensym)))
|
|
|
|
(if (not (traced? func))
|
2009-04-17 10:41:15 -04:00
|
|
|
(set-top-level-value! sym
|
2009-05-12 21:13:40 -04:00
|
|
|
(eval
|
|
|
|
`(lambda ,args
|
|
|
|
(begin (println (cons ',sym ,args))
|
|
|
|
(apply ',func ,args)))))))
|
2009-03-28 17:39:04 -04:00
|
|
|
'ok)
|
|
|
|
|
|
|
|
(define (untrace sym)
|
2009-05-12 21:13:40 -04:00
|
|
|
(let ((func (top-level-value sym)))
|
|
|
|
(if (traced? func)
|
2009-04-17 10:41:15 -04:00
|
|
|
(set-top-level-value! sym
|
2009-05-12 21:13:40 -04:00
|
|
|
(aref (function:vals func) 2)))))
|
2009-03-28 17:39:04 -04:00
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define-macro (time expr)
|
2008-06-30 21:54:22 -04:00
|
|
|
(let ((t0 (gensym)))
|
|
|
|
`(let ((,t0 (time.now)))
|
|
|
|
(prog1
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
,expr
|
|
|
|
(princ "Elapsed time: " (- (time.now) ,t0) " seconds\n")))))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; text I/O --------------------------------------------------------------------
|
|
|
|
|
2009-05-08 00:08:31 -04:00
|
|
|
(define (print . args) (apply io.print *output-stream* args))
|
|
|
|
(define (princ . args) (apply io.princ *output-stream* args))
|
2009-03-28 17:39:04 -04:00
|
|
|
|
2009-04-01 00:31:49 -04:00
|
|
|
(define (newline) (princ *linefeed*) #t)
|
2009-01-31 20:53:58 -05:00
|
|
|
(define (display x) (princ x) #t)
|
2009-03-26 23:06:55 -04:00
|
|
|
(define (println . args) (prog1 (apply print args) (newline)))
|
2009-01-31 20:53:58 -05:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (io.readline s) (io.readuntil s #\x0a))
|
|
|
|
|
|
|
|
; vector functions ------------------------------------------------------------
|
|
|
|
|
|
|
|
(define (list->vector l) (apply vector l))
|
|
|
|
(define (vector->list v)
|
|
|
|
(let ((n (length v))
|
|
|
|
(l ()))
|
|
|
|
(for 1 n
|
|
|
|
(lambda (i)
|
|
|
|
(set! l (cons (aref v (- n i)) l))))
|
|
|
|
l))
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (vector.map f v)
|
2008-12-21 00:55:00 -05:00
|
|
|
(let* ((n (length v))
|
|
|
|
(nv (vector.alloc n)))
|
|
|
|
(for 0 (- n 1)
|
|
|
|
(lambda (i)
|
2009-01-31 20:53:58 -05:00
|
|
|
(aset! nv i (f (aref v i)))))
|
2008-12-21 00:55:00 -05:00
|
|
|
nv))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; table functions -------------------------------------------------------------
|
|
|
|
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (table.pairs t)
|
2008-12-21 00:55:00 -05:00
|
|
|
(table.foldl (lambda (k v z) (cons (cons k v) z))
|
|
|
|
() t))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (table.keys t)
|
2008-12-21 00:55:00 -05:00
|
|
|
(table.foldl (lambda (k v z) (cons k z))
|
|
|
|
() t))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (table.values t)
|
2008-12-21 00:55:00 -05:00
|
|
|
(table.foldl (lambda (k v z) (cons v z))
|
|
|
|
() t))
|
switching to scheme #t, #f, and () values
porting code to sort out which NILs are false and which are
empty lists
switching to scheme-style special forms. however you feel about
scheme names vs. CL names, using both is silly.
mostly switching to scheme predicate names, with compatibility
aliases for now. adding set-constant! to make this efficient.
adding null?, eqv?, assq, assv, assoc, memq, memv, member
adding 2-argument form of if
allowing else as final cond condition
looking for init file in same directory as executable, so flisp
can be started from anywhere
renaming T to FL_T, since exporting a 1-character symbol is
not very nice
adding opaque type boilerplate example file
adding correctness checking for the pattern-lambda benchmark
bugfix in int2str
2009-01-28 20:04:23 -05:00
|
|
|
(define (table.clone t)
|
2008-12-22 01:36:50 -05:00
|
|
|
(let ((nt (table)))
|
2009-01-31 20:53:58 -05:00
|
|
|
(table.foldl (lambda (k v z) (put! nt k v))
|
2008-12-22 01:36:50 -05:00
|
|
|
() t)
|
|
|
|
nt))
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (table.invert t)
|
|
|
|
(let ((nt (table)))
|
|
|
|
(table.foldl (lambda (k v z) (put! nt v k))
|
|
|
|
() t)
|
|
|
|
nt))
|
|
|
|
(define (table.foreach f t)
|
|
|
|
(table.foldl (lambda (k v z) (begin (f k v) #t)) () t))
|
2009-02-05 22:41:24 -05:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; string functions ------------------------------------------------------------
|
2009-02-18 22:31:40 -05:00
|
|
|
|
2009-05-06 22:10:52 -04:00
|
|
|
(define (string.tail s n) (string.sub s (string.inc s 0 n)))
|
2009-02-19 17:29:47 -05:00
|
|
|
|
2009-02-27 20:59:01 -05:00
|
|
|
(define *whitespace*
|
|
|
|
(string.encode #array(wchar 9 10 11 12 13 32 133 160 5760 6158 8192
|
|
|
|
8193 8194 8195 8196 8197 8198 8199 8200
|
|
|
|
8201 8202 8232 8233 8239 8287 12288)))
|
|
|
|
|
|
|
|
(define (string.trim s at-start at-end)
|
|
|
|
(define (trim-start s chars i L)
|
2009-04-08 14:17:02 -04:00
|
|
|
(if (and (< i L)
|
|
|
|
(string.find chars (string.char s i)))
|
|
|
|
(trim-start s chars (string.inc s i) L)
|
2009-02-27 20:59:01 -05:00
|
|
|
i))
|
|
|
|
(define (trim-end s chars i)
|
|
|
|
(if (and (> i 0)
|
2009-04-08 14:17:02 -04:00
|
|
|
(string.find chars (string.char s (string.dec s i))))
|
|
|
|
(trim-end s chars (string.dec s i))
|
2009-02-27 20:59:01 -05:00
|
|
|
i))
|
2009-04-08 14:17:02 -04:00
|
|
|
(let ((L (length s)))
|
2009-02-27 20:59:01 -05:00
|
|
|
(string.sub s
|
|
|
|
(trim-start s at-start 0 L)
|
|
|
|
(trim-end s at-end L))))
|
|
|
|
|
2009-03-04 22:48:17 -05:00
|
|
|
(define (string.map f s)
|
|
|
|
(let ((b (buffer))
|
2009-04-08 14:17:02 -04:00
|
|
|
(n (length s)))
|
2009-03-12 23:30:10 -04:00
|
|
|
(let ((i 0))
|
2009-04-08 14:17:02 -04:00
|
|
|
(while (< i n)
|
|
|
|
(begin (io.putc b (f (string.char s i)))
|
|
|
|
(set! i (string.inc s i)))))
|
2009-03-12 23:30:10 -04:00
|
|
|
(io.tostring! b)))
|
2009-03-04 22:48:17 -05:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (string.rep s k)
|
|
|
|
(cond ((< k 4)
|
|
|
|
(cond ((<= k 0) "")
|
|
|
|
((= k 1) (string s))
|
|
|
|
((= k 2) (string s s))
|
|
|
|
(else (string s s s))))
|
|
|
|
((odd? k) (string s (string.rep s (- k 1))))
|
|
|
|
(else (string.rep (string s s) (/ k 2)))))
|
|
|
|
|
2009-05-29 22:52:22 -04:00
|
|
|
(define (string.lpad s n c) (string (string.rep c (- n (string.count s))) s))
|
|
|
|
(define (string.rpad s n c) (string s (string.rep c (- n (string.count s)))))
|
2009-03-28 17:39:04 -04:00
|
|
|
|
2009-03-04 22:48:17 -05:00
|
|
|
(define (print-to-string v)
|
|
|
|
(let ((b (buffer)))
|
|
|
|
(io.print b v)
|
|
|
|
(io.tostring! b)))
|
|
|
|
|
2009-04-19 12:48:09 -04:00
|
|
|
(define (string.join strlist sep)
|
|
|
|
(if (null? strlist) ""
|
|
|
|
(let ((b (buffer)))
|
|
|
|
(io.write b (car strlist))
|
|
|
|
(for-each (lambda (s) (begin (io.write b sep)
|
|
|
|
(io.write b s)))
|
|
|
|
(cdr strlist))
|
|
|
|
(io.tostring! b))))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
; toplevel --------------------------------------------------------------------
|
|
|
|
|
2009-05-29 00:38:50 -04:00
|
|
|
(define get-defined-vars
|
|
|
|
(letrec ((get-defined-vars-
|
|
|
|
(lambda (expr)
|
|
|
|
(cond ((atom? expr) ())
|
|
|
|
((and (eq? (car expr) 'define)
|
|
|
|
(pair? (cdr expr)))
|
|
|
|
(or (and (symbol? (cadr expr))
|
|
|
|
(list (cadr expr)))
|
|
|
|
(and (pair? (cadr expr))
|
|
|
|
(symbol? (caadr expr))
|
|
|
|
(list (caadr expr)))
|
|
|
|
()))
|
|
|
|
((eq? (car expr) 'begin)
|
|
|
|
(apply append (map get-defined-vars- (cdr expr))))
|
|
|
|
(else ())))))
|
|
|
|
(lambda (expr) (delete-duplicates (get-defined-vars- expr)))))
|
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (macrocall? e) (and (symbol? (car e))
|
2009-04-20 20:56:05 -04:00
|
|
|
(get *syntax-environment* (car e) #f)))
|
2009-03-28 17:39:04 -04:00
|
|
|
|
|
|
|
(define (macroexpand-1 e)
|
|
|
|
(if (atom? e) e
|
|
|
|
(let ((f (macrocall? e)))
|
|
|
|
(if f (apply f (cdr e))
|
|
|
|
e))))
|
|
|
|
|
2009-05-30 17:13:13 -04:00
|
|
|
(define (macroexpand e)
|
|
|
|
(define (expand-lambda e env)
|
|
|
|
(let ((B (if (pair? (cddr e))
|
|
|
|
(if (pair? (cdddr e))
|
|
|
|
(cons 'begin (cddr e))
|
|
|
|
(caddr e))
|
|
|
|
#f)))
|
|
|
|
(let ((V (get-defined-vars B))
|
|
|
|
(Be (macroexpand-in B env)))
|
2009-05-31 14:58:09 -04:00
|
|
|
(list* 'lambda
|
|
|
|
(cadr e)
|
|
|
|
(if (null? V)
|
|
|
|
Be
|
|
|
|
(cons (list 'lambda V Be)
|
|
|
|
(map (lambda (x) #f) V)))
|
|
|
|
(lastcdr e)))))
|
2009-05-30 17:13:13 -04:00
|
|
|
(define (macroexpand-in e env)
|
|
|
|
(if (atom? e) e
|
|
|
|
(let ((f (assq (car e) env)))
|
|
|
|
(if f
|
|
|
|
(macroexpand-in (apply (cadr f) (cdr e)) (caddr f))
|
|
|
|
(let ((f (macrocall? e)))
|
|
|
|
(if f
|
|
|
|
(macroexpand-in (apply f (cdr e)) env)
|
|
|
|
(cond ((eq (car e) 'quote) e)
|
|
|
|
((eq (car e) 'lambda) (expand-lambda e env))
|
|
|
|
((eq (car e) 'let-syntax)
|
|
|
|
(let ((binds (cadr e))
|
|
|
|
(body `((lambda () ,@(cddr e)))))
|
|
|
|
(macroexpand-in
|
|
|
|
body
|
|
|
|
(nconc
|
|
|
|
(map (lambda (bind)
|
|
|
|
(list (car bind)
|
|
|
|
(macroexpand-in (cadr bind) env)
|
|
|
|
env))
|
|
|
|
binds)
|
|
|
|
env))))
|
|
|
|
(else
|
|
|
|
(map (lambda (x) (macroexpand-in x env)) e)))))))))
|
|
|
|
(macroexpand-in e ()))
|
2009-03-28 17:39:04 -04:00
|
|
|
|
|
|
|
(define (expand x) (macroexpand x))
|
|
|
|
|
2009-04-20 20:56:05 -04:00
|
|
|
(define (eval x) ((compile-thunk (expand x))))
|
|
|
|
|
|
|
|
(define (load-process x) (eval x))
|
2009-04-14 20:12:01 -04:00
|
|
|
|
2009-03-28 17:39:04 -04:00
|
|
|
(define (load filename)
|
|
|
|
(let ((F (file filename :read)))
|
|
|
|
(trycatch
|
|
|
|
(let next (prev E v)
|
|
|
|
(if (not (io.eof? F))
|
|
|
|
(next (read F)
|
|
|
|
prev
|
2009-04-14 20:12:01 -04:00
|
|
|
(load-process E))
|
2009-03-28 17:39:04 -04:00
|
|
|
(begin (io.close F)
|
|
|
|
; evaluate last form in almost-tail position
|
2009-04-14 20:12:01 -04:00
|
|
|
(load-process E))))
|
2009-03-28 17:39:04 -04:00
|
|
|
(lambda (e)
|
|
|
|
(begin
|
|
|
|
(io.close F)
|
|
|
|
(raise `(load-error ,filename ,e)))))))
|
|
|
|
|
|
|
|
(define *banner* (string.tail "
|
|
|
|
; _
|
|
|
|
; |_ _ _ |_ _ | . _ _
|
|
|
|
; | (-||||_(_)|__|_)|_)
|
|
|
|
;-------------------|----------------------------------------------------------
|
|
|
|
|
|
|
|
" 1))
|
2009-03-02 22:16:30 -05:00
|
|
|
|
2009-02-18 22:31:40 -05:00
|
|
|
(define (repl)
|
|
|
|
(define (prompt)
|
|
|
|
(princ "> ") (io.flush *output-stream*)
|
|
|
|
(let ((v (trycatch (read)
|
|
|
|
(lambda (e) (begin (io.discardbuffer *input-stream*)
|
|
|
|
(raise e))))))
|
|
|
|
(and (not (io.eof? *input-stream*))
|
2009-04-17 10:41:15 -04:00
|
|
|
(let ((V (load-process v)))
|
2009-02-18 22:31:40 -05:00
|
|
|
(print V)
|
|
|
|
(set! that V)
|
|
|
|
#t))))
|
|
|
|
(define (reploop)
|
2009-03-26 23:06:55 -04:00
|
|
|
(when (trycatch (and (prompt) (newline))
|
2009-04-14 20:12:01 -04:00
|
|
|
(lambda (e) (print-exception e)))
|
2009-03-26 23:06:55 -04:00
|
|
|
(begin (newline)
|
2009-02-18 22:31:40 -05:00
|
|
|
(reploop))))
|
|
|
|
(reploop)
|
2009-03-26 23:06:55 -04:00
|
|
|
(newline))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
|
|
|
(define (print-exception e)
|
2009-05-08 00:08:31 -04:00
|
|
|
(define (eprinc . args) (apply io.princ *error-stream* args))
|
|
|
|
(define (eprint . args) (apply io.print *error-stream* args))
|
2009-02-18 22:31:40 -05:00
|
|
|
(cond ((and (pair? e)
|
|
|
|
(eq? (car e) 'type-error)
|
2009-03-04 22:48:17 -05:00
|
|
|
(length= e 4))
|
2009-05-05 19:51:13 -04:00
|
|
|
(eprinc "type-error: " (cadr e) ": expected " (caddr e) ", got ")
|
|
|
|
(eprint (cadddr e)))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
|
|
|
((and (pair? e)
|
|
|
|
(eq? (car e) 'unbound-error)
|
|
|
|
(pair? (cdr e)))
|
2009-05-05 19:51:13 -04:00
|
|
|
(eprinc "unbound-error: eval: variable " (cadr e)
|
|
|
|
" has no value"))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
|
|
|
((and (pair? e)
|
|
|
|
(eq? (car e) 'error))
|
2009-05-05 19:51:13 -04:00
|
|
|
(eprinc "error: ")
|
|
|
|
(apply eprinc (cdr e)))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
|
|
|
((and (pair? e)
|
|
|
|
(eq? (car e) 'load-error))
|
|
|
|
(print-exception (caddr e))
|
2009-05-05 19:51:13 -04:00
|
|
|
(eprinc "in file " (cadr e)))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
|
|
|
((and (list? e)
|
2009-03-04 22:48:17 -05:00
|
|
|
(length= e 2))
|
2009-05-31 18:09:26 -04:00
|
|
|
(eprint (car e))
|
|
|
|
(eprinc ": ")
|
2009-03-04 22:48:17 -05:00
|
|
|
(let ((msg (cadr e)))
|
|
|
|
((if (or (string? msg) (symbol? msg))
|
2009-05-05 19:51:13 -04:00
|
|
|
eprinc eprint)
|
|
|
|
msg)))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
2009-05-05 19:51:13 -04:00
|
|
|
(else (eprinc "*** Unhandled exception: ")
|
|
|
|
(eprint e)))
|
2009-02-18 22:31:40 -05:00
|
|
|
|
2009-05-05 19:51:13 -04:00
|
|
|
(eprinc *linefeed*)
|
2009-02-18 22:31:40 -05:00
|
|
|
#t)
|
|
|
|
|
2009-05-07 22:52:25 -04:00
|
|
|
(define (simple-sort l)
|
|
|
|
(if (or (null? l) (null? (cdr l))) l
|
|
|
|
(let* ((piv (car l))
|
|
|
|
(halves (separate (lambda (x) (< x piv)) (cdr l))))
|
|
|
|
(nconc (simple-sort (car halves))
|
|
|
|
(list piv)
|
|
|
|
(simple-sort (cdr halves))))))
|
|
|
|
|
2009-04-20 20:56:05 -04:00
|
|
|
(define (make-system-image fname)
|
2009-04-21 10:53:18 -04:00
|
|
|
(let ((f (file fname :write :create :truncate))
|
2009-04-21 17:41:32 -04:00
|
|
|
(excludes '(*linefeed* *directory-separator* *argv* that
|
2009-05-05 19:51:13 -04:00
|
|
|
*print-pretty* *print-width* *print-readably*))
|
2009-04-26 18:19:32 -04:00
|
|
|
(pp *print-pretty*))
|
|
|
|
(set! *print-pretty* #f)
|
|
|
|
(unwind-protect
|
|
|
|
(for-each (lambda (s)
|
|
|
|
(if (and (bound? s)
|
|
|
|
(not (constant? s))
|
|
|
|
(not (builtin? (top-level-value s)))
|
|
|
|
(not (memq s excludes))
|
|
|
|
(not (iostream? (top-level-value s))))
|
|
|
|
(begin
|
|
|
|
(io.print f s) (io.write f "\n")
|
|
|
|
(io.print f (top-level-value s)) (io.write f "\n"))))
|
2009-05-31 17:06:04 -04:00
|
|
|
(reverse! (simple-sort (environment))))
|
2009-04-26 18:19:32 -04:00
|
|
|
(begin
|
|
|
|
(io.close f)
|
|
|
|
(set! *print-pretty* pp)))))
|
2009-04-20 20:56:05 -04:00
|
|
|
|
|
|
|
; initialize globals that need to be set at load time
|
|
|
|
(define (__init_globals)
|
|
|
|
(if (or (eq? *os-name* 'win32)
|
|
|
|
(eq? *os-name* 'win64)
|
|
|
|
(eq? *os-name* 'windows))
|
|
|
|
(begin (set! *directory-separator* "\\")
|
|
|
|
(set! *linefeed* "\r\n"))
|
|
|
|
(begin (set! *directory-separator* "/")
|
|
|
|
(set! *linefeed* "\n")))
|
|
|
|
(set! *output-stream* *stdout*)
|
2009-05-05 19:51:13 -04:00
|
|
|
(set! *input-stream* *stdin*)
|
|
|
|
(set! *error-stream* *stderr*))
|
2009-04-20 20:56:05 -04:00
|
|
|
|
2009-02-18 22:31:40 -05:00
|
|
|
(define (__script fname)
|
|
|
|
(trycatch (load fname)
|
|
|
|
(lambda (e) (begin (print-exception e)
|
|
|
|
(exit 1)))))
|
|
|
|
|
2009-04-16 23:40:52 -04:00
|
|
|
(define (__start argv)
|
2009-04-20 20:56:05 -04:00
|
|
|
(__init_globals)
|
2009-02-18 22:31:40 -05:00
|
|
|
(if (pair? (cdr argv))
|
|
|
|
(begin (set! *argv* (cdr argv))
|
|
|
|
(__script (cadr argv)))
|
|
|
|
(begin (set! *argv* argv)
|
|
|
|
(princ *banner*)
|
|
|
|
(repl)))
|
|
|
|
(exit 0))
|