Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
;; Version 1: ;; A simple evaluator, without tracing info (defun *eval-expr (expr) (cond ((or (numberp expr) (stringp expr) (eq nil expr) (eq t expr)) expr) ((symbolp expr) (*eval-varexpr expr)) ((listp expr) (*eval-listexpr expr)) (t (error "I don't know how to *eval-expr %S" expr)))) (defun *eval-varexpr (expr) (symbol-value expr)) (defun *eval-exprs (exprs) (if exprs (let* ((head (car exprs)) (rest (cdr exprs))) (cons (*eval-expr head) (*eval-exprs rest))))) (defun *eval-listexpr (expr) (let* ((head (car expr)) (rest (cdr expr))) (apply head (*eval-exprs rest)))) ;; Some tests ' (let ((a 2)) (*eval-expr 'a)) ' (let ((a 1) (b 2) (c 3) (d 4)) (*eval-expr '(* (+ a b) (+ c d)))) ;; Version 2: ;; The same, but with tracing info ;; Trace functions (defvar *object nil) (defun *show () (insert (format "\n%S" *object))) (defun *setcar (cell-up newcar) (cond ((null cell-up)) ((listp cell-up) (setcar cell-up newcar)) ((symbolp cell-up) (set cell-up newcar))) newcar) (defun *setcdr (cell-left newcdr) (cond ((null cell-left)) ((listp cell-left) (setcdr cell-left newcar)) ((symbolp cell-left) (set cell-left newcar))) newcdr) (defun *add-mark-horizontal (cell-left cell-right) (let ((cell-temp (cons '_ cell-right))) (*setcdr cell-left cell-temp) cell-temp)) (defun *remove-mark-horizontal (cell-left cell-right) (*setcdr cell-left cell-right)) (defun *add-mark-vertical (cell-up cell-down) (let ((cell-temp (cons '_ cell-down))) (*setcar cell-up cell-temp) cell-temp)) (defun *remove-mark-vertical (cell-up cell-down) (*setcar cell-up cell-down))) ;; (defun **eval-exprs (cell-left exprs) (*add-mark-horizontal cell-left exprs) (*show) (if exprs (progn (**eval-expr (*remove-mark-horizontal cell-left exprs) (null exprs) (let ((expr (car exprs)) (rest (cdr exprs))) (*setcdr cell-left (cons (*eval-expr expr (*setcdr cell-left (cons (*eval-expr (**setcdr cell-left (cons '_ exprs)) (**show) (**setcdr cell-left (if exprs (let* ((head (car exprs)) (rest (cdr exprs))) (cons (**eval-expr head) (**eval-exprs rest))))) (defun *eval-exprs (expr (*setcar parent (cons '_ expr)) ;; em *eval-listexpr (defun *eval-listexpr (expr &optional cell-up) (let ((head (car expr)) (rest (cdr expr))) (*setcar cell-up (cons '_ expr)) (*show) (setq *object '(* (+ 1 2) (+ 3 4))) (*eval-listexpr *object '*object) (if cell-up (setcar cell-up newcar))) (defun *setcdr (cell-left newcdr) (if cell-up (setcar cell-up newcar))) ( (*setcdr cell-left (*setcdr cell-left (cons result (cons _ (+ 1 2) _ (_ + 1 2) _ (+ _ 1 2) _ (+ 1 _ 2) _ (+ 1 _ 2) (* (+ 1 2) (+ 3 4)) (_ * (+ 1 2) (+ 3 4)) (* _ (+ 1 2) (+ 3 4)) (* _ (_ + 1 2) (+ 3 4)) (* _ (+ _ 1 2) (+ 3 4)) (* _ (+ 1 _ 2) (+ 3 4)) (* _ (+ 1 2 _) (+ 3 4)) (* 3 _ (+ 3 4)) (* 3 _ (_ + 3 4)) (* 3 _ (+ _ 3 4)) (* 3 _ (+ 3 _ 4)) (* 3 _ (+ 3 4 _)) (* 3 7 _) 21 (_ square (+ 1 2)) (_ (lambda (x) (* x x)) (+ 1 2)) ((lambda (x) (* x x)) _ (+ 1 2)) ((lambda (x) (* x x)) _ (_ + 1 2)) ((lambda (x) (* x x)) _ (+ _ 1 2)) ((lambda (x) (* x x)) _ (+ 1 _ 2)) ((lambda (x) (* x x)) _ (+ 1 2 _)) ((lambda (x) (* x x)) 3 _) (let ((x 3)) _ (* x x)) (let ((x 3)) _ (_ * x x)) (let ((x 3)) _ (* _ x x)) (let ((x 3)) _ (* 3 _ x)) (let ((x 3)) _ (* 3 3 _)) (let ((x 3)) 9 _) 9 contexto como bloquinhos outros modos: substituição de variáveis livres comparação com lambda-cálculo # (find-node "(/usr/share/info/elisp)Sequence Functions") ;; Local Variables: ;; coding: raw-text-unix ;; ee-delimiter-hash: "\n#*\n" ;; ee-delimiter-percent: "\n%*\n" ;; ee-anchor-format: "«%s»" ;; ee-comment-prefix: ";;" ;; modes: (emacs-lisp-mode fundamental-mode) ;; End: