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
This commit is contained in:
parent
38cf75733e
commit
a55b46e9a6
|
@ -1,3 +1,4 @@
|
|||
; -*- scheme -*-
|
||||
; utilities for AST processing
|
||||
|
||||
(define (symconcat s1 s2)
|
||||
|
@ -9,13 +10,13 @@
|
|||
(cons item lst)))
|
||||
|
||||
(define (index-of item lst start)
|
||||
(cond ((null lst) nil)
|
||||
(cond ((null lst) #f)
|
||||
((eq item (car lst)) start)
|
||||
(T (index-of item (cdr lst) (+ start 1)))))
|
||||
|
||||
(define (each f l)
|
||||
(if (null l) l
|
||||
(progn (f (car l))
|
||||
(begin (f (car l))
|
||||
(each f (cdr l)))))
|
||||
|
||||
(define (maptree-pre f tr)
|
||||
|
@ -136,19 +137,19 @@
|
|||
env))))
|
||||
|
||||
; flatten op with any associativity
|
||||
(defmacro flatten-all-op (op e)
|
||||
(define-macro (flatten-all-op op e)
|
||||
`(pattern-expand
|
||||
(pattern-lambda (,op (-- l ...) (-- inner (,op ...)) (-- r ...))
|
||||
(cons ',op (append l (cdr inner) r)))
|
||||
,e))
|
||||
|
||||
(defmacro pattern-lambda (pat body)
|
||||
(define-macro (pattern-lambda pat body)
|
||||
(let* ((args (patargs pat))
|
||||
(expander `(lambda ,args ,body)))
|
||||
`(lambda (expr)
|
||||
(let ((m (match ',pat expr)))
|
||||
(if m
|
||||
; matches; perform expansion
|
||||
(apply ,expander (map (lambda (var) (cdr (or (assoc var m) '(0 . nil))))
|
||||
(apply ,expander (map (lambda (var) (cdr (or (assq var m) '(0 . #f))))
|
||||
',args))
|
||||
nil)))))
|
||||
#f)))))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
; -*- scheme -*-
|
||||
; tree regular expression pattern matching
|
||||
; by Jeff Bezanson
|
||||
|
||||
|
@ -41,12 +42,12 @@
|
|||
(cond ((symbolp p)
|
||||
(cond ((eq p '_) state)
|
||||
(T
|
||||
(let ((capt (assoc p state)))
|
||||
(let ((capt (assq p state)))
|
||||
(if capt
|
||||
(and (equal expr (cdr capt)) state)
|
||||
(cons (cons p expr) state))))))
|
||||
|
||||
((functionp p)
|
||||
((function? p)
|
||||
(and (p expr) state))
|
||||
|
||||
((consp p)
|
||||
|
@ -56,7 +57,7 @@
|
|||
(and (match- (caddr p) expr state)
|
||||
(cons (cons (cadr p) expr) state)))
|
||||
((eq (car p) '-$) ; greedy alternation for toplevel pattern
|
||||
(match-alt (cdr p) () (list expr) state nil 1))
|
||||
(match-alt (cdr p) () (list expr) state #f 1))
|
||||
(T
|
||||
(and (consp expr)
|
||||
(equal (car p) (car expr))
|
||||
|
@ -67,7 +68,7 @@
|
|||
|
||||
; match an alternation
|
||||
(define (match-alt alt prest expr state var L)
|
||||
(if (null alt) nil ; no alternatives left
|
||||
(if (null alt) #f ; no alternatives left
|
||||
(let ((subma (match- (car alt) (car expr) state)))
|
||||
(or (and subma
|
||||
(match-seq prest (cdr expr)
|
||||
|
@ -81,7 +82,7 @@
|
|||
; match generalized kleene star (try consuming min to max)
|
||||
(define (match-star- p prest expr state var min max L sofar)
|
||||
(cond ; case 0: impossible to match
|
||||
((> min max) nil)
|
||||
((> min max) #f)
|
||||
; case 1: only allowed to match 0 subexpressions
|
||||
((= max 0) (match-seq prest expr
|
||||
(if var (cons (cons var (reverse sofar)) state)
|
||||
|
@ -101,16 +102,16 @@
|
|||
|
||||
; match sequences of expressions
|
||||
(define (match-seq p expr state L)
|
||||
(cond ((not state) nil)
|
||||
((null p) (if (null expr) state nil))
|
||||
(cond ((not state) #f)
|
||||
((null p) (if (null expr) state #f))
|
||||
(T
|
||||
(let ((subp (car p))
|
||||
(var nil))
|
||||
(var #f))
|
||||
(if (and (consp subp)
|
||||
(eq (car subp) '--))
|
||||
(progn (setq var (cadr subp))
|
||||
(setq subp (caddr subp)))
|
||||
nil)
|
||||
(begin (set! var (cadr subp))
|
||||
(set! subp (caddr subp)))
|
||||
#f)
|
||||
(let ((head (if (consp subp) (car subp) ())))
|
||||
(cond ((eq subp '...)
|
||||
(match-star '_ (cdr p) expr state var 0 L L))
|
||||
|
@ -149,7 +150,7 @@
|
|||
; returns the new expression, or expr if no matches
|
||||
(define (apply-patterns plist expr)
|
||||
(if (null plist) expr
|
||||
(if (functionp plist)
|
||||
(if (function? plist)
|
||||
(let ((enew (plist expr)))
|
||||
(if (not enew)
|
||||
expr
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,4 @@
|
|||
; -*- scheme -*-
|
||||
(load "match.lsp")
|
||||
(load "asttools.lsp")
|
||||
|
||||
|
@ -18,10 +19,14 @@
|
|||
|
||||
; transformations
|
||||
|
||||
(let ((ctr 0))
|
||||
(define (r-gensym) (prog1 (intern (string "%r:" ctr))
|
||||
(set! ctr (+ ctr 1)))))
|
||||
|
||||
(define (dollarsign-transform e)
|
||||
(pattern-expand
|
||||
(pattern-lambda ($ lhs name)
|
||||
(let* ((g (if (not (consp lhs)) lhs (gensym)))
|
||||
(let* ((g (if (not (consp lhs)) lhs (r-gensym)))
|
||||
(n (if (symbolp name)
|
||||
name ;(symbol->string name)
|
||||
name))
|
||||
|
@ -41,7 +46,7 @@
|
|||
(pattern-expand
|
||||
(pattern-lambda (-$ (<- (r-call f lhs ...) rhs)
|
||||
(<<- (r-call f lhs ...) rhs))
|
||||
(let ((g (if (consp rhs) (gensym) rhs))
|
||||
(let ((g (if (consp rhs) (r-gensym) rhs))
|
||||
(op (car __)))
|
||||
`(r-block ,@(if (consp rhs) `((ref= ,g ,rhs)) ())
|
||||
(,op ,lhs (r-call ,(symconcat f '<-) ,@(cddr (cadr __)) ,g))
|
||||
|
@ -77,9 +82,9 @@
|
|||
(let ((vars ()))
|
||||
(maptree-pre (lambda (s)
|
||||
(if (not (consp s)) s
|
||||
(cond ((eq (car s) 'lambda) nil)
|
||||
(cond ((eq (car s) 'lambda) ())
|
||||
((eq (car s) '<-)
|
||||
(setq vars (list-adjoin (cadr s) vars))
|
||||
(set! vars (list-adjoin (cadr s) vars))
|
||||
(cddr s))
|
||||
(T s))))
|
||||
n)
|
||||
|
@ -102,18 +107,3 @@
|
|||
(fancy-assignment-transform
|
||||
(dollarsign-transform
|
||||
(flatten-all-op && (flatten-all-op \|\| e)))))))
|
||||
|
||||
;(trace map)
|
||||
;(pretty-print (compile-ish *input*))
|
||||
;(print
|
||||
; (time-call (lambda () (compile-ish *input*)) 1)
|
||||
;)
|
||||
(define (main)
|
||||
(progn
|
||||
(define *input* (load "datetimeR.lsp"))
|
||||
;(define t0 ((java.util.Date:new):getTime))
|
||||
(time (compile-ish *input*))
|
||||
;(define t1 ((java.util.Date:new):getTime))
|
||||
))
|
||||
|
||||
(main)
|
||||
|
|
|
@ -81,21 +81,32 @@ value_t fl_intern(value_t *args, u_int32_t nargs)
|
|||
return symbol(cvalue_data(args[0]));
|
||||
}
|
||||
|
||||
value_t fl_setconstant(value_t *args, u_int32_t nargs)
|
||||
{
|
||||
argcount("set-constant!", nargs, 2);
|
||||
symbol_t *sym = tosymbol(args[0], "set-constant!");
|
||||
if (isconstant(args[0]) || sym->binding != UNBOUND)
|
||||
lerror(ArgError, "set-constant!: cannot redefine %s",
|
||||
symbol_name(args[0]));
|
||||
setc(args[0], args[1]);
|
||||
return args[1];
|
||||
}
|
||||
|
||||
extern value_t LAMBDA;
|
||||
|
||||
value_t fl_setsyntax(value_t *args, u_int32_t nargs)
|
||||
{
|
||||
argcount("set-syntax", nargs, 2);
|
||||
symbol_t *sym = tosymbol(args[0], "set-syntax");
|
||||
argcount("set-syntax!", nargs, 2);
|
||||
symbol_t *sym = tosymbol(args[0], "set-syntax!");
|
||||
if (sym->syntax && (sym->syntax == TAG_CONST || isspecial(sym->syntax)))
|
||||
lerror(ArgError, "set-syntax: cannot define syntax for %s",
|
||||
lerror(ArgError, "set-syntax!: cannot define syntax for %s",
|
||||
symbol_name(args[0]));
|
||||
if (args[1] == NIL) {
|
||||
if (args[1] == FL_F) {
|
||||
sym->syntax = 0;
|
||||
}
|
||||
else {
|
||||
if (!iscons(args[1]) || car_(args[1])!=LAMBDA)
|
||||
type_error("set-syntax", "function", args[1]);
|
||||
type_error("set-syntax!", "function", args[1]);
|
||||
sym->syntax = args[1];
|
||||
}
|
||||
return args[1];
|
||||
|
@ -109,7 +120,7 @@ value_t fl_symbolsyntax(value_t *args, u_int32_t nargs)
|
|||
// don't behave like functions (they take their arguments directly
|
||||
// from the form rather than from the stack of evaluated arguments)
|
||||
if (sym->syntax == TAG_CONST || isspecial(sym->syntax))
|
||||
return NIL;
|
||||
return FL_F;
|
||||
return sym->syntax;
|
||||
}
|
||||
|
||||
|
@ -160,15 +171,15 @@ extern value_t QUOTE;
|
|||
|
||||
value_t fl_constantp(value_t *args, u_int32_t nargs)
|
||||
{
|
||||
argcount("constantp", nargs, 1);
|
||||
argcount("constant?", nargs, 1);
|
||||
if (issymbol(args[0]))
|
||||
return (isconstant(args[0]) ? T : NIL);
|
||||
return (isconstant(args[0]) ? FL_T : FL_F);
|
||||
if (iscons(args[0])) {
|
||||
if (car_(args[0]) == QUOTE)
|
||||
return T;
|
||||
return NIL;
|
||||
return FL_T;
|
||||
return FL_F;
|
||||
}
|
||||
return T;
|
||||
return FL_T;
|
||||
}
|
||||
|
||||
value_t fl_fixnum(value_t *args, u_int32_t nargs)
|
||||
|
@ -278,7 +289,7 @@ value_t fl_path_cwd(value_t *args, uint32_t nargs)
|
|||
char *ptr = tostring(args[0], "path.cwd");
|
||||
if (set_cwd(ptr))
|
||||
lerror(IOError, "could not cd to %s", ptr);
|
||||
return T;
|
||||
return FL_T;
|
||||
}
|
||||
|
||||
value_t fl_os_getenv(value_t *args, uint32_t nargs)
|
||||
|
@ -286,7 +297,7 @@ value_t fl_os_getenv(value_t *args, uint32_t nargs)
|
|||
argcount("os.getenv", nargs, 1);
|
||||
char *name = tostring(args[0], "os.getenv");
|
||||
char *val = getenv(name);
|
||||
if (val == NULL) return NIL;
|
||||
if (val == NULL) return FL_F;
|
||||
if (*val == 0)
|
||||
return symbol_value(emptystringsym);
|
||||
return cvalue_static_cstring(val);
|
||||
|
@ -297,7 +308,7 @@ value_t fl_os_setenv(value_t *args, uint32_t nargs)
|
|||
argcount("os.setenv", nargs, 2);
|
||||
char *name = tostring(args[0], "os.setenv");
|
||||
int result;
|
||||
if (args[1] == NIL) {
|
||||
if (args[1] == FL_F) {
|
||||
result = unsetenv(name);
|
||||
}
|
||||
else {
|
||||
|
@ -306,7 +317,7 @@ value_t fl_os_setenv(value_t *args, uint32_t nargs)
|
|||
}
|
||||
if (result != 0)
|
||||
lerror(ArgError, "os.setenv: invalid environment variable");
|
||||
return T;
|
||||
return FL_T;
|
||||
}
|
||||
|
||||
value_t fl_rand(value_t *args, u_int32_t nargs)
|
||||
|
@ -351,11 +362,12 @@ extern void stringfuncs_init();
|
|||
extern void table_init();
|
||||
|
||||
static builtinspec_t builtin_info[] = {
|
||||
{ "set-syntax", fl_setsyntax },
|
||||
{ "set-constant!", fl_setconstant },
|
||||
{ "set-syntax!", fl_setsyntax },
|
||||
{ "symbol-syntax", fl_symbolsyntax },
|
||||
{ "syntax-environment", fl_syntax_env },
|
||||
{ "environment", fl_global_env },
|
||||
{ "constantp", fl_constantp },
|
||||
{ "constant?", fl_constantp },
|
||||
|
||||
{ "print", fl_print },
|
||||
{ "princ", fl_princ },
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
; -*- scheme -*-
|
||||
; uncomment for compatibility with CL
|
||||
;(defun mapp (f l) (mapcar f l))
|
||||
;(defmacro define (name &rest body)
|
||||
|
@ -18,7 +19,7 @@
|
|||
((equal key (caar dl)) (cdar dl))
|
||||
(T (dict-lookup (cdr dl) key))))
|
||||
|
||||
(define (dict-keys dl) (map (symbol-function 'car) dl))
|
||||
(define (dict-keys dl) (map car dl))
|
||||
|
||||
; graphs ----------------------------------------------------------------------
|
||||
(define (graph-empty) (dict-new))
|
||||
|
@ -50,14 +51,14 @@
|
|||
color-of-node
|
||||
(map
|
||||
(lambda (n)
|
||||
(let ((color-pair (assoc n coloring)))
|
||||
(if (consp color-pair) (cdr color-pair) nil)))
|
||||
(let ((color-pair (assq n coloring)))
|
||||
(if (consp color-pair) (cdr color-pair) ())))
|
||||
(graph-neighbors g node-to-color)))))
|
||||
|
||||
(define (try-each f lst)
|
||||
(if (null lst) nil
|
||||
(let ((ret (funcall f (car lst))))
|
||||
(if ret ret (try-each f (cdr lst))))))
|
||||
(if (null lst) #f
|
||||
(let ((ret (f (car lst))))
|
||||
(if ret ret (try-each f (cdr lst))))))
|
||||
|
||||
(define (color-node g coloring colors uncolored-nodes color)
|
||||
(cond
|
||||
|
@ -71,24 +72,24 @@
|
|||
|
||||
(define (color-graph g colors)
|
||||
(if (null colors)
|
||||
(null (graph-nodes g))
|
||||
(color-node g () colors (graph-nodes g) (car colors))))
|
||||
(and (null (graph-nodes g)) ())
|
||||
(color-node g () colors (graph-nodes g) (car colors))))
|
||||
|
||||
(define (color-pairs pairs colors)
|
||||
(color-graph (graph-from-edges pairs) colors))
|
||||
|
||||
; queens ----------------------------------------------------------------------
|
||||
(defun can-attack (x y)
|
||||
(define (can-attack x y)
|
||||
(let ((x1 (mod x 5))
|
||||
(y1 (truncate (/ x 5)))
|
||||
(x2 (mod y 5))
|
||||
(y2 (truncate (/ y 5))))
|
||||
(or (= x1 x2) (= y1 y2) (= (abs (- y2 y1)) (abs (- x2 x1))))))
|
||||
|
||||
(defun generate-5x5-pairs ()
|
||||
(let ((result nil))
|
||||
(define (generate-5x5-pairs)
|
||||
(let ((result ()))
|
||||
(dotimes (x 25)
|
||||
(dotimes (y 25)
|
||||
(if (and (/= x y) (can-attack x y))
|
||||
(setq result (cons (cons x y) result)) nil)))
|
||||
(set! result (cons (cons x y) result)) ())))
|
||||
result))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
; -*- scheme -*-
|
||||
(define (cond->if form)
|
||||
(cond-clauses->if (cdr form)))
|
||||
(define (cond-clauses->if lst)
|
||||
|
@ -8,30 +9,30 @@
|
|||
,(f-body (cdr clause))
|
||||
,(cond-clauses->if (cdr lst))))))
|
||||
|
||||
(define (progn->cps forms k)
|
||||
(define (begin->cps forms k)
|
||||
(cond ((atom forms) `(,k ,forms))
|
||||
((null (cdr forms)) (cps- (car forms) k))
|
||||
(T (let ((_ (gensym))) ; var to bind ignored value
|
||||
(cps- (car forms) `(lambda (,_)
|
||||
,(progn->cps (cdr forms) k)))))))
|
||||
,(begin->cps (cdr forms) k)))))))
|
||||
|
||||
(defmacro lambda/cc (args body)
|
||||
(define-macro (lambda/cc args body)
|
||||
`(rplaca (lambda ,args ,body) 'lambda/cc))
|
||||
|
||||
; a utility used at run time to dispatch a call with or without
|
||||
; the continuation argument, depending on the function
|
||||
(define (funcall/cc f k . args)
|
||||
(if (and (consp f) (eq (car f) 'lambda/cc))
|
||||
(if (and (pair? f) (eq (car f) 'lambda/cc))
|
||||
(apply f (cons k args))
|
||||
(k (apply f args))))
|
||||
(define *funcall/cc-names*
|
||||
(list-to-vector
|
||||
(map (lambda (i) (intern (string 'funcall/cc- i)))
|
||||
(iota 6))))
|
||||
(defmacro def-funcall/cc-n (args)
|
||||
(define-macro (def-funcall/cc-n args)
|
||||
(let* ((name (aref *funcall/cc-names* (length args))))
|
||||
`(define (,name f k ,@args)
|
||||
(if (and (consp f) (eq (car f) 'lambda/cc))
|
||||
(if (and (pair? f) (eq (car f) 'lambda/cc))
|
||||
(f k ,@args)
|
||||
(k (f ,@args))))))
|
||||
(def-funcall/cc-n ())
|
||||
|
@ -43,7 +44,7 @@
|
|||
|
||||
(define (rest->cps xformer form k argsyms)
|
||||
(let ((el (car form)))
|
||||
(if (or (atom el) (constantp el))
|
||||
(if (or (atom el) (constant? el))
|
||||
(xformer (cdr form) k (cons el argsyms))
|
||||
(let ((g (gensym)))
|
||||
(cps- el `(lambda (,g)
|
||||
|
@ -79,14 +80,14 @@
|
|||
(cps- (macroexpand form) *top-k*)))))
|
||||
(define (cps- form k)
|
||||
(let ((g (gensym)))
|
||||
(cond ((or (atom form) (constantp form))
|
||||
(cond ((or (atom form) (constant? form))
|
||||
`(,k ,form))
|
||||
|
||||
((eq (car form) 'lambda)
|
||||
`(,k (lambda/cc ,(cons g (cadr form)) ,(cps- (caddr form) g))))
|
||||
|
||||
((eq (car form) 'progn)
|
||||
(progn->cps (cdr form) k))
|
||||
((eq (car form) 'begin)
|
||||
(begin->cps (cdr form) k))
|
||||
|
||||
((eq (car form) 'cond)
|
||||
(cps- (cond->if form) k))
|
||||
|
@ -116,7 +117,7 @@
|
|||
,(cps- form g))))))
|
||||
|
||||
((eq (car form) 'or)
|
||||
(cond ((atom (cdr form)) `(,k ()))
|
||||
(cond ((atom (cdr form)) `(,k #f))
|
||||
((atom (cddr form)) (cps- (cadr form) k))
|
||||
(T
|
||||
(if (atom k)
|
||||
|
@ -132,18 +133,18 @@
|
|||
(body (caddr form))
|
||||
(lastval (gensym)))
|
||||
(cps- (macroexpand
|
||||
`(let ((,lastval nil))
|
||||
`(let ((,lastval #f))
|
||||
((label ,g (lambda ()
|
||||
(if ,test
|
||||
(progn (setq ,lastval ,body)
|
||||
(begin (set! ,lastval ,body)
|
||||
(,g))
|
||||
,lastval))))))
|
||||
k)))
|
||||
|
||||
((eq (car form) 'setq)
|
||||
((eq (car form) 'set!)
|
||||
(let ((var (cadr form))
|
||||
(E (caddr form)))
|
||||
(cps- E `(lambda (,g) (,k (setq ,var ,g))))))
|
||||
(cps- E `(lambda (,g) (,k (set! ,var ,g))))))
|
||||
|
||||
((eq (car form) 'reset)
|
||||
`(,k ,(cps- (cadr form) *top-k*)))
|
||||
|
@ -158,12 +159,12 @@
|
|||
((eq (car form) 'without-delimited-continuations)
|
||||
`(,k ,(cadr form)))
|
||||
|
||||
((and (constantp (car form))
|
||||
(builtinp (eval (car form))))
|
||||
((and (constant? (car form))
|
||||
(builtin? (eval (car form))))
|
||||
(builtincall->cps form k))
|
||||
|
||||
; ((lambda (...) body) ...)
|
||||
((and (consp (car form))
|
||||
((and (pair? (car form))
|
||||
(eq (caar form) 'lambda))
|
||||
(let ((largs (cadr (car form)))
|
||||
(lbody (caddr (car form))))
|
||||
|
@ -183,13 +184,13 @@
|
|||
; (lambda (args...) (f args...)) => f
|
||||
; but only for constant, builtin f
|
||||
(define (η-reduce form)
|
||||
(cond ((or (atom form) (constantp form)) form)
|
||||
(cond ((or (atom form) (constant? form)) form)
|
||||
((and (eq (car form) 'lambda)
|
||||
(let ((body (caddr form))
|
||||
(args (cadr form)))
|
||||
(and (consp body)
|
||||
(and (pair? body)
|
||||
(equal (cdr body) args)
|
||||
(constantp (car (caddr form))))))
|
||||
(constant? (car (caddr form))))))
|
||||
(car (caddr form)))
|
||||
(T (map η-reduce form))))
|
||||
|
||||
|
@ -198,18 +199,18 @@
|
|||
(any (lambda (p) (contains x p)) form)))
|
||||
|
||||
(define (β-reduce form)
|
||||
(if (or (atom form) (constantp form))
|
||||
(if (or (atom form) (constant? form))
|
||||
form
|
||||
(β-reduce- (map β-reduce form))))
|
||||
|
||||
(define (β-reduce- form)
|
||||
; ((lambda (f) (f arg)) X) => (X arg)
|
||||
(cond ((and (= (length form) 2)
|
||||
(consp (car form))
|
||||
(pair? (car form))
|
||||
(eq (caar form) 'lambda)
|
||||
(let ((args (cadr (car form)))
|
||||
(body (caddr (car form))))
|
||||
(and (consp body) (consp args)
|
||||
(and (pair? body) (pair? args)
|
||||
(= (length body) 2)
|
||||
(= (length args) 1)
|
||||
(eq (car body) (car args))
|
||||
|
@ -227,15 +228,15 @@
|
|||
; ((lambda (p1 args...) body) s exprs...)
|
||||
; where exprs... doesn't contain p1
|
||||
((and (= (length form) 2)
|
||||
(consp (car form))
|
||||
(pair? (car form))
|
||||
(eq (caar form) 'lambda)
|
||||
(or (atom (cadr form)) (constantp (cadr form)))
|
||||
(or (atom (cadr form)) (constant? (cadr form)))
|
||||
(let ((args (cadr (car form)))
|
||||
(s (cadr form))
|
||||
(body (caddr (car form))))
|
||||
(and (consp args) (= (length args) 1)
|
||||
(consp body)
|
||||
(consp (car body))
|
||||
(and (pair? args) (= (length args) 1)
|
||||
(pair? body)
|
||||
(pair? (car body))
|
||||
(eq (caar body) 'lambda)
|
||||
(let ((innerargs (cadr (car body)))
|
||||
(innerbody (caddr (car body)))
|
||||
|
@ -248,14 +249,17 @@
|
|||
|
||||
(T form)))
|
||||
|
||||
(defmacro with-delimited-continuations code (cps (f-body code)))
|
||||
(define-macro (with-delimited-continuations . code)
|
||||
(cps (f-body code)))
|
||||
|
||||
(defmacro defgenerator (name args . body)
|
||||
(define-macro (define-generator form . body)
|
||||
(let ((ko (gensym))
|
||||
(cur (gensym)))
|
||||
`(defun ,name ,args
|
||||
(let ((,ko ())
|
||||
(,cur ()))
|
||||
(cur (gensym))
|
||||
(name (car form))
|
||||
(args (cdr form)))
|
||||
`(define (,name ,@args)
|
||||
(let ((,ko #f)
|
||||
(,cur #f))
|
||||
(lambda ()
|
||||
(with-delimited-continuations
|
||||
(if ,ko (,ko ,cur)
|
||||
|
@ -263,17 +267,17 @@
|
|||
(let ((yield
|
||||
(lambda (v)
|
||||
(shift yk
|
||||
(progn (setq ,ko yk)
|
||||
(setq ,cur v))))))
|
||||
(begin (set! ,ko yk)
|
||||
(set! ,cur v))))))
|
||||
,(f-body body))))))))))
|
||||
|
||||
; a test case
|
||||
(defgenerator range-iterator (lo hi)
|
||||
(define-generator (range-iterator lo hi)
|
||||
((label loop
|
||||
(lambda (i)
|
||||
(if (< hi i)
|
||||
'done
|
||||
(progn (yield i)
|
||||
(begin (yield i)
|
||||
(loop (+ 1 i))))))
|
||||
lo))
|
||||
|
||||
|
@ -301,15 +305,15 @@ todo:
|
|||
|
||||
(let ((x 0))
|
||||
(while (< x 10)
|
||||
(progn (print x) (setq x (+ 1 x)))))
|
||||
(begin (print x) (set! x (+ 1 x)))))
|
||||
=>
|
||||
(let ((x 0))
|
||||
(reset
|
||||
(let ((l nil))
|
||||
(let ((l #f))
|
||||
(let ((k (shift k (k k))))
|
||||
(if (< x 10)
|
||||
(progn (setq l (progn (print x)
|
||||
(setq x (+ 1 x))))
|
||||
(begin (set! l (begin (print x)
|
||||
(set! x (+ 1 x))))
|
||||
(k k))
|
||||
l)))))
|
||||
|#
|
||||
|
|
|
@ -617,7 +617,12 @@ value_t cvalue_typeof(value_t *args, u_int32_t nargs)
|
|||
case TAG_NUM: return fixnumsym;
|
||||
case TAG_SYM: return symbolsym;
|
||||
case TAG_VECTOR: return vectorsym;
|
||||
case TAG_BUILTIN: return builtinsym;
|
||||
case TAG_BUILTIN:
|
||||
if (args[0] == FL_T || args[0] == FL_F)
|
||||
return booleansym;
|
||||
if (args[0] == NIL)
|
||||
return nullsym;
|
||||
return builtinsym;
|
||||
}
|
||||
return cv_type((cvalue_t*)ptr(args[0]));
|
||||
}
|
||||
|
|
|
@ -256,8 +256,8 @@ value_t compare(value_t a, value_t b)
|
|||
value_t equal(value_t a, value_t b)
|
||||
{
|
||||
if (eq_comparable(a, b))
|
||||
return (a == b) ? T : NIL;
|
||||
return (numval(compare_(a,b,1))==0 ? T : NIL);
|
||||
return (a == b) ? FL_T : FL_F;
|
||||
return (numval(compare_(a,b,1))==0 ? FL_T : FL_F);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* cvalues system providing C data types and a C FFI
|
||||
* constructor notation for nicely printing arbitrary values
|
||||
* strings
|
||||
- hash tables
|
||||
* hash tables
|
||||
|
||||
by Jeff Bezanson (C) 2009
|
||||
Distributed under the BSD License
|
||||
|
@ -52,27 +52,28 @@
|
|||
|
||||
static char *builtin_names[] =
|
||||
{ "quote", "cond", "if", "and", "or", "while", "lambda",
|
||||
"trycatch", "%apply", "setq", "progn",
|
||||
"trycatch", "%apply", "set!", "begin",
|
||||
|
||||
"eq", "atom", "not", "symbolp", "numberp", "boundp", "consp",
|
||||
"builtinp", "vectorp", "fixnump", "equal",
|
||||
"cons", "list", "car", "cdr", "rplaca", "rplacd",
|
||||
"eq?", "eqv?", "equal?", "atom?", "not", "null?", "boolean?", "symbol?",
|
||||
"number?", "bound?", "pair?", "builtin?", "vector?", "fixnum?",
|
||||
|
||||
"cons", "list", "car", "cdr", "set-car!", "set-cdr!",
|
||||
"eval", "eval*", "apply", "prog1", "raise",
|
||||
"+", "-", "*", "/", "<", "~", "&", "!", "$",
|
||||
"vector", "aref", "aset", "length", "assoc", "compare",
|
||||
"for" };
|
||||
"vector", "aref", "aset", "length", "assq", "compare", "for",
|
||||
"", "", "" };
|
||||
|
||||
#define N_STACK 98304
|
||||
value_t Stack[N_STACK];
|
||||
uint32_t SP = 0;
|
||||
|
||||
value_t NIL, T, LAMBDA, QUOTE, IF, TRYCATCH;
|
||||
value_t NIL, FL_T, FL_F, LAMBDA, QUOTE, IF, TRYCATCH;
|
||||
value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT;
|
||||
value_t IOError, ParseError, TypeError, ArgError, UnboundError, MemoryError;
|
||||
value_t DivideError, BoundsError, Error, KeyError;
|
||||
value_t conssym, symbolsym, fixnumsym, vectorsym, builtinsym;
|
||||
value_t defunsym, defmacrosym, forsym, labelsym, printprettysym, setqsym;
|
||||
value_t printwidthsym;
|
||||
value_t definesym, defmacrosym, forsym, labelsym, printprettysym, setqsym;
|
||||
value_t printwidthsym, tsym, Tsym, fsym, Fsym, booleansym, nullsym, elsesym;
|
||||
|
||||
static value_t eval_sexpr(value_t e, uint32_t penv, int tail);
|
||||
static value_t *alloc_words(int n);
|
||||
|
@ -592,7 +593,7 @@ int isnumber(value_t v)
|
|||
// eval -----------------------------------------------------------------------
|
||||
|
||||
// return a cons element of v whose car is item
|
||||
static value_t assoc(value_t item, value_t v)
|
||||
static value_t assq(value_t item, value_t v)
|
||||
{
|
||||
value_t bind;
|
||||
|
||||
|
@ -602,7 +603,7 @@ static value_t assoc(value_t item, value_t v)
|
|||
return bind;
|
||||
v = cdr_(v);
|
||||
}
|
||||
return NIL;
|
||||
return FL_F;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -646,7 +647,7 @@ static value_t do_trycatch(value_t expr, uint32_t penv)
|
|||
FL_CATCH {
|
||||
v = cdr_(Stack[SP-1]);
|
||||
if (!iscons(v)) {
|
||||
v = NIL; // 1-argument form
|
||||
v = FL_F; // 1-argument form
|
||||
}
|
||||
else {
|
||||
Stack[SP-1] = car_(v);
|
||||
|
@ -771,7 +772,7 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
if (*pv == NIL) break;
|
||||
pv = &vector_elt(*pv, 0);
|
||||
}
|
||||
sym = tosymbol(e, "setq");
|
||||
sym = tosymbol(e, "set!");
|
||||
if (sym->syntax != TAG_CONST)
|
||||
sym->binding = v;
|
||||
break;
|
||||
|
@ -809,24 +810,28 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
case F_IF:
|
||||
if (!iscons(Stack[saveSP])) goto notpair;
|
||||
v = car_(Stack[saveSP]);
|
||||
if (eval(v) != NIL) {
|
||||
if (eval(v) != FL_F) {
|
||||
v = cdr_(Stack[saveSP]);
|
||||
if (!iscons(v)) goto notpair;
|
||||
v = car_(v);
|
||||
}
|
||||
else {
|
||||
v = cdr_(Stack[saveSP]);
|
||||
if (!iscons(v) || !iscons(v=cdr_(v))) goto notpair;
|
||||
v = car_(v);
|
||||
if (!iscons(v)) goto notpair;
|
||||
if (!iscons(v=cdr_(v))) v = FL_F; // allow 2-arg form
|
||||
else v = car_(v);
|
||||
}
|
||||
tail_eval(v);
|
||||
break;
|
||||
case F_COND:
|
||||
pv = &Stack[saveSP]; v = NIL;
|
||||
pv = &Stack[saveSP]; v = FL_F;
|
||||
while (iscons(*pv)) {
|
||||
c = tocons(car_(*pv), "cond");
|
||||
v = eval(c->car);
|
||||
if (v != NIL) {
|
||||
v = c->car;
|
||||
// allow last condition to be 'else'
|
||||
if (iscons(cdr_(*pv)) || v != elsesym)
|
||||
v = eval(v);
|
||||
if (v != FL_F) {
|
||||
*pv = cdr_(car_(*pv));
|
||||
// evaluate body forms
|
||||
if (iscons(*pv)) {
|
||||
|
@ -842,11 +847,11 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
}
|
||||
break;
|
||||
case F_AND:
|
||||
pv = &Stack[saveSP]; v = T;
|
||||
pv = &Stack[saveSP]; v = FL_T;
|
||||
if (iscons(*pv)) {
|
||||
while (iscons(cdr_(*pv))) {
|
||||
if ((v=eval(car_(*pv))) == NIL) {
|
||||
SP = saveSP; return NIL;
|
||||
if ((v=eval(car_(*pv))) == FL_F) {
|
||||
SP = saveSP; return FL_F;
|
||||
}
|
||||
*pv = cdr_(*pv);
|
||||
}
|
||||
|
@ -854,10 +859,10 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
}
|
||||
break;
|
||||
case F_OR:
|
||||
pv = &Stack[saveSP]; v = NIL;
|
||||
pv = &Stack[saveSP]; v = FL_F;
|
||||
if (iscons(*pv)) {
|
||||
while (iscons(cdr_(*pv))) {
|
||||
if ((v=eval(car_(*pv))) != NIL) {
|
||||
if ((v=eval(car_(*pv))) != FL_F) {
|
||||
SP = saveSP; return v;
|
||||
}
|
||||
*pv = cdr_(*pv);
|
||||
|
@ -871,9 +876,9 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
PUSH(*body);
|
||||
Stack[saveSP] = car_(Stack[saveSP]);
|
||||
value_t *cond = &Stack[saveSP];
|
||||
PUSH(NIL);
|
||||
PUSH(FL_F);
|
||||
pv = &Stack[SP-1];
|
||||
while (eval(*cond) != NIL) {
|
||||
while (eval(*cond) != FL_F) {
|
||||
*body = Stack[SP-2];
|
||||
while (iscons(*body)) {
|
||||
*pv = eval(car_(*body));
|
||||
|
@ -892,7 +897,7 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
}
|
||||
tail_eval(car_(*pv));
|
||||
}
|
||||
v = NIL;
|
||||
v = FL_F;
|
||||
break;
|
||||
case F_TRYCATCH:
|
||||
v = do_trycatch(car(Stack[saveSP]), penv);
|
||||
|
@ -900,13 +905,13 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
|
||||
// ordinary functions
|
||||
case F_BOUNDP:
|
||||
argcount("boundp", nargs, 1);
|
||||
sym = tosymbol(Stack[SP-1], "boundp");
|
||||
v = (sym->binding == UNBOUND) ? NIL : T;
|
||||
argcount("bound?", nargs, 1);
|
||||
sym = tosymbol(Stack[SP-1], "bound?");
|
||||
v = (sym->binding == UNBOUND) ? FL_F : FL_T;
|
||||
break;
|
||||
case F_EQ:
|
||||
argcount("eq", nargs, 2);
|
||||
v = ((Stack[SP-2] == Stack[SP-1]) ? T : NIL);
|
||||
argcount("eq?", nargs, 2);
|
||||
v = ((Stack[SP-2] == Stack[SP-1]) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_CONS:
|
||||
argcount("cons", nargs, 2);
|
||||
|
@ -937,12 +942,12 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
if (!iscons(v)) goto notpair;
|
||||
v = cdr_(v);
|
||||
break;
|
||||
case F_RPLACA:
|
||||
argcount("rplaca", nargs, 2);
|
||||
case F_SETCAR:
|
||||
argcount("set-car!", nargs, 2);
|
||||
car(v=Stack[SP-2]) = Stack[SP-1];
|
||||
break;
|
||||
case F_RPLACD:
|
||||
argcount("rplacd", nargs, 2);
|
||||
case F_SETCDR:
|
||||
argcount("set-cdr!", nargs, 2);
|
||||
cdr(v=Stack[SP-2]) = Stack[SP-1];
|
||||
break;
|
||||
case F_VECTOR:
|
||||
|
@ -1015,36 +1020,47 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
}
|
||||
break;
|
||||
case F_ATOM:
|
||||
argcount("atom", nargs, 1);
|
||||
v = ((!iscons(Stack[SP-1])) ? T : NIL);
|
||||
argcount("atom?", nargs, 1);
|
||||
v = ((!iscons(Stack[SP-1])) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_CONSP:
|
||||
argcount("consp", nargs, 1);
|
||||
v = (iscons(Stack[SP-1]) ? T : NIL);
|
||||
argcount("pair?", nargs, 1);
|
||||
v = (iscons(Stack[SP-1]) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_SYMBOLP:
|
||||
argcount("symbolp", nargs, 1);
|
||||
v = ((issymbol(Stack[SP-1])) ? T : NIL);
|
||||
argcount("symbol?", nargs, 1);
|
||||
v = ((issymbol(Stack[SP-1])) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_NUMBERP:
|
||||
argcount("numberp", nargs, 1);
|
||||
v = (isfixnum(Stack[SP-1]) || iscprim(Stack[SP-1]) ? T : NIL);
|
||||
argcount("number?", nargs, 1);
|
||||
v = (isfixnum(Stack[SP-1]) || iscprim(Stack[SP-1]) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_FIXNUMP:
|
||||
argcount("fixnump", nargs, 1);
|
||||
v = (isfixnum(Stack[SP-1]) ? T : NIL);
|
||||
argcount("fixnum?", nargs, 1);
|
||||
v = (isfixnum(Stack[SP-1]) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_BUILTINP:
|
||||
argcount("builtinp", nargs, 1);
|
||||
v = (isbuiltinish(Stack[SP-1]) ? T : NIL);
|
||||
argcount("builtin?", nargs, 1);
|
||||
v = Stack[SP-1];
|
||||
v = ((isbuiltinish(v) && v!=FL_F && v!=FL_T && v!=NIL)
|
||||
? FL_T : FL_F);
|
||||
break;
|
||||
case F_VECTORP:
|
||||
argcount("vectorp", nargs, 1);
|
||||
v = ((isvector(Stack[SP-1])) ? T : NIL);
|
||||
argcount("vector?", nargs, 1);
|
||||
v = ((isvector(Stack[SP-1])) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_NOT:
|
||||
argcount("not", nargs, 1);
|
||||
v = ((Stack[SP-1] == NIL) ? T : NIL);
|
||||
v = ((Stack[SP-1] == FL_F) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_NULL:
|
||||
argcount("null?", nargs, 1);
|
||||
v = ((Stack[SP-1] == NIL) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_BOOLEANP:
|
||||
argcount("boolean?", nargs, 1);
|
||||
v = Stack[SP-1];
|
||||
v = ((v == FL_T || v == FL_F) ? FL_T : FL_F);
|
||||
break;
|
||||
case F_ADD:
|
||||
s = 0;
|
||||
|
@ -1157,19 +1173,37 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
case F_LT:
|
||||
argcount("<", nargs, 2);
|
||||
if (bothfixnums(Stack[SP-2], Stack[SP-1])) {
|
||||
v = (numval(Stack[SP-2]) < numval(Stack[SP-1])) ? T : NIL;
|
||||
v = (numval(Stack[SP-2]) < numval(Stack[SP-1])) ? FL_T : FL_F;
|
||||
}
|
||||
else {
|
||||
v = (numval(compare(Stack[SP-2], Stack[SP-1])) < 0) ? T : NIL;
|
||||
v = (numval(compare(Stack[SP-2], Stack[SP-1])) < 0) ?
|
||||
FL_T : FL_F;
|
||||
}
|
||||
break;
|
||||
case F_EQUAL:
|
||||
argcount("equal", nargs, 2);
|
||||
if (eq_comparable(Stack[SP-2],Stack[SP-1])) {
|
||||
v = (Stack[SP-2] == Stack[SP-1]) ? T : NIL;
|
||||
argcount("equal?", nargs, 2);
|
||||
if (Stack[SP-2] == Stack[SP-1]) {
|
||||
v = FL_T;
|
||||
}
|
||||
else if (eq_comparable(Stack[SP-2],Stack[SP-1])) {
|
||||
v = FL_F;
|
||||
}
|
||||
else {
|
||||
v = (numval(compare(Stack[SP-2], Stack[SP-1]))==0) ? T : NIL;
|
||||
v = (numval(compare(Stack[SP-2], Stack[SP-1]))==0) ?
|
||||
FL_T : FL_F;
|
||||
}
|
||||
break;
|
||||
case F_EQV:
|
||||
argcount("eqv?", nargs, 2);
|
||||
if (Stack[SP-2] == Stack[SP-1]) {
|
||||
v = FL_T;
|
||||
}
|
||||
else if (!leafp(Stack[SP-2]) || !leafp(Stack[SP-1])) {
|
||||
v = FL_F;
|
||||
}
|
||||
else {
|
||||
v = (numval(compare(Stack[SP-2], Stack[SP-1]))==0) ?
|
||||
FL_T : FL_F;
|
||||
}
|
||||
break;
|
||||
case F_EVAL:
|
||||
|
@ -1207,9 +1241,9 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
lerror(ArgError, "prog1: too few arguments");
|
||||
v = Stack[saveSP+1];
|
||||
break;
|
||||
case F_ASSOC:
|
||||
argcount("assoc", nargs, 2);
|
||||
v = assoc(Stack[SP-2], Stack[SP-1]);
|
||||
case F_ASSQ:
|
||||
argcount("assq", nargs, 2);
|
||||
v = assq(Stack[SP-2], Stack[SP-1]);
|
||||
break;
|
||||
case F_FOR:
|
||||
argcount("for", nargs, 3);
|
||||
|
@ -1224,7 +1258,7 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
SP += 4; // make space
|
||||
Stack[SP-4] = fixnum(3); // env size
|
||||
Stack[SP-1] = cdr_(cdr_(f)); // cloenv
|
||||
v = NIL;
|
||||
v = FL_F;
|
||||
for(s=lo; s <= hi; s++) {
|
||||
f = Stack[SP-5];
|
||||
Stack[SP-3] = car_(f); // lambda list
|
||||
|
@ -1256,6 +1290,10 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
}
|
||||
noeval = 1;
|
||||
goto apply_lambda;
|
||||
case F_TRUE:
|
||||
case F_FALSE:
|
||||
case F_NIL:
|
||||
goto apply_type_error;
|
||||
default:
|
||||
// function pointer tagged as a builtin
|
||||
v = ((builtin_t)ptr(f))(&Stack[saveSP+1], nargs);
|
||||
|
@ -1358,6 +1396,7 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
}
|
||||
// not reached
|
||||
}
|
||||
apply_type_error:
|
||||
type_error("apply", "function", f);
|
||||
notpair:
|
||||
lerror(TypeError, "expected cons");
|
||||
|
@ -1369,7 +1408,7 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
extern void builtins_init();
|
||||
extern void comparehash_init();
|
||||
|
||||
static char *EXEDIR;
|
||||
static char *EXEDIR = NULL;
|
||||
|
||||
void assign_global_builtins(builtinspec_t *b)
|
||||
{
|
||||
|
@ -1393,8 +1432,9 @@ void lisp_init(void)
|
|||
htable_new(&printconses, 32);
|
||||
comparehash_init();
|
||||
|
||||
NIL = symbol("nil"); setc(NIL, NIL);
|
||||
T = symbol("T"); setc(T, T);
|
||||
NIL = builtin(F_NIL);
|
||||
FL_T = builtin(F_TRUE);
|
||||
FL_F = builtin(F_FALSE);
|
||||
LAMBDA = symbol("lambda");
|
||||
QUOTE = symbol("quote");
|
||||
TRYCATCH = symbol("trycatch");
|
||||
|
@ -1417,12 +1457,17 @@ void lisp_init(void)
|
|||
fixnumsym = symbol("fixnum");
|
||||
vectorsym = symbol("vector");
|
||||
builtinsym = symbol("builtin");
|
||||
defunsym = symbol("defun");
|
||||
defmacrosym = symbol("defmacro");
|
||||
booleansym = symbol("boolean");
|
||||
nullsym = symbol("null");
|
||||
definesym = symbol("define");
|
||||
defmacrosym = symbol("define-macro");
|
||||
forsym = symbol("for");
|
||||
labelsym = symbol("label");
|
||||
setqsym = symbol("setq");
|
||||
set(printprettysym=symbol("*print-pretty*"), T);
|
||||
setqsym = symbol("set!");
|
||||
elsesym = symbol("else");
|
||||
tsym = symbol("t"); Tsym = symbol("T");
|
||||
fsym = symbol("f"); Fsym = symbol("F");
|
||||
set(printprettysym=symbol("*print-pretty*"), FL_T);
|
||||
set(printwidthsym=symbol("*print-width*"), fixnum(SCR_WIDTH));
|
||||
lasterror = NIL;
|
||||
lerrorbuf[0] = '\0';
|
||||
|
@ -1433,7 +1478,7 @@ void lisp_init(void)
|
|||
((symbol_t*)ptr(symbol(builtin_names[i])))->syntax = builtin(i);
|
||||
i++;
|
||||
}
|
||||
for (; i < N_BUILTINS; i++) {
|
||||
for (; i < F_TRUE; i++) {
|
||||
setc(symbol(builtin_names[i]), builtin(i));
|
||||
}
|
||||
|
||||
|
@ -1559,6 +1604,7 @@ int locale_is_utf8;
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
value_t v;
|
||||
char fname_buf[1024];
|
||||
|
||||
locale_is_utf8 = u8_is_locale_utf8(setlocale(LC_ALL, ""));
|
||||
|
||||
|
@ -1575,7 +1621,13 @@ int main(int argc, char *argv[])
|
|||
if (argc > 1) return 1;
|
||||
else goto repl;
|
||||
}
|
||||
load_file("system.lsp");
|
||||
fname_buf[0] = '\0';
|
||||
if (EXEDIR != NULL) {
|
||||
strcat(fname_buf, EXEDIR);
|
||||
strcat(fname_buf, PATHSEPSTRING);
|
||||
}
|
||||
strcat(fname_buf, "system.lsp");
|
||||
load_file(fname_buf);
|
||||
if (argc > 1) { load_file(argv[1]); return 0; }
|
||||
printf("; _ \n");
|
||||
printf("; |_ _ _ |_ _ | . _ _\n");
|
||||
|
|
|
@ -103,18 +103,21 @@ enum {
|
|||
// special forms
|
||||
F_QUOTE=0, F_COND, F_IF, F_AND, F_OR, F_WHILE, F_LAMBDA,
|
||||
F_TRYCATCH, F_SPECIAL_APPLY, F_SETQ, F_PROGN,
|
||||
|
||||
// functions
|
||||
F_EQ, F_ATOM, F_NOT, F_SYMBOLP, F_NUMBERP, F_BOUNDP, F_CONSP,
|
||||
F_BUILTINP, F_VECTORP, F_FIXNUMP, F_EQUAL,
|
||||
F_CONS, F_LIST, F_CAR, F_CDR, F_RPLACA, F_RPLACD,
|
||||
F_EQ, F_EQV, F_EQUAL, F_ATOM, F_NOT, F_NULL, F_BOOLEANP, F_SYMBOLP,
|
||||
F_NUMBERP, F_BOUNDP, F_CONSP, F_BUILTINP, F_VECTORP, F_FIXNUMP,
|
||||
|
||||
F_CONS, F_LIST, F_CAR, F_CDR, F_SETCAR, F_SETCDR,
|
||||
F_EVAL, F_EVALSTAR, F_APPLY, F_PROG1, F_RAISE,
|
||||
F_ADD, F_SUB, F_MUL, F_DIV, F_LT, F_BNOT, F_BAND, F_BOR, F_BXOR,
|
||||
F_VECTOR, F_AREF, F_ASET, F_LENGTH, F_ASSOC, F_COMPARE, F_FOR,
|
||||
N_BUILTINS
|
||||
F_VECTOR, F_AREF, F_ASET, F_LENGTH, F_ASSQ, F_COMPARE, F_FOR,
|
||||
F_TRUE, F_FALSE, F_NIL,
|
||||
N_BUILTINS,
|
||||
};
|
||||
#define isspecial(v) (uintval(v) <= (unsigned int)F_PROGN)
|
||||
|
||||
extern value_t NIL, T;
|
||||
extern value_t NIL, FL_T, FL_F;
|
||||
|
||||
/* read, eval, print main entry points */
|
||||
value_t read_sexpr(ios_t *f);
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include "llt.h"
|
||||
#include "flisp.h"
|
||||
|
||||
// global replace TYPE with your type name to make your very own type!
|
||||
|
||||
static value_t TYPEsym;
|
||||
static fltype_t *TYPEtype;
|
||||
|
||||
void print_TYPE(value_t v, ios_t *f, int princ)
|
||||
{
|
||||
}
|
||||
|
||||
void print_traverse_TYPE(value_t self)
|
||||
{
|
||||
}
|
||||
|
||||
void free_TYPE(value_t self)
|
||||
{
|
||||
}
|
||||
|
||||
void relocate_TYPE(value_t oldv, value_t newv)
|
||||
{
|
||||
}
|
||||
|
||||
cvtable_t TYPE_vtable = { print_TYPE, relocate_TYPE, free_TYPE,
|
||||
print_traverse_TYPE };
|
||||
|
||||
int isTYPE(value_t v)
|
||||
{
|
||||
return iscvalue(v) && cv_class((cvalue_t*)ptr(v)) == TYPEtype;
|
||||
}
|
||||
|
||||
value_t fl_TYPEp(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("TYPE?", nargs, 1);
|
||||
return isTYPE(args[0]) ? FL_T : FL_F;
|
||||
}
|
||||
|
||||
static TYPE_t *toTYPE(value_t v, char *fname)
|
||||
{
|
||||
if (!isTYPE(v))
|
||||
type_error(fname, "TYPE", v);
|
||||
return (TYPE_t*)cv_data((cvalue_t*)ptr(v));
|
||||
}
|
||||
|
||||
static builtinspec_t TYPEfunc_info[] = {
|
||||
{ "TYPE?", fl_TYPEp },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void TYPE_init()
|
||||
{
|
||||
TYPEsym = symbol("TYPE");
|
||||
TYPEtype = define_opaque_type(TYPEsym, sizeof(TYPE_t),
|
||||
&TYPE_vtable, NULL);
|
||||
assign_global_builtins(TYPEfunc_info);
|
||||
}
|
|
@ -9,17 +9,20 @@
|
|||
(assert (equal (time (yfib 32)) 2178309))
|
||||
|
||||
(princ "sort: ")
|
||||
(setq r (map-int (lambda (x) (mod (+ (* x 9421) 12345) 1024)) 1000))
|
||||
(set! r (map-int (lambda (x) (mod (+ (* x 9421) 12345) 1024)) 1000))
|
||||
(time (sort r))
|
||||
|
||||
(princ "mexpand: ")
|
||||
(time (dotimes (n 5000) (macroexpand '(dotimes (i 100) body1 body2))))
|
||||
|
||||
(princ "append: ")
|
||||
(setq L (map-int (lambda (x) (map-int identity 20)) 20))
|
||||
(set! L (map-int (lambda (x) (map-int identity 20)) 20))
|
||||
(time (dotimes (n 1000) (apply append L)))
|
||||
|
||||
(path.cwd "ast")
|
||||
(princ "p-lambda: ")
|
||||
(load "rpasses.lsp")
|
||||
(define *input* (load "datetimeR.lsp"))
|
||||
(time (set! *output* (compile-ish *input*)))
|
||||
(assert (equal *output* (load "rpasses-out.lsp")))
|
||||
(path.cwd "..")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(defun pisum ()
|
||||
(define (pisum)
|
||||
(dotimes (j 500)
|
||||
((label sumloop
|
||||
(lambda (i sum)
|
||||
|
|
|
@ -169,7 +169,7 @@ static int smallp(value_t v)
|
|||
static int specialindent(value_t head)
|
||||
{
|
||||
// indent these forms 2 spaces, not lined up with the first argument
|
||||
if (head == LAMBDA || head == TRYCATCH || head == defunsym ||
|
||||
if (head == LAMBDA || head == TRYCATCH || head == definesym ||
|
||||
head == defmacrosym || head == forsym || head == labelsym)
|
||||
return 2;
|
||||
return -1;
|
||||
|
@ -200,7 +200,13 @@ static int allsmallp(value_t v)
|
|||
static int indentafter3(value_t head, value_t v)
|
||||
{
|
||||
// for certain X always indent (X a b c) after b
|
||||
return ((head == defunsym || head == defmacrosym || head == forsym) &&
|
||||
return ((head == forsym) && !allsmallp(cdr_(v)));
|
||||
}
|
||||
|
||||
static int indentafter2(value_t head, value_t v)
|
||||
{
|
||||
// for certain X always indent (X a b) after a
|
||||
return ((head == definesym || head == defmacrosym) &&
|
||||
!allsmallp(cdr_(v)));
|
||||
}
|
||||
|
||||
|
@ -251,6 +257,7 @@ static void print_pair(ios_t *f, value_t v, int princ)
|
|||
if (!blk) always = indentevery(v);
|
||||
value_t head = car_(v);
|
||||
int after3 = indentafter3(head, v);
|
||||
int after2 = indentafter2(head, v);
|
||||
int n_unindented = 1;
|
||||
while (1) {
|
||||
lastv = VPOS;
|
||||
|
@ -287,6 +294,7 @@ static void print_pair(ios_t *f, value_t v, int princ)
|
|||
(n > 0 && always) ||
|
||||
|
||||
(n == 2 && after3) ||
|
||||
(n == 1 && after2) ||
|
||||
|
||||
(n_unindented >= 3 && !nextsmall) ||
|
||||
|
||||
|
@ -328,8 +336,6 @@ void fl_print_child(ios_t *f, value_t v, int princ)
|
|||
name = symbol_name(v);
|
||||
if (princ)
|
||||
outs(name, f);
|
||||
else if (v == NIL)
|
||||
outs("()", f);
|
||||
else if (ismanaged(v)) {
|
||||
outs("#:", f);
|
||||
outs(name, f);
|
||||
|
@ -338,6 +344,18 @@ void fl_print_child(ios_t *f, value_t v, int princ)
|
|||
print_symbol_name(f, name);
|
||||
break;
|
||||
case TAG_BUILTIN:
|
||||
if (v == FL_T) {
|
||||
outs("#t", f);
|
||||
break;
|
||||
}
|
||||
if (v == FL_F) {
|
||||
outs("#f", f);
|
||||
break;
|
||||
}
|
||||
if (v == NIL) {
|
||||
outs("()", f);
|
||||
break;
|
||||
}
|
||||
if (isbuiltin(v)) {
|
||||
outs("#.", f);
|
||||
outs(builtin_names[uintval(v)], f);
|
||||
|
@ -624,7 +642,7 @@ static void set_print_width()
|
|||
|
||||
void print(ios_t *f, value_t v, int princ)
|
||||
{
|
||||
print_pretty = (symbol_value(printprettysym) != NIL);
|
||||
print_pretty = (symbol_value(printprettysym) != FL_F);
|
||||
if (print_pretty)
|
||||
set_print_width();
|
||||
printlabel = 0;
|
||||
|
|
|
@ -270,12 +270,6 @@ static u_int32_t peek(ios_t *f)
|
|||
read_token(f, ch, 0);
|
||||
toktype = TOK_SHARPSYM;
|
||||
tokval = symbol(buf);
|
||||
c = nextchar(f);
|
||||
if (c != '(') {
|
||||
take();
|
||||
lerror(ParseError, "read: expected argument list for %s",
|
||||
symbol_name(tokval));
|
||||
}
|
||||
}
|
||||
else {
|
||||
lerror(ParseError, "read: unknown read macro");
|
||||
|
@ -465,6 +459,7 @@ static value_t do_read_sexpr(ios_t *f, value_t label)
|
|||
value_t v, sym, oldtokval, *head;
|
||||
value_t *pv;
|
||||
u_int32_t t;
|
||||
char c;
|
||||
|
||||
t = peek(f);
|
||||
take();
|
||||
|
@ -511,8 +506,18 @@ static value_t do_read_sexpr(ios_t *f, value_t label)
|
|||
read_list(f, &Stack[SP-1], label);
|
||||
return POP();
|
||||
case TOK_SHARPSYM:
|
||||
// constructor notation
|
||||
sym = tokval;
|
||||
if (sym == tsym || sym == Tsym)
|
||||
return FL_T;
|
||||
else if (sym == fsym || sym == Fsym)
|
||||
return FL_F;
|
||||
// constructor notation
|
||||
c = nextchar(f);
|
||||
if (c != '(') {
|
||||
take();
|
||||
lerror(ParseError, "read: expected argument list for %s",
|
||||
symbol_name(tokval));
|
||||
}
|
||||
PUSH(NIL);
|
||||
read_list(f, &Stack[SP-1], UNBOUND);
|
||||
v = POP();
|
||||
|
|
|
@ -31,8 +31,8 @@ int isstream(value_t v)
|
|||
|
||||
value_t fl_streamp(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("streamp", nargs, 1);
|
||||
return isstream(args[0]) ? T : NIL;
|
||||
argcount("stream?", nargs, 1);
|
||||
return isstream(args[0]) ? FL_T : FL_F;
|
||||
}
|
||||
|
||||
static ios_t *tostream(value_t v, char *fname)
|
||||
|
@ -43,7 +43,7 @@ static ios_t *tostream(value_t v, char *fname)
|
|||
}
|
||||
|
||||
static builtinspec_t streamfunc_info[] = {
|
||||
{ "streamp", fl_streamp },
|
||||
{ "stream?", fl_streamp },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ static value_t print_to_string(value_t v, int princ)
|
|||
|
||||
value_t fl_stringp(value_t *args, u_int32_t nargs)
|
||||
{
|
||||
argcount("stringp", nargs, 1);
|
||||
return isstring(args[0]) ? T : NIL;
|
||||
argcount("string?", nargs, 1);
|
||||
return isstring(args[0]) ? FL_T : FL_F;
|
||||
}
|
||||
|
||||
value_t fl_string_length(value_t *args, u_int32_t nargs)
|
||||
|
@ -84,7 +84,7 @@ value_t fl_string_decode(value_t *args, u_int32_t nargs)
|
|||
{
|
||||
int term=0;
|
||||
if (nargs == 2) {
|
||||
term = (POP() != NIL);
|
||||
term = (POP() != FL_F);
|
||||
nargs--;
|
||||
}
|
||||
argcount("string.decode", nargs, 1);
|
||||
|
@ -254,7 +254,7 @@ static value_t mem_find_byte(char *s, char c, size_t start, size_t len)
|
|||
{
|
||||
char *p = memchr(s+start, c, len-start);
|
||||
if (p == NULL)
|
||||
return NIL;
|
||||
return FL_F;
|
||||
return size_wrap((size_t)(p - s));
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ value_t fl_string_find(value_t *args, u_int32_t nargs)
|
|||
type_error("string.find", "string", args[1]);
|
||||
}
|
||||
if (needlesz > len-start)
|
||||
return NIL;
|
||||
return FL_F;
|
||||
else if (needlesz == 1)
|
||||
return mem_find_byte(s, needle[0], start, len);
|
||||
else if (needlesz == 0)
|
||||
|
@ -305,7 +305,7 @@ value_t fl_string_find(value_t *args, u_int32_t nargs)
|
|||
return size_wrap(i);
|
||||
}
|
||||
}
|
||||
return NIL;
|
||||
return FL_F;
|
||||
}
|
||||
|
||||
value_t fl_string_inc(value_t *args, u_int32_t nargs)
|
||||
|
@ -349,7 +349,7 @@ value_t fl_string_dec(value_t *args, u_int32_t nargs)
|
|||
|
||||
static builtinspec_t stringfunc_info[] = {
|
||||
{ "string", fl_string },
|
||||
{ "stringp", fl_stringp },
|
||||
{ "string?", fl_stringp },
|
||||
{ "string.length", fl_string_length },
|
||||
{ "string.split", fl_string_split },
|
||||
{ "string.sub", fl_string_sub },
|
||||
|
|
|
@ -1,56 +1,70 @@
|
|||
; -*- scheme -*-
|
||||
; femtoLisp standard library
|
||||
; by Jeff Bezanson (C) 2009
|
||||
; Distributed under the BSD License
|
||||
|
||||
(set-constant! 'eq eq?)
|
||||
(set-constant! 'eqv eqv?)
|
||||
(set-constant! 'equal equal?)
|
||||
(set-constant! 'booleanp boolean?)
|
||||
(set-constant! 'consp pair?)
|
||||
(set-constant! 'null null?)
|
||||
(set-constant! 'atom atom?)
|
||||
(set-constant! 'symbolp symbol?)
|
||||
(set-constant! 'numberp number?)
|
||||
(set-constant! 'boundp bound?)
|
||||
(set-constant! 'builtinp builtin?)
|
||||
(set-constant! 'vectorp vector?)
|
||||
(set-constant! 'fixnump fixnum?)
|
||||
(set-constant! 'rplaca set-car!)
|
||||
(set-constant! 'rplacd set-cdr!)
|
||||
(set-constant! 'char? (lambda (x) (eq? (typeof x) 'wchar)))
|
||||
(set-constant! 'T #t)
|
||||
|
||||
; convert a sequence of body statements to a single expression.
|
||||
; this allows define, defun, defmacro, let, etc. to contain multiple
|
||||
; body expressions as in Common Lisp.
|
||||
(setq f-body (lambda (e)
|
||||
(set! f-body (lambda (e)
|
||||
(cond ((atom e) e)
|
||||
((eq (cdr e) ()) (car e))
|
||||
(T (cons 'progn e)))))
|
||||
(T (cons 'begin e)))))
|
||||
|
||||
(set-syntax 'defmacro
|
||||
(lambda (name args . body)
|
||||
(list 'set-syntax (list 'quote name)
|
||||
(list 'lambda args (f-body body)))))
|
||||
(set-syntax! 'define-macro
|
||||
(lambda (form . body)
|
||||
(list 'set-syntax! (list 'quote (car form))
|
||||
(list 'lambda (cdr form) (f-body body)))))
|
||||
|
||||
(defmacro label (name fn)
|
||||
(list (list 'lambda (list name) (list 'setq name fn)) nil))
|
||||
(define-macro (label name fn)
|
||||
(list (list 'lambda (list name) (list 'set! name fn)) #f))
|
||||
|
||||
; support both CL defun and Scheme-style define
|
||||
(defmacro defun (name args . body)
|
||||
(list 'setq name (list 'lambda args (f-body body))))
|
||||
(define-macro (define form . body)
|
||||
(if (symbolp form)
|
||||
(list 'set! form (car body))
|
||||
(list 'set! (car form) (list 'lambda (cdr form) (f-body body)))))
|
||||
|
||||
(defmacro define (name . body)
|
||||
(if (symbolp name)
|
||||
(list 'setq name (car body))
|
||||
(cons 'defun (cons (car name) (cons (cdr name) body)))))
|
||||
(define (set s v) (eval (list 'set! s (list 'quote v))))
|
||||
|
||||
(defun set (s v) (eval (list 'setq s (list 'quote v))))
|
||||
(define (identity x) x)
|
||||
|
||||
(defun identity (x) x)
|
||||
(setq null not)
|
||||
|
||||
(defun map (f lst)
|
||||
(define (map f lst)
|
||||
(if (atom lst) lst
|
||||
(cons (f (car lst)) (map f (cdr lst)))))
|
||||
(cons (f (car lst)) (map f (cdr lst)))))
|
||||
|
||||
(defmacro let (binds . body)
|
||||
(define-macro (let binds . body)
|
||||
(cons (list 'lambda
|
||||
(map (lambda (c) (if (consp c) (car c) c)) binds)
|
||||
(f-body body))
|
||||
(map (lambda (c) (if (consp c) (cadr c) nil)) binds)))
|
||||
(map (lambda (c) (if (consp c) (cadr c) #f)) binds)))
|
||||
|
||||
(defun nconc lsts
|
||||
(define (nconc . lsts)
|
||||
(cond ((null lsts) ())
|
||||
((null (cdr lsts)) (car lsts))
|
||||
((null (car lsts)) (apply nconc (cdr lsts)))
|
||||
(T (prog1 (car lsts)
|
||||
(rplacd (last (car lsts))
|
||||
(apply nconc (cdr lsts)))))))
|
||||
(rplacd (last (car lsts))
|
||||
(apply nconc (cdr lsts)))))))
|
||||
|
||||
(defun append lsts
|
||||
(define (append . lsts)
|
||||
(cond ((null lsts) ())
|
||||
((null (cdr lsts)) (car lsts))
|
||||
(T ((label append2 (lambda (l d)
|
||||
|
@ -59,43 +73,61 @@
|
|||
(append2 (cdr l) d)))))
|
||||
(car lsts) (apply append (cdr lsts))))))
|
||||
|
||||
(defun member (item lst)
|
||||
(cond ((atom lst) ())
|
||||
((equal (car lst) item) lst)
|
||||
(T (member item (cdr lst)))))
|
||||
(define (member item lst)
|
||||
(cond ((atom lst) #f)
|
||||
((equal (car lst) item) lst)
|
||||
(T (member item (cdr lst)))))
|
||||
(define (memq item lst)
|
||||
(cond ((atom lst) #f)
|
||||
((eq (car lst) item) lst)
|
||||
(T (memq item (cdr lst)))))
|
||||
(define (memv item lst)
|
||||
(cond ((atom lst) #f)
|
||||
((eqv (car lst) item) lst)
|
||||
(T (memv item (cdr lst)))))
|
||||
|
||||
(defun macrocallp (e) (and (symbolp (car e))
|
||||
(symbol-syntax (car e))))
|
||||
(define (assoc item lst)
|
||||
(cond ((atom lst) #f)
|
||||
((equal (caar lst) item) (car lst))
|
||||
(T (assoc item (cdr lst)))))
|
||||
(define (assv item lst)
|
||||
(cond ((atom lst) #f)
|
||||
((eqv (caar lst) item) (car lst))
|
||||
(T (assv item (cdr lst)))))
|
||||
|
||||
(defun functionp (x)
|
||||
(define (macrocall? e) (and (symbolp (car e))
|
||||
(symbol-syntax (car e))))
|
||||
|
||||
(define (function? x)
|
||||
(or (builtinp x)
|
||||
(and (consp x) (eq (car x) 'lambda))))
|
||||
(define procedure? function?)
|
||||
|
||||
(defun macroexpand-1 (e)
|
||||
(define (macroexpand-1 e)
|
||||
(if (atom e) e
|
||||
(let ((f (macrocallp e)))
|
||||
(if f (apply f (cdr e))
|
||||
e))))
|
||||
(let ((f (macrocall? e)))
|
||||
(if f (apply f (cdr e))
|
||||
e))))
|
||||
|
||||
; convert to proper list, i.e. remove "dots", and append
|
||||
(defun append.2 (l tail)
|
||||
(define (append.2 l tail)
|
||||
(cond ((null l) tail)
|
||||
((atom l) (cons l tail))
|
||||
(T (cons (car l) (append.2 (cdr l) tail)))))
|
||||
|
||||
(define (cadr x) (car (cdr x)))
|
||||
|
||||
;(setq *special-forms* '(quote cond if and or while lambda trycatch
|
||||
; setq progn))
|
||||
;(set! *special-forms* '(quote cond if and or while lambda trycatch
|
||||
; set! begin))
|
||||
|
||||
(defun macroexpand (e)
|
||||
(define (macroexpand e)
|
||||
((label mexpand
|
||||
(lambda (e env f)
|
||||
(progn
|
||||
(begin
|
||||
(while (and (consp e)
|
||||
(not (member (car e) env))
|
||||
(setq f (macrocallp e)))
|
||||
(setq e (apply f (cdr e))))
|
||||
(set! f (macrocall? e)))
|
||||
(set! e (apply f (cdr e))))
|
||||
(cond ((and (consp e)
|
||||
(not (eq (car e) 'quote)))
|
||||
(let ((newenv
|
||||
|
@ -103,28 +135,26 @@
|
|||
(consp (cdr e)))
|
||||
(append.2 (cadr e) env)
|
||||
env)))
|
||||
(map (lambda (x) (mexpand x newenv nil)) e)))
|
||||
;((and (symbolp e) (constantp e)) (eval e))
|
||||
(map (lambda (x) (mexpand x newenv ())) e)))
|
||||
;((and (symbolp e) (constant? e)) (eval e))
|
||||
;((and (symbolp e)
|
||||
; (not (member e *special-forms*))
|
||||
; (not (member e env))) (cons '%top e))
|
||||
(T e)))))
|
||||
e nil nil))
|
||||
e () ()))
|
||||
|
||||
; uncomment this to macroexpand functions at definition time.
|
||||
; makes typical code ~25% faster, but only works for defun expressions
|
||||
; at the top level.
|
||||
(defmacro defun (name args . body)
|
||||
(list 'setq name (macroexpand (list 'lambda args (f-body body)))))
|
||||
(define-macro (define form . body)
|
||||
(if (symbolp form)
|
||||
(list 'set! form (car body))
|
||||
(list 'set! (car form)
|
||||
(macroexpand (list 'lambda (cdr form) (f-body body))))))
|
||||
(define-macro (define-macro form . body)
|
||||
(list 'set-syntax! (list 'quote (car form))
|
||||
(macroexpand (list 'lambda (cdr form) (f-body body)))))
|
||||
(define macroexpand (macroexpand macroexpand))
|
||||
|
||||
; same thing for macros. enabled by default because macros are usually
|
||||
; defined at the top level.
|
||||
(defmacro defmacro (name args . body)
|
||||
(list 'set-syntax (list 'quote name)
|
||||
(macroexpand (list 'lambda args (f-body body)))))
|
||||
|
||||
(setq = equal)
|
||||
(setq eql equal)
|
||||
(define = equal)
|
||||
(define eql eqv)
|
||||
(define (/= a b) (not (equal a b)))
|
||||
(define != /=)
|
||||
(define (> a b) (< b a))
|
||||
|
@ -134,11 +164,7 @@
|
|||
(define (1- n) (- n 1))
|
||||
(define (mod x y) (- x (* (/ x y) y)))
|
||||
(define (abs x) (if (< x 0) (- x) x))
|
||||
(setq K prog1) ; K combinator ;)
|
||||
(define (funcall f . args) (apply f args))
|
||||
(define (symbol-value sym) (eval sym))
|
||||
(define symbol-function symbol-value)
|
||||
(define (terpri) (princ "\n") nil)
|
||||
(define K prog1) ; K combinator ;)
|
||||
|
||||
(define (caar x) (car (car x)))
|
||||
(define (cdar x) (cdr (car x)))
|
||||
|
@ -153,51 +179,52 @@
|
|||
(define (cddar x) (cdr (cdr (car x))))
|
||||
(define (cdddr x) (cdr (cdr (cdr x))))
|
||||
|
||||
(defun every (pred lst)
|
||||
(define (every pred lst)
|
||||
(or (atom lst)
|
||||
(and (pred (car lst))
|
||||
(every pred (cdr lst)))))
|
||||
|
||||
(defun any (pred lst)
|
||||
(define (any pred lst)
|
||||
(and (consp lst)
|
||||
(or (pred (car lst))
|
||||
(any pred (cdr lst)))))
|
||||
|
||||
(defun listp (a) (or (eq a ()) (consp a)))
|
||||
(define (listp a) (or (null a) (consp a)))
|
||||
(define (list? a) (or (null a) (and (pair? a) (list? (cdr a)))))
|
||||
|
||||
(defun nthcdr (lst n)
|
||||
(define (nthcdr lst n)
|
||||
(if (<= n 0) lst
|
||||
(nthcdr (cdr lst) (- n 1))))
|
||||
(nthcdr (cdr lst) (- n 1))))
|
||||
|
||||
(defun list-ref (lst n)
|
||||
(define (list-ref lst n)
|
||||
(car (nthcdr lst n)))
|
||||
|
||||
(defun list* l
|
||||
(define (list* . l)
|
||||
(if (atom (cdr l))
|
||||
(car l)
|
||||
(cons (car l) (apply list* (cdr l)))))
|
||||
(cons (car l) (apply list* (cdr l)))))
|
||||
|
||||
(defun nlist* l
|
||||
(define (nlist* . l)
|
||||
(if (atom (cdr l))
|
||||
(car l)
|
||||
(rplacd l (apply nlist* (cdr l)))))
|
||||
(rplacd l (apply nlist* (cdr l)))))
|
||||
|
||||
(defun lastcdr (l)
|
||||
(define (lastcdr l)
|
||||
(if (atom l) l
|
||||
(lastcdr (cdr l))))
|
||||
(lastcdr (cdr l))))
|
||||
|
||||
(defun last (l)
|
||||
(define (last l)
|
||||
(cond ((atom l) l)
|
||||
((atom (cdr l)) l)
|
||||
(T (last (cdr l)))))
|
||||
|
||||
(defun map! (f lst)
|
||||
(define (map! f lst)
|
||||
(prog1 lst
|
||||
(while (consp lst)
|
||||
(rplaca lst (f (car lst)))
|
||||
(setq lst (cdr lst)))))
|
||||
(while (consp lst)
|
||||
(rplaca lst (f (car lst)))
|
||||
(set! lst (cdr lst)))))
|
||||
|
||||
(defun mapcar (f . lsts)
|
||||
(define (mapcar f . lsts)
|
||||
((label mapcar-
|
||||
(lambda (lsts)
|
||||
(cond ((null lsts) (f))
|
||||
|
@ -206,18 +233,18 @@
|
|||
(mapcar- (map cdr lsts)))))))
|
||||
lsts))
|
||||
|
||||
(defun transpose (M) (apply mapcar (cons list M)))
|
||||
(define (transpose M) (apply mapcar (cons list M)))
|
||||
|
||||
(defun filter (pred lst) (filter- pred lst nil))
|
||||
(defun filter- (pred lst accum)
|
||||
(define (filter pred lst) (filter- pred lst ()))
|
||||
(define (filter- pred lst accum)
|
||||
(cond ((null lst) accum)
|
||||
((pred (car lst))
|
||||
(filter- pred (cdr lst) (cons (car lst) accum)))
|
||||
(T
|
||||
(filter- pred (cdr lst) accum))))
|
||||
|
||||
(defun separate (pred lst) (separate- pred lst nil nil))
|
||||
(defun separate- (pred lst yes no)
|
||||
(define (separate pred lst) (separate- pred lst () ()))
|
||||
(define (separate- pred lst yes no)
|
||||
(cond ((null lst) (cons yes no))
|
||||
((pred (car lst))
|
||||
(separate- pred (cdr lst) (cons (car lst) yes) no))
|
||||
|
@ -232,11 +259,7 @@
|
|||
(if (null lst) zero
|
||||
(foldl f (f (car lst) zero) (cdr lst))))
|
||||
|
||||
(define (reverse lst) (foldl cons nil lst))
|
||||
|
||||
(defun reduce (f zero lst)
|
||||
(if (null lst) zero
|
||||
(reduce f (f zero (car lst)) (cdr lst))))
|
||||
(define (reverse lst) (foldl cons () lst))
|
||||
|
||||
(define (copy-list l)
|
||||
(if (atom l) l
|
||||
|
@ -248,80 +271,80 @@
|
|||
(copy-tree (cdr l)))))
|
||||
|
||||
(define (nreverse l)
|
||||
(let ((prev nil))
|
||||
(let ((prev ()))
|
||||
(while (consp l)
|
||||
(setq l (prog1 (cdr l)
|
||||
(rplacd l (prog1 prev
|
||||
(setq prev l))))))
|
||||
(set! l (prog1 (cdr l)
|
||||
(rplacd l (prog1 prev
|
||||
(set! prev l))))))
|
||||
prev))
|
||||
|
||||
(defmacro let* (binds . body)
|
||||
(define-macro (let* binds . body)
|
||||
(cons (list 'lambda (map car binds)
|
||||
(cons 'progn
|
||||
(nconc (map (lambda (b) (cons 'setq b)) binds)
|
||||
(cons 'begin
|
||||
(nconc (map (lambda (b) (cons 'set! b)) binds)
|
||||
body)))
|
||||
(map (lambda (x) nil) binds)))
|
||||
(map (lambda (x) #f) binds)))
|
||||
|
||||
(defmacro labels (binds . body)
|
||||
(define-macro (labels binds . body)
|
||||
(cons (list 'lambda (map car binds)
|
||||
(cons 'progn
|
||||
(cons 'begin
|
||||
(nconc (map (lambda (b)
|
||||
(list 'setq (car b) (cons 'lambda (cdr b))))
|
||||
(list 'set! (car b) (cons 'lambda (cdr b))))
|
||||
binds)
|
||||
body)))
|
||||
(map (lambda (x) nil) binds)))
|
||||
(map (lambda (x) #f) binds)))
|
||||
|
||||
(defmacro when (c . body) (list 'if c (f-body body) nil))
|
||||
(defmacro unless (c . body) (list 'if c nil (f-body body)))
|
||||
(define-macro (when c . body) (list 'if c (f-body body) #f))
|
||||
(define-macro (unless c . body) (list 'if c #f (f-body body)))
|
||||
|
||||
(defmacro dotimes (var . body)
|
||||
(define-macro (dotimes var . body)
|
||||
(let ((v (car var))
|
||||
(cnt (cadr var)))
|
||||
`(for 0 (- ,cnt 1)
|
||||
(lambda (,v) ,(f-body body)))))
|
||||
|
||||
(defun map-int (f n)
|
||||
(define (map-int f n)
|
||||
(if (<= n 0)
|
||||
()
|
||||
(let ((first (cons (f 0) nil))
|
||||
(acc nil))
|
||||
(setq acc first)
|
||||
(let ((first (cons (f 0) ()))
|
||||
(acc ()))
|
||||
(set! acc first)
|
||||
(for 1 (- n 1)
|
||||
(lambda (i)
|
||||
(progn (rplacd acc (cons (f i) nil))
|
||||
(setq acc (cdr acc)))))
|
||||
(begin (rplacd acc (cons (f i) ()))
|
||||
(set! acc (cdr acc)))))
|
||||
first)))
|
||||
|
||||
(defun iota (n) (map-int identity n))
|
||||
(define (iota n) (map-int identity n))
|
||||
(define ι iota)
|
||||
|
||||
(defun error args (raise (cons 'error args)))
|
||||
(define (error . args) (raise (cons 'error args)))
|
||||
|
||||
(defmacro throw (tag value) `(raise (list 'thrown-value ,tag ,value)))
|
||||
(defmacro catch (tag expr)
|
||||
(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 (consp ,e)
|
||||
(eq (car ,e) 'thrown-value)
|
||||
(eq (cadr ,e) ,tag))
|
||||
(caddr ,e)
|
||||
(raise ,e))))))
|
||||
(raise ,e))))))
|
||||
|
||||
(defmacro unwind-protect (expr finally)
|
||||
(define-macro (unwind-protect expr finally)
|
||||
(let ((e (gensym)))
|
||||
`(prog1 (trycatch ,expr
|
||||
(lambda (,e) (progn ,finally (raise ,e))))
|
||||
,finally)))
|
||||
(lambda (,e) (begin ,finally (raise ,e))))
|
||||
,finally)))
|
||||
|
||||
; (try expr
|
||||
; (catch (type-error e) . exprs)
|
||||
; (catch (io-error e) . exprs)
|
||||
; (catch (e) . exprs)
|
||||
; (finally . exprs))
|
||||
(defmacro try (expr . forms)
|
||||
(define-macro (try expr . forms)
|
||||
(let* ((e (gensym))
|
||||
(reraised (gensym))
|
||||
(final (f-body (cdr (or (assoc 'finally forms) '(())))))
|
||||
(final (f-body (cdr (or (assq 'finally forms) '(())))))
|
||||
(catches (filter (lambda (f) (eq (car f) 'catch)) forms))
|
||||
(catchblock `(cond
|
||||
,.(map (lambda (catc)
|
||||
|
@ -337,7 +360,7 @@
|
|||
(eq (car ,e)
|
||||
',extype)))
|
||||
T); (catch (e) ...), match anything
|
||||
(let ((,var ,e)) (progn ,@todo)))))
|
||||
(let ((,var ,e)) (begin ,@todo)))))
|
||||
catches)
|
||||
(T (raise ,e))))) ; no matches, reraise
|
||||
(if final
|
||||
|
@ -347,12 +370,12 @@
|
|||
(lambda (,e)
|
||||
(trycatch ,catchblock
|
||||
(lambda (,reraised)
|
||||
(progn ,final
|
||||
(begin ,final
|
||||
(raise ,reraised))))))
|
||||
,final)
|
||||
; finally only; same as unwind-protect
|
||||
`(prog1 (trycatch ,expr (lambda (,e)
|
||||
(progn ,final (raise ,e))))
|
||||
(begin ,final (raise ,e))))
|
||||
,final))
|
||||
; catch, no finally
|
||||
`(trycatch ,expr (lambda (,e) ,catchblock)))))
|
||||
|
@ -360,7 +383,7 @@
|
|||
; setf
|
||||
; expands (setf (place x ...) v) to (mutator (f x ...) v)
|
||||
; (mutator (identity x ...) v) is interpreted as (mutator x ... v)
|
||||
(setq *setf-place-list*
|
||||
(set! *setf-place-list*
|
||||
; place mutator f
|
||||
'((car rplaca identity)
|
||||
(cdr rplacd identity)
|
||||
|
@ -379,60 +402,58 @@
|
|||
(list-ref rplaca nthcdr)
|
||||
(get put identity)
|
||||
(aref aset identity)
|
||||
(symbol-function set identity)
|
||||
(symbol-value set identity)
|
||||
(symbol-syntax set-syntax identity)))
|
||||
(symbol-syntax set-syntax! identity)))
|
||||
|
||||
(defun setf-place-mutator (place val)
|
||||
(define (setf-place-mutator place val)
|
||||
(if (symbolp place)
|
||||
(list 'setq place val)
|
||||
(let ((mutator (assoc (car place) *setf-place-list*)))
|
||||
(list 'set! place val)
|
||||
(let ((mutator (assq (car place) *setf-place-list*)))
|
||||
(if (null mutator)
|
||||
(error '|setf: unknown place | (car place))
|
||||
(if (eq (caddr mutator) 'identity)
|
||||
(cons (cadr mutator) (append (cdr place) (list val)))
|
||||
(list (cadr mutator)
|
||||
(cons (caddr mutator) (cdr place))
|
||||
val))))))
|
||||
(error "setf: unknown place " (car place))
|
||||
(if (eq (caddr mutator) 'identity)
|
||||
(cons (cadr mutator) (append (cdr place) (list val)))
|
||||
(list (cadr mutator)
|
||||
(cons (caddr mutator) (cdr place))
|
||||
val))))))
|
||||
|
||||
(defmacro setf args
|
||||
(define-macro (setf . args)
|
||||
(f-body
|
||||
((label setf-
|
||||
(lambda (args)
|
||||
(if (null args)
|
||||
nil
|
||||
()
|
||||
(cons (setf-place-mutator (car args) (cadr args))
|
||||
(setf- (cddr args))))))
|
||||
args)))
|
||||
|
||||
(defun revappend (l1 l2) (nconc (reverse l1) l2))
|
||||
(defun nreconc (l1 l2) (nconc (nreverse l1) l2))
|
||||
(define (revappend l1 l2) (nconc (reverse l1) l2))
|
||||
(define (nreconc l1 l2) (nconc (nreverse l1) l2))
|
||||
|
||||
(defun list-to-vector (l) (apply vector l))
|
||||
(defun vector-to-list (v)
|
||||
(define (list-to-vector l) (apply vector l))
|
||||
(define (vector-to-list v)
|
||||
(let ((n (length v))
|
||||
(l nil))
|
||||
(l ()))
|
||||
(for 1 n
|
||||
(lambda (i)
|
||||
(setq l (cons (aref v (- n i)) l))))
|
||||
(set! l (cons (aref v (- n i)) l))))
|
||||
l))
|
||||
|
||||
(defun self-evaluating-p (x)
|
||||
(define (self-evaluating? x)
|
||||
(or (and (atom x)
|
||||
(not (symbolp x)))
|
||||
(and (constantp x)
|
||||
(and (constant? x)
|
||||
(eq x (eval x)))))
|
||||
|
||||
; backquote
|
||||
(defmacro backquote (x) (bq-process x))
|
||||
(define-macro (backquote x) (bq-process x))
|
||||
|
||||
(defun splice-form-p (x)
|
||||
(define (splice-form? x)
|
||||
(or (and (consp x) (or (eq (car x) '*comma-at*)
|
||||
(eq (car x) '*comma-dot*)))
|
||||
(eq x '*comma*)))
|
||||
|
||||
(defun bq-process (x)
|
||||
(cond ((self-evaluating-p x)
|
||||
(define (bq-process x)
|
||||
(cond ((self-evaluating? x)
|
||||
(if (vectorp x)
|
||||
(let ((body (bq-process (vector-to-list x))))
|
||||
(if (eq (car body) 'list)
|
||||
|
@ -442,7 +463,7 @@
|
|||
((atom x) (list 'quote x))
|
||||
((eq (car x) 'backquote) (bq-process (bq-process (cadr x))))
|
||||
((eq (car x) '*comma*) (cadr x))
|
||||
((not (any splice-form-p x))
|
||||
((not (any splice-form? x))
|
||||
(let ((lc (lastcdr x))
|
||||
(forms (map bq-bracket1 x)))
|
||||
(if (null lc)
|
||||
|
@ -451,8 +472,8 @@
|
|||
(T (let ((p x) (q ()))
|
||||
(while (and (consp p)
|
||||
(not (eq (car p) '*comma*)))
|
||||
(setq q (cons (bq-bracket (car p)) q))
|
||||
(setq p (cdr p)))
|
||||
(set! q (cons (bq-bracket (car p)) q))
|
||||
(set! p (cdr p)))
|
||||
(let ((forms
|
||||
(cond ((consp p) (nreconc q (list (cadr p))))
|
||||
((null p) (nreverse q))
|
||||
|
@ -461,7 +482,7 @@
|
|||
(car forms)
|
||||
(cons 'nconc forms)))))))
|
||||
|
||||
(defun bq-bracket (x)
|
||||
(define (bq-bracket x)
|
||||
(cond ((atom x) (list list (bq-process x)))
|
||||
((eq (car x) '*comma*) (list list (cadr x)))
|
||||
((eq (car x) '*comma-at*) (list 'copy-list (cadr x)))
|
||||
|
@ -469,21 +490,23 @@
|
|||
(T (list list (bq-process x)))))
|
||||
|
||||
; bracket without splicing
|
||||
(defun bq-bracket1 (x)
|
||||
(define (bq-bracket1 x)
|
||||
(if (and (consp x) (eq (car x) '*comma*))
|
||||
(cadr x)
|
||||
(bq-process x)))
|
||||
(bq-process x)))
|
||||
|
||||
(defmacro assert (expr) `(if ,expr T (raise '(assert-failed ,expr))))
|
||||
(define-macro (assert expr) `(if ,expr T (raise '(assert-failed ,expr))))
|
||||
|
||||
(defmacro time (expr)
|
||||
(define-macro (time expr)
|
||||
(let ((t0 (gensym)))
|
||||
`(let ((,t0 (time.now)))
|
||||
(prog1
|
||||
,expr
|
||||
(princ "Elapsed time: " (- (time.now) ,t0) " seconds\n")))))
|
||||
,expr
|
||||
(princ "Elapsed time: " (- (time.now) ,t0) " seconds\n")))))
|
||||
|
||||
(defun vector.map (f v)
|
||||
(define (display x) (princ x) (princ "\n"))
|
||||
|
||||
(define (vector.map f v)
|
||||
(let* ((n (length v))
|
||||
(nv (vector.alloc n)))
|
||||
(for 0 (- n 1)
|
||||
|
@ -491,16 +514,16 @@
|
|||
(aset nv i (f (aref v i)))))
|
||||
nv))
|
||||
|
||||
(defun table.pairs (t)
|
||||
(define (table.pairs t)
|
||||
(table.foldl (lambda (k v z) (cons (cons k v) z))
|
||||
() t))
|
||||
(defun table.keys (t)
|
||||
(define (table.keys t)
|
||||
(table.foldl (lambda (k v z) (cons k z))
|
||||
() t))
|
||||
(defun table.values (t)
|
||||
(define (table.values t)
|
||||
(table.foldl (lambda (k v z) (cons v z))
|
||||
() t))
|
||||
(defun table.clone (t)
|
||||
(define (table.clone t)
|
||||
(let ((nt (table)))
|
||||
(table.foldl (lambda (k v z) (put nt k v))
|
||||
() t)
|
||||
|
|
|
@ -70,8 +70,8 @@ int ishashtable(value_t v)
|
|||
|
||||
value_t fl_tablep(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("tablep", nargs, 1);
|
||||
return ishashtable(args[0]) ? T : NIL;
|
||||
argcount("table?", nargs, 1);
|
||||
return ishashtable(args[0]) ? FL_T : FL_F;
|
||||
}
|
||||
|
||||
static htable_t *totable(value_t v, char *fname)
|
||||
|
@ -139,7 +139,7 @@ value_t fl_table_has(value_t *args, uint32_t nargs)
|
|||
{
|
||||
argcount("has", nargs, 2);
|
||||
htable_t *h = totable(args[0], "has");
|
||||
return equalhash_has(h, (void*)args[1]) ? T : NIL;
|
||||
return equalhash_has(h, (void*)args[1]) ? FL_T : FL_F;
|
||||
}
|
||||
|
||||
// (del table key)
|
||||
|
@ -177,7 +177,7 @@ value_t fl_table_foldl(value_t *args, uint32_t nargs)
|
|||
|
||||
static builtinspec_t tablefunc_info[] = {
|
||||
{ "table", fl_table },
|
||||
{ "tablep", fl_tablep },
|
||||
{ "table?", fl_tablep },
|
||||
{ "put", fl_table_put },
|
||||
{ "get", fl_table_get },
|
||||
{ "has", fl_table_has },
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
; -*- scheme -*-
|
||||
; color for performance
|
||||
|
||||
(load "color.lsp")
|
||||
|
||||
; 100x color 5 queens
|
||||
(setq Q (generate-5x5-pairs))
|
||||
(defun ct ()
|
||||
(setq C (color-pairs Q '(a b c d e)))
|
||||
(define Q (generate-5x5-pairs))
|
||||
(define (ct)
|
||||
(set! C (color-pairs Q '(a b c d e)))
|
||||
(dotimes (n 99) (color-pairs Q '(a b c d e))))
|
||||
(time (ct))
|
||||
(assert (equal C '((23 . a) (9 . a) (22 . b) (17 . d) (14 . d) (8 . b) (21 . e)
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
; -*- scheme -*-
|
||||
|
||||
; make label self-evaluating, but evaluating the lambda in the process
|
||||
;(defmacro labl (name f)
|
||||
; (list list ''labl (list 'quote name) f))
|
||||
|
||||
(defmacro labl (name f)
|
||||
`(let (,name) (setq ,name ,f)))
|
||||
(define-macro (labl name f)
|
||||
`(let (,name) (set! ,name ,f)))
|
||||
|
||||
;(define (reverse lst)
|
||||
; ((label rev-help (lambda (lst result)
|
||||
; (if (null lst) result
|
||||
; (rev-help (cdr lst) (cons (car lst) result)))))
|
||||
; lst nil))
|
||||
; lst ()))
|
||||
|
||||
(define (append- . lsts)
|
||||
((label append-h
|
||||
|
@ -28,20 +30,20 @@
|
|||
(define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
|
||||
;(princ (time (fib 34)) "\n")
|
||||
;(dotimes (i 20000) (map-int (lambda (x) (list 'quote x)) 8))
|
||||
;(dotimes (i 40000) (append '(a b) '(1 2 3 4) nil '(c) nil '(5 6)))
|
||||
;(dotimes (i 40000) (append '(a b) '(1 2 3 4) () '(c) () '(5 6)))
|
||||
;(dotimes (i 80000) (list 1 2 3 4 5))
|
||||
;(setq a (map-int identity 10000))
|
||||
;(dotimes (i 200) (rfoldl cons nil a))
|
||||
;(set! a (map-int identity 10000))
|
||||
;(dotimes (i 200) (rfoldl cons () a))
|
||||
|
||||
; iterative filter
|
||||
(defun ifilter (pred lst)
|
||||
(define (ifilter pred lst)
|
||||
((label f (lambda (accum lst)
|
||||
(cond ((null lst) (nreverse accum))
|
||||
((not (pred (car lst))) (f accum (cdr lst)))
|
||||
(T (f (cons (car lst) accum) (cdr lst))))))
|
||||
nil lst))
|
||||
() lst))
|
||||
|
||||
(defun sort (l)
|
||||
(define (sort l)
|
||||
(if (or (null l) (null (cdr l))) l
|
||||
(let* ((piv (car l))
|
||||
(halves (separate (lambda (x) (< x piv)) (cdr l))))
|
||||
|
@ -49,29 +51,29 @@
|
|||
(list piv)
|
||||
(sort (cdr halves))))))
|
||||
|
||||
(defmacro dotimes (var . body)
|
||||
(define-macro (dotimes var . body)
|
||||
(let ((v (car var))
|
||||
(cnt (cadr var)))
|
||||
`(let ((,v 0))
|
||||
(while (< ,v ,cnt)
|
||||
(prog1
|
||||
,(f-body body)
|
||||
(setq ,v (+ ,v 1)))))))
|
||||
(set! ,v (+ ,v 1)))))))
|
||||
|
||||
(defun map-int (f n)
|
||||
(define (map-int f n)
|
||||
(if (<= n 0)
|
||||
()
|
||||
(let ((first (cons (f 0) nil)))
|
||||
((label map-int-
|
||||
(lambda (acc i n)
|
||||
(if (= i n)
|
||||
first
|
||||
(progn (rplacd acc (cons (f i) nil))
|
||||
(map-int- (cdr acc) (+ i 1) n)))))
|
||||
first 1 n))))
|
||||
(let ((first (cons (f 0) ())))
|
||||
((label map-int-
|
||||
(lambda (acc i n)
|
||||
(if (= i n)
|
||||
first
|
||||
(begin (rplacd acc (cons (f i) ()))
|
||||
(map-int- (cdr acc) (+ i 1) n)))))
|
||||
first 1 n))))
|
||||
|
||||
(defmacro labl (name fn)
|
||||
`((lambda (,name) (setq ,name ,fn)) nil))
|
||||
(define-macro (labl name fn)
|
||||
`((lambda (,name) (set! ,name ,fn)) ()))
|
||||
|
||||
(define (square x) (* x x))
|
||||
(define (evenp x) (= x (* (/ x 2) 2)))
|
||||
|
@ -88,43 +90,43 @@
|
|||
(T (gcd b (- a b)))))
|
||||
|
||||
; like eval-when-compile
|
||||
(defmacro literal (expr)
|
||||
(define-macro (literal expr)
|
||||
(let ((v (eval expr)))
|
||||
(if (self-evaluating-p v) v (list quote v))))
|
||||
(if (self-evaluating? v) v (list quote v))))
|
||||
|
||||
(defun cardepth (l)
|
||||
(define (cardepth l)
|
||||
(if (atom l) 0
|
||||
(+ 1 (cardepth (car l)))))
|
||||
(+ 1 (cardepth (car l)))))
|
||||
|
||||
(defun nestlist (f zero n)
|
||||
(define (nestlist f zero n)
|
||||
(if (<= n 0) ()
|
||||
(cons zero (nestlist f (f zero) (- n 1)))))
|
||||
(cons zero (nestlist f (f zero) (- n 1)))))
|
||||
|
||||
(defun mapl (f . lsts)
|
||||
(define (mapl f . lsts)
|
||||
((label mapl-
|
||||
(lambda (lsts)
|
||||
(if (null (car lsts)) ()
|
||||
(progn (apply f lsts) (mapl- (map cdr lsts))))))
|
||||
(begin (apply f lsts) (mapl- (map cdr lsts))))))
|
||||
lsts))
|
||||
|
||||
; test to see if a symbol begins with :
|
||||
(defun keywordp (s)
|
||||
(define (keywordp s)
|
||||
(and (>= s '|:|) (<= s '|:~|)))
|
||||
|
||||
; swap the cars and cdrs of every cons in a structure
|
||||
(defun swapad (c)
|
||||
(define (swapad c)
|
||||
(if (atom c) c
|
||||
(rplacd c (K (swapad (car c))
|
||||
(rplaca c (swapad (cdr c)))))))
|
||||
(rplacd c (K (swapad (car c))
|
||||
(rplaca c (swapad (cdr c)))))))
|
||||
|
||||
(defun without (x l)
|
||||
(define (without x l)
|
||||
(filter (lambda (e) (not (eq e x))) l))
|
||||
|
||||
(defun conscount (c)
|
||||
(define (conscount c)
|
||||
(if (consp c) (+ 1
|
||||
(conscount (car c))
|
||||
(conscount (cdr c)))
|
||||
0))
|
||||
0))
|
||||
|
||||
; _ Welcome to
|
||||
; (_ _ _ |_ _ | . _ _ 2
|
||||
|
@ -135,12 +137,12 @@
|
|||
;| (/_||||_()|_|_\|)
|
||||
; |
|
||||
|
||||
(defmacro while- (test . forms)
|
||||
(define-macro (while- test . forms)
|
||||
`((label -loop- (lambda ()
|
||||
(if ,test
|
||||
(progn ,@forms
|
||||
(begin ,@forms
|
||||
(-loop-))
|
||||
nil)))))
|
||||
())))))
|
||||
|
||||
; this would be a cool use of thunking to handle 'finally' clauses, but
|
||||
; this code doesn't work in the case where the user manually re-raises
|
||||
|
@ -150,8 +152,8 @@
|
|||
; (catch (TypeError e) . exprs)
|
||||
; (catch (IOError e) . exprs)
|
||||
; (finally . exprs))
|
||||
(defmacro try (expr . forms)
|
||||
(let ((final (f-body (cdr (or (assoc 'finally forms) '(())))))
|
||||
(define-macro (try expr . forms)
|
||||
(let ((final (f-body (cdr (or (assq 'finally forms) '(())))))
|
||||
(body (foldr
|
||||
; create a function to check for and handle one exception
|
||||
; type, and pass off control to the next when no match
|
||||
|
@ -167,7 +169,7 @@
|
|||
(,next ,var)))))
|
||||
|
||||
; default function; no matches so re-raise
|
||||
'(lambda (e) (progn (*_try_finally_thunk_*) (raise e)))
|
||||
'(lambda (e) (begin (*_try_finally_thunk_*) (raise e)))
|
||||
|
||||
; make list of catch forms
|
||||
(filter (lambda (f) (eq (car f) 'catch)) forms))))
|
||||
|
@ -175,10 +177,6 @@
|
|||
(prog1 (attempt ,expr ,body)
|
||||
(*_try_finally_thunk_*)))))
|
||||
|
||||
(defun map (f lst)
|
||||
(if (atom lst) lst
|
||||
(cons (funcall f (car lst)) (map f (cdr lst)))))
|
||||
|
||||
(define Y
|
||||
(lambda (f)
|
||||
((lambda (h)
|
||||
|
@ -191,56 +189,39 @@
|
|||
(lambda (n)
|
||||
(if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))))))
|
||||
|
||||
(defmacro debug ()
|
||||
(let ((g (gensym)))
|
||||
`(progn (princ "Debug REPL:\n")
|
||||
(let ((,g (read)))
|
||||
(while (not (eq ,g 'quit))
|
||||
(prog1
|
||||
(print (trycatch (apply '(macro x x) ,g)
|
||||
identity))
|
||||
(setq ,g (read))))))))
|
||||
|
||||
;(defun tt () (time (dotimes (i 500000) (* 0x1fffffff 1) )))
|
||||
;(tt)
|
||||
;(tt)
|
||||
;(tt)
|
||||
|
||||
(let ((g (gensym)))
|
||||
(defmacro delay (expr)
|
||||
`(let ((,g ',g))
|
||||
(lambda () (if (eq ,g ',g) (setq ,g ,expr) ,g)))))
|
||||
|
||||
(defun force (p) (p))
|
||||
|
||||
(defmacro accumulate-while (cnd what . body)
|
||||
(define-macro (accumulate-while cnd what . body)
|
||||
(let ((first (gensym))
|
||||
(acc (gensym)))
|
||||
`(let ((,first nil)
|
||||
(,acc (list nil)))
|
||||
(setq ,first ,acc)
|
||||
`(let ((,first ())
|
||||
(,acc (list ())))
|
||||
(set! ,first ,acc)
|
||||
(while ,cnd
|
||||
(progn (setq ,acc
|
||||
(cdr (rplacd ,acc (cons ,what nil))))
|
||||
,@body))
|
||||
(begin (set! ,acc
|
||||
(cdr (rplacd ,acc (cons ,what ()))))
|
||||
,@body))
|
||||
(cdr ,first))))
|
||||
|
||||
(defmacro accumulate-for (var lo hi what . body)
|
||||
(define-macro (accumulate-for var lo hi what . body)
|
||||
(let ((first (gensym))
|
||||
(acc (gensym)))
|
||||
`(let ((,first nil)
|
||||
(,acc (list nil)))
|
||||
(setq ,first ,acc)
|
||||
`(let ((,first ())
|
||||
(,acc (list ())))
|
||||
(set! ,first ,acc)
|
||||
(for ,lo ,hi
|
||||
(lambda (,var)
|
||||
(progn (setq ,acc
|
||||
(cdr (rplacd ,acc (cons ,what nil))))
|
||||
(begin (set! ,acc
|
||||
(cdr (rplacd ,acc (cons ,what ()))))
|
||||
,@body)))
|
||||
(cdr ,first))))
|
||||
|
||||
(defun map-indexed (f lst)
|
||||
(define (map-indexed f lst)
|
||||
(if (atom lst) lst
|
||||
(let ((i 0))
|
||||
(accumulate-while (consp lst) (f (car lst) i)
|
||||
(progn (setq lst (cdr lst))
|
||||
(setq i (1+ i)))))))
|
||||
(begin (set! lst (cdr lst))
|
||||
(set! i (1+ i)))))))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(defun maplist (f l)
|
||||
; -*- scheme -*-
|
||||
(define (maplist f l)
|
||||
(if (null l) ()
|
||||
(cons (f l) (maplist f (cdr l)))))
|
||||
|
||||
|
@ -6,37 +7,37 @@
|
|||
; make m copies of a CDR-circular list of length n, and connect corresponding
|
||||
; conses in CAR-circular loops
|
||||
; replace maplist 'identity' with 'copy-tree' for rapdily exploding memory use
|
||||
(defun torus (m n)
|
||||
(define (torus m n)
|
||||
(let* ((l (map-int identity n))
|
||||
(g l)
|
||||
(prev g))
|
||||
(dotimes (i (- m 1))
|
||||
(setq prev g)
|
||||
(setq g (maplist identity g))
|
||||
(rplacd (last prev) prev))
|
||||
(rplacd (last g) g)
|
||||
(set! prev g)
|
||||
(set! g (maplist identity g))
|
||||
(set-cdr! (last prev) prev))
|
||||
(set-cdr! (last g) g)
|
||||
(let ((a l)
|
||||
(b g))
|
||||
(dotimes (i n)
|
||||
(rplaca a b)
|
||||
(setq a (cdr a))
|
||||
(setq b (cdr b))))
|
||||
(set-car! a b)
|
||||
(set! a (cdr a))
|
||||
(set! b (cdr b))))
|
||||
l))
|
||||
|
||||
(defun cyl (m n)
|
||||
(define (cyl m n)
|
||||
(let* ((l (map-int identity n))
|
||||
(g l))
|
||||
(dotimes (i (- m 1))
|
||||
(setq g (maplist identity g)))
|
||||
(set! g (maplist identity g)))
|
||||
(let ((a l)
|
||||
(b g))
|
||||
(dotimes (i n)
|
||||
(rplaca a b)
|
||||
(setq a (cdr a))
|
||||
(setq b (cdr b))))
|
||||
(set-car! a b)
|
||||
(set! a (cdr a))
|
||||
(set! b (cdr b))))
|
||||
l))
|
||||
|
||||
(time (progn (print (torus 100 100)) nil))
|
||||
(time (begin (print (torus 100 100)) ()))
|
||||
;(time (dotimes (i 1) (load "100x100.lsp")))
|
||||
; with ltable
|
||||
; printing time: 0.415sec
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
; -*- scheme -*-
|
||||
(define (every-int n)
|
||||
(list (fixnum n) (int8 n) (uint8 n) (int16 n) (uint16 n) (int32 n) (uint32 n)
|
||||
(int64 n) (uint64 n)))
|
||||
|
@ -7,7 +8,7 @@
|
|||
|
||||
(define (each f l)
|
||||
(if (atom l) ()
|
||||
(progn (f (car l))
|
||||
(begin (f (car l))
|
||||
(each f (cdr l)))))
|
||||
|
||||
(define (each^2 f l m)
|
||||
|
@ -15,7 +16,7 @@
|
|||
|
||||
(define (test-lt a b)
|
||||
(each^2 (lambda (neg pos)
|
||||
(progn
|
||||
(begin
|
||||
(eval `(assert (= -1 (compare ,neg ,pos))))
|
||||
(eval `(assert (= 1 (compare ,pos ,neg))))))
|
||||
a
|
||||
|
@ -23,7 +24,7 @@
|
|||
|
||||
(define (test-eq a b)
|
||||
(each^2 (lambda (a b)
|
||||
(progn
|
||||
(begin
|
||||
(eval `(assert (= 0 (compare ,a ,b))))))
|
||||
a
|
||||
b))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(setq i 0)
|
||||
(defmacro while- (test . forms)
|
||||
(set! i 0)
|
||||
(define-macro (while- test . forms)
|
||||
`((label -loop- (lambda ()
|
||||
(if ,test
|
||||
(progn ,@forms
|
||||
(begin ,@forms
|
||||
(-loop-))
|
||||
nil)))))
|
||||
(while (< i 10000000) (setq i (+ i 1)))
|
||||
nil)))))
|
||||
(while (< i 10000000) (set! i (+ i 1)))
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
char *int2str(char *dest, size_t n, long num, uint32_t base)
|
||||
{
|
||||
int i = n-1;
|
||||
int b = (int)base;
|
||||
int neg = (num<0 ? 1 : 0);
|
||||
int b = (int)base, neg = 0;
|
||||
char ch;
|
||||
if (num < 0) {
|
||||
num = -num;
|
||||
neg = 1;
|
||||
}
|
||||
dest[i--] = '\0';
|
||||
while (i >= 0) {
|
||||
ch = (char)(num % b);
|
||||
|
|
Loading…
Reference in New Issue