X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fboot.lisp;h=7605a2968ef46c2073138461bed39313b157bac4;hb=28a82d590a536e520a46e0703a08829485ae8bf5;hp=3ba4fda901ebf42c87893113339e2fcebeff588e;hpb=6401376cfce4be41e163eb4c7cd9b848f4f955ec;p=jscl.git diff --git a/src/boot.lisp b/src/boot.lisp index 3ba4fda..7605a29 100644 --- a/src/boot.lisp +++ b/src/boot.lisp @@ -60,10 +60,10 @@ (defmacro unless (condition &body body) `(if ,condition nil (progn ,@body))) -(defmacro defvar (name value &optional docstring) +(defmacro defvar (name &optional (value nil value-p) docstring) `(progn (declaim (special ,name)) - (unless (boundp ',name) (setq ,name ,value)) + ,@(when value-p `((unless (boundp ',name) (setq ,name ,value)))) ,@(when (stringp docstring) `((oset ',name "vardoc" ,docstring))) ',name)) @@ -92,23 +92,15 @@ (defun boundp (x) (boundp x)) -;; Basic functions -(defun = (x y) (= x y)) -(defun * (x y) (* x y)) -(defun / (x y) (/ x y)) -(defun 1+ (x) (+ x 1)) -(defun 1- (x) (- x 1)) -(defun zerop (x) (= x 0)) - -(defun truncate (x &optional (y 1)) - (floor (/ x y))) +(defun fboundp (x) + (fboundp x)) +(defun eq (x y) (eq x y)) (defun eql (x y) (eq x y)) (defun not (x) (if x nil t)) ;; Basic macros - (defmacro incf (place &optional (delta 1)) (multiple-value-bind (dummies vals newval setter getter) (get-setf-expansion place) @@ -139,6 +131,21 @@ ,@(cdr newval)) ,setter)))) +(defmacro pushnew (x place &rest keys &key key test test-not) + (declare (ignore key test test-not)) + (multiple-value-bind (dummies vals newval setter getter) + (get-setf-expansion place) + (let ((g (gensym)) + (v (gensym))) + `(let* ((,g ,x) + ,@(mapcar #'list dummies vals) + ,@(cdr newval) + (,v ,getter)) + (if (member ,g ,v ,@keys) + ,v + (let ((,(car newval) (cons ,g ,getter))) + ,setter)))))) + (defmacro dolist ((var list &optional result) &body body) (let ((g!list (gensym))) (unless (symbolp var) (error "`~S' is not a symbol." var)) @@ -163,28 +170,35 @@ ,result)))) (defmacro cond (&rest clausules) - (if (null clausules) - nil - (if (eq (caar clausules) t) - `(progn ,@(cdar clausules)) - (let ((test-symbol (gensym))) - `(let ((,test-symbol ,(caar clausules))) - (if ,test-symbol - ,(if (null (cdar clausules)) - test-symbol - `(progn ,@(cdar clausules))) - (cond ,@(cdr clausules)))))))) + (unless (null clausules) + (destructuring-bind (condition &body body) + (first clausules) + (cond + ((eq condition t) + `(progn ,@body)) + ((null body) + (let ((test-symbol (gensym))) + `(let ((,test-symbol ,condition)) + (if ,test-symbol + ,test-symbol + (cond ,@(rest clausules)))))) + (t + `(if ,condition + (progn ,@body) + (cond ,@(rest clausules)))))))) (defmacro case (form &rest clausules) (let ((!form (gensym))) `(let ((,!form ,form)) (cond ,@(mapcar (lambda (clausule) - (if (or (eq (car clausule) t) - (eq (car clausule) 'otherwise)) - `(t ,@(cdr clausule)) - `((eql ,!form ',(car clausule)) - ,@(cdr clausule)))) + (destructuring-bind (keys &body body) + clausule + (if (or (eq keys 't) (eq keys 'otherwise)) + `(t nil ,@body) + (let ((keys (if (listp keys) keys (list keys)))) + `((or ,@(mapcar (lambda (key) `(eql ,!form ',key)) keys)) + nil ,@body))))) clausules))))) (defmacro ecase (form &rest clausules) @@ -238,18 +252,6 @@ ;;; Go on growing the Lisp language in Ecmalisp, with more high level ;;; utilities as well as correct versions of other constructions. -(defun + (&rest args) - (let ((r 0)) - (dolist (x args r) - (incf r x)))) - -(defun - (x &rest others) - (if (null others) - (- x) - (let ((r x)) - (dolist (y others r) - (decf r y))))) - (defun append-two (list1 list2) (if (null list1) list2 @@ -352,6 +354,10 @@ (defun identity (x) x) +(defun complement (x) + (lambda (&rest args) + (not (apply x args)))) + (defun constantly (x) (lambda (&rest args) x)) @@ -365,49 +371,15 @@ (defun char= (x y) (eql x y)) -(defun integerp (x) - (and (numberp x) (= (floor x) x))) - -(defun floatp (x) - (and (numberp x) (not (integerp x)))) - -(defun plusp (x) (< 0 x)) -(defun minusp (x) (< x 0)) +(defun char< (x y) + (< (char-code x) (char-code y))) (defun atom (x) (not (consp x))) -(defun remove (x list) - (cond - ((null list) - nil) - ((eql x (car list)) - (remove x (cdr list))) - (t - (cons (car list) (remove x (cdr list)))))) - -(defun remove-if (func list) - (cond - ((null list) - nil) - ((funcall func (car list)) - (remove-if func (cdr list))) - (t - ;; - (cons (car list) (remove-if func (cdr list)))))) - -(defun remove-if-not (func list) - (cond - ((null list) - nil) - ((funcall func (car list)) - (cons (car list) (remove-if-not func (cdr list)))) - (t - (remove-if-not func (cdr list))))) - (defun alpha-char-p (x) (or (<= (char-code #\a) (char-code x) (char-code #\z)) - (<= (char-code #\Z) (char-code x) (char-code #\Z)))) + (<= (char-code #\A) (char-code x) (char-code #\Z)))) (defun digit-char-p (x) (if (and (<= (char-code #\0) (char-code x) (char-code #\9))) @@ -418,59 +390,6 @@ (and (<= 0 weight 9) (char "0123456789" weight))) -(defun subseq (seq a &optional b) - (if b - (slice seq a b) - (slice seq a))) - -(defmacro do-sequence (iteration &body body) - (let ((seq (gensym)) - (index (gensym))) - `(let ((,seq ,(second iteration))) - (cond - ;; Strings - ((stringp ,seq) - (let ((,index 0)) - (dotimes (,index (length ,seq)) - (let ((,(first iteration) - (char ,seq ,index))) - ,@body)))) - ;; Lists - ((listp ,seq) - (dolist (,(first iteration) ,seq) - ,@body)) - (t - (error "type-error!")))))) - -(defun find (item sequence &key (key #'identity) (test #'eql)) - (do-sequence (x sequence) - (when (funcall test (funcall key x) item) - (return x)))) - -(defun find-if (predicate sequence &key (key #'identity)) - (do-sequence (x sequence) - (when (funcall predicate (funcall key x)) - (return x)))) - -(defun some (function seq) - (do-sequence (elt seq) - (when (funcall function elt) - (return-from some t)))) - -(defun every (function seq) - (do-sequence (elt seq) - (unless (funcall function elt) - (return-from every nil))) - t) - -(defun position (elt sequence) - (let ((pos 0)) - (do-sequence (x seq) - (when (eq elt x) - (return)) - (incf pos)) - pos)) - (defun equal (x y) (cond ((eql x y) t) @@ -618,4 +537,3 @@ (defun error (fmt &rest args) (%throw (apply #'format nil fmt args))) -