diff --git a/forge/forge.lisp b/forge/forge.lisp index a771aac..e7e1eca 100644 --- a/forge/forge.lisp +++ b/forge/forge.lisp @@ -51,13 +51,14 @@ (defclass forge-env () ((data-stack :initform nil :accessor data-stack) - (words :initform (make-hash-table)) + (words :initform (make-hash-table :test #'eq)) (comp-words :initform (make-hash-table)) + (words-rev :initform (make-hash-table)) + (words-meta :initform (make-hash-table)) (packages :initform '(:sf-user :sf-builtin)) (current-package :initform :sf-builtin) - (rp :initform (make-iseq)) - (cp :initform (make-iseq)) - (ip :initform (make-iseq)))) + (ip :initform (make-iseq)) + (rp) (cp))) (defun forge-env () (make-instance 'forge-env)) @@ -75,13 +76,16 @@ (defun comp-words () (slot-value *forge-env* 'comp-words)) -(defun register-comp-word (sym fn) - (register sym fn 'comp-words)) +(defun register-comp-word (sym fn &key code) + (register sym fn :slot 'comp-words :code code)) -(defun register (sym fn &optional (slot 'words)) +(defun register (sym fn &key (slot 'words) code) (let* ((w (intern (string sym) (current-package))) (words (slot-value *forge-env* slot))) - (setf (gethash w words) fn))) + (setf (gethash w words) fn) + (setf (gethash fn (slot-value *forge-env* 'words-rev)) w) + (if code + (setf (gethash w (slot-value *forge-env* 'words-meta)) code)))) ;;; builtins @@ -95,12 +99,12 @@ (defun do-reg () (let* ((name (popd)) (code (popd))) - (register name #'(lambda () (call code))))) + (register name #'(lambda () (call code)) :code code))) (defun do-regc () (let* ((name (popd)) (code (popd))) - (register-comp-word name #'(lambda () (call code))))) + (register-comp-word name #'(lambda () (call code)) :code code))) (defun do-quote () (comp-item #'lit) (comp-item (read-next))) @@ -131,6 +135,13 @@ ;;; compiler, interpreter +(defun do-trace (code) + (format t "~%~a" + (mapcar + #'(lambda (f) + (or (gethash f (slot-value *forge-env* 'words-rev)) f)) + code))) + (defun exec-str (s) (exec (read-from-string (concatenate 'string "(" s ")")))) @@ -144,7 +155,7 @@ (call (comp code))) (defun call (code) - #+forge-trace (print code) + #+forge-trace (do-trace code) (let ((old-ip (fip)) (ip (make-iseq code))) (setf (slot-value *forge-env* 'ip) ip)