X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=ecmalisp.lisp;h=cb89dfc00a43213f12029305a49d9f4663ddfb77;hb=04eb2ffe0a6043e3d1f979088f4ca90463b07b79;hp=28f34277365886081d3b540364ef9c30e4b6266e;hpb=b8e4b54644d537d32a07e8570672d11728379f8d;p=jscl.git diff --git a/ecmalisp.lisp b/ecmalisp.lisp index 28f3427..cb89dfc 100644 --- a/ecmalisp.lisp +++ b/ecmalisp.lisp @@ -26,15 +26,17 @@ (progn (eval-when-compile (%compile-defmacro 'defmacro - '(lambda (name args &rest body) - `(eval-when-compile - (%compile-defmacro ',name - '(lambda ,(mapcar (lambda (x) - (if (eq x '&body) - '&rest - x)) - args) - ,@body)))))) + '(function + (lambda (name args &rest body) + `(eval-when-compile + (%compile-defmacro ',name + '(function + (lambda ,(mapcar #'(lambda (x) + (if (eq x '&body) + '&rest + x)) + args) + ,@body)))))))) (defmacro declaim (&rest decls) `(eval-when-compile @@ -45,6 +47,9 @@ (js-vset "nil" nil) (setq t 't) + (defmacro lambda (args &body body) + `(function (lambda ,args ,@body))) + (defmacro when (condition &body body) `(if ,condition (progn ,@body) nil)) @@ -296,6 +301,34 @@ `(let ,(mapcar #'cdr assignments) (setq ,@(!reduce #'append (mapcar #'butlast assignments) '()))))) + (defmacro do (varlist endlist &body body) + `(block nil + (let ,(mapcar (lambda (x) (list (first x) (second x))) varlist) + (while t + (when ,(car endlist) + (return (progn ,(cdr endlist)))) + (tagbody ,@body) + (psetq + ,@(apply #'append + (mapcar (lambda (v) + (and (consp (cddr v)) + (list (first v) (third v)))) + varlist))))))) + + (defmacro do* (varlist endlist &body body) + `(block nil + (let* ,(mapcar (lambda (x) (list (first x) (second x))) varlist) + (while t + (when ,(car endlist) + (return (progn ,(cdr endlist)))) + (tagbody ,@body) + (setq + ,@(apply #'append + (mapcar (lambda (v) + (and (consp (cddr v)) + (list (first v) (third v)))) + varlist))))))) + (defun list-length (list) (let ((l 0)) (while (not (null list)) @@ -618,11 +651,6 @@ (defun concat-two (s1 s2) (concatenate 'string s1 s2)) - (defun setcar (cons new) - (setf (car cons) new)) - (defun setcdr (cons new) - (setf (cdr cons) new)) - (defun aset (array idx value) (setf (aref array idx) value))) @@ -816,7 +844,7 @@ (defun %read-char (stream) (and (< (cdr stream) (length (car stream))) (prog1 (char (car stream) (cdr stream)) - (setcdr stream (1+ (cdr stream)))))) + (rplacd stream (1+ (cdr stream)))))) (defun whitespacep (ch) (or (char= ch #\space) (char= ch #\newline) (char= ch #\tab))) @@ -1005,10 +1033,10 @@ (defun binding-declarations (b) (fourth b)) (defun set-binding-value (b value) - (setcar (cddr b) value)) + (rplaca (cddr b) value)) (defun set-binding-declarations (b value) - (setcar (cdddr b) value)) + (rplaca (cdddr b) value)) (defun push-binding-declaration (decl b) (set-binding-declarations b (cons decl (binding-declarations b)))) @@ -1022,10 +1050,10 @@ (defun push-to-lexenv (binding lexenv namespace) (ecase namespace - (variable (setcar lexenv (cons binding (car lexenv)))) - (function (setcar (cdr lexenv) (cons binding (cadr lexenv)))) - (block (setcar (cddr lexenv) (cons binding (caddr lexenv)))) - (gotag (setcar (cdddr lexenv) (cons binding (cadddr lexenv)))))) + (variable (rplaca lexenv (cons binding (car lexenv)))) + (function (rplaca (cdr lexenv) (cons binding (cadr lexenv)))) + (block (rplaca (cddr lexenv) (cons binding (caddr lexenv)))) + (gotag (rplaca (cdddr lexenv) (cons binding (cadddr lexenv)))))) (defun extend-lexenv (bindings lexenv namespace) (let ((env (copy-lexenv lexenv))) @@ -1051,7 +1079,7 @@ (defun extend-local-env (args) (let ((new (copy-lexenv *environment*))) (dolist (symbol args new) - (let ((b (make-binding symbol 'lexical-variable (gvarname symbol)))) + (let ((b (make-binding symbol 'variable (gvarname symbol)))) (push-to-lexenv b new 'variable))))) ;;; Toplevel compilations @@ -1165,7 +1193,7 @@ (concat "checkArgsAtMost(arguments, " (integer-to-string max) ");" *newline*) ""))))) -(define-compilation lambda (lambda-list &rest body) +(defun compile-lambda (lambda-list body) (let ((required-arguments (lambda-list-required-arguments lambda-list)) (optional-arguments (lambda-list-optional-arguments lambda-list)) (rest-argument (lambda-list-rest-argument lambda-list)) @@ -1234,7 +1262,9 @@ (defun setq-pair (var val) (let ((b (lookup-in-lexenv var *environment* 'variable))) - (if (eq (binding-type b) 'lexical-variable) + (if (and (eq (binding-type b) 'variable) + (not (member 'special (binding-declarations b))) + (not (member 'constant (binding-declarations b)))) (concat (binding-value b) " = " (ls-compile val)) (ls-compile `(set ',var ,val))))) @@ -1336,7 +1366,7 @@ (define-compilation function (x) (cond ((and (listp x) (eq (car x) 'lambda)) - (ls-compile x)) + (compile-lambda (cadr x) (cddr x))) ((symbolp x) (ls-compile `(symbol-function ',x))))) @@ -1410,7 +1440,7 @@ ;;; Return the code to initialize BINDING, and push it extending the -;;; current lexical environment if the variable is special. +;;; current lexical environment if the variable is not special. (defun let*-initialize-value (binding) (let ((var (first binding)) (value (second binding))) @@ -1815,13 +1845,13 @@ (ls-compile nil) ": tmp.cdr;" *newline*)) -(define-builtin setcar (x new) +(define-builtin rplaca (x new) (type-check (("x" "object" x)) - (concat "(x.car = " new ")"))) + (concat "(x.car = " new ", x)"))) -(define-builtin setcdr (x new) +(define-builtin rplacd (x new) (type-check (("x" "object" x)) - (concat "(x.cdr = " new ")"))) + (concat "(x.cdr = " new ", x)"))) (define-builtin symbolp (x) (js!bool @@ -2118,20 +2148,20 @@ boundp butlast caar cadddr caddr cadr car car case catch cdar cdddr cddr cdr cdr char char-code char= code-char cond cons consp copy-list decf declaim defparameter defun defmacro defvar digit-char-p - disassemble documentation dolist dotimes ecase eq eql equal error eval - every export fdefinition find-package find-symbol first fourth fset - funcall function functionp gensym get-universal-time go identity if - in-package incf integerp integerp intern keywordp lambda last length - let let* list-all-packages list listp make-array make-package - make-symbol mapcar member minusp mod multiple-value-bind + disassemble do do* documentation dolist dotimes ecase eq eql equal + error eval every export fdefinition find-package find-symbol first + fourth fset funcall function functionp gensym get-universal-time go + identity if in-package incf integerp integerp intern keywordp lambda + last length let let* list-all-packages list listp make-array + make-package make-symbol mapcar member minusp mod multiple-value-bind multiple-value-call multiple-value-list multiple-value-prog1 nil not nth nthcdr null numberp or package-name package-use-list packagep plusp prin1-to-string print proclaim prog1 prog2 progn psetq push quote remove remove-if remove-if-not return return-from revappend - reverse second set setq some string-upcase string string= stringp - subseq symbol-function symbol-name symbol-package symbol-plist - symbol-value symbolp t tagbody third throw truncate unless - unwind-protect values values-list variable warn when write-line + reverse rplaca rplacd second set setq some string-upcase string + string= stringp subseq symbol-function symbol-name symbol-package + symbol-plist symbol-value symbolp t tagbody third throw truncate + unless unwind-protect values values-list variable warn when write-line write-string zerop)) (setq *package* *user-package*)