2010-m1s1-compilation/implementation/divers.lisp
2010-11-22 03:10:55 +01:00

98 lines
2.7 KiB
Common Lisp

;; variables "locales" : documentation
(defvar documentation '(function variable struct)) ;; TODO
;; TODO : décider de quelles "primitives" on a besoin.
;; "Primitives" :
;; - (%asm in-values out-values clobber-registers instructions)
;; - (%eval expr env)
;; - (%push-new-env "description")
;; - (%add-top-level-fun-binding name value)
;; - (%add-top-level-var-binding name value)
;; - (%add-fun-binding name value)
;; - (%add-var-binding name value)
;; - (%ref-fun name)
;; Les ref-xxx renvoient un bout de code ASM comme ci-dessous :
;; - Pour une valeur dans la pile :
;; (%asm () (r0) (r0) "load X(sp) r0;")
;; où X est la position dans la pile de name
;; - Pour une valeur dans le top-level :
;; (%asm () (r0) (r0) "load X(bp) r0;")
;; - Pour une valeur dans le tas (si on en a un)
;; (%asm () (r0) (r0) "load X r0;")
(defmacro defun (name args &rest body)
(let ((has-docstring
(and (stringp (car body))
(cdr body))))
`(progn
(when ,has-docstring
(push (car body) documentation)) ;; TODO
(%top-level-fun-bind
,name
(lambda ,args
,@(if has-docstring
(cdr body)
body))))))
(defmacro setf (place value)
(cond ((eq (car place) 'car)
`(%set-car ,place ,value))
((eq (car place) 'cdr)
`(%set-cdr ,place ,value))
;; TODO
(t (error 'setf-invalid-place "setf : invalid place ~a" place))))
(defmacro cond (&rest conditions)
(if (atom conditions)
nil
`(if ,(caar conditions)
,(if (atom (cdr (cdar conditions))) ;; Si une seule instruction dans la partie droite
(car (cdar conditions)) ;; On la met telle qu'elle
'(progn ,@(cdar conditions))) ;; Sinon, on met un progn autour.
(cond ,@(cdr conditions)))))
(defmacro car (list)
(%asm )) ;; TODO : list dans rX, résultat dans rY => move [indirect rX], rY
(defmacro cdr (list)
(%asm )) ;; TODO : list dans rX, résultat dans rY => move rX, rY; incr rY; move [indirect rY], rY;
(defmacro let (bindings &rest body)
`((lambda ,(mapcar #'car bindings)
,@body)
,@(mapcar #'cadr bindings)))
(defmacro let* (bindings &rest body)
(if (endp bindings)
`(progn ,@body)
`(let (,(car bindings))
(let* ,(cdr bindings)
,@body))))
(defmacro labels (f-bindings &rest body)
;; TODO
)
(defmacro funcall (function &rest args)
;; TODO
)
(defmacro apply (function &rest args)
;; TODO
;; (last args) est la liste des arguments, les précédents sont des arguments "fixes".
)
(defun mapcar (fun &rest lists)
(if (atom list)
nil
(cons (if (atom (cdr lists))
(apply fun (caar lists))
(apply fun (mapcar #'car lists))
(mapcar fun (mapcar #'cdr lists))))))
(defun last (list)
(if (atom (cdr list))
list
(last (cdr list))))