diff options
author | mRnea <[email protected]> | 2024-07-23 16:17:16 +0300 |
---|---|---|
committer | mRnea <[email protected]> | 2024-07-23 16:17:16 +0300 |
commit | 7fa561a9d9651f36de5aaf40a8faf533a5effc61 (patch) | |
tree | 627a100732f682ae5ab66043554f6dbea49587e4 | |
parent | 1732b9a1a137d8a7e6476e8cdfa254c01638bce3 (diff) |
added op-case and some conditions for it (error checking)
-rw-r--r-- | cl-forth.lisp | 105 |
1 files changed, 84 insertions, 21 deletions
diff --git a/cl-forth.lisp b/cl-forth.lisp index 565e1f5..14b6573 100644 --- a/cl-forth.lisp +++ b/cl-forth.lisp @@ -1,9 +1,10 @@ (in-package :cl-forth) -(defparameter *identifiers* '(+ - |.| =)) - -(defun is-identifier (sym) - (find sym *identifiers*)) +(eval-always + (defparameter *identifiers* + '(+ - |.| = ise yoksa yap eş push değiş üst rot düş)) + (defun is-identifier (sym) + (find sym *identifiers*))) (defun make-token (sym? line col) (if (or (is-identifier sym?) (numberp sym?)) @@ -13,8 +14,9 @@ (defun token-op (token) (car token)) -(defun lex-line (line-stream line-num) - (iter (with col = 0) +(defun lex-line (line &optional (line-num 0)) + (iter (with line-stream = (make-string-input-stream line)) + (with col = 0) (with has-err = nil) (for next-char = (peek-char nil line-stream nil nil)) (until (null next-char)) @@ -49,7 +51,7 @@ (until (null line)) (for line-num from 1) (multiple-value-bind (tokens has-err) - (lex-line (make-string-input-stream line) line-num) + (lex-line line line-num) (when has-err (setf has-error t) (when report-errors @@ -77,6 +79,11 @@ (let ((op (token-op token))) (cond ((numberp op) (vector-push-extend `(push ,op) ops)) + ((eq 'ise op) + (vector-push-extend + `(ise ,(position 'yap tokens :start i :key #'token-op)) + ops)) + ;; currently does not handle nesting (t (vector-push-extend (list op) ops)))) (finally (return ops)))) @@ -88,23 +95,79 @@ (parse-tokens tokens))) ;; (defun *ops* '(push pop minus dump)) +(define-condition op-not-implemented (style-warning) + ((undef-ops :initarg :ops :reader undef-ops)) + (:report (lambda (condition stream) + (format stream "These ops are not defined in op-case: ~s" + (undef-ops condition))))) + +(defun identifier-coverage (defined-ops) + (let ((undef-ops (set-difference *identifiers* defined-ops))) + (unless (null undef-ops) + (warn (make-condition 'op-not-implemented :ops undef-ops))))) + +(defmacro op-case (case-form &body body) + (iter (for (op-id) in body) + (when (not (is-identifier op-id)) + (error "op-case: ~a is not an identifier" op-id)) + (collect op-id into defined-ops) + (finally (identifier-coverage defined-ops))) + (let ((case-sym (gensym))) + `(let ((,case-sym ,case-form)) + (case ,case-sym + ,@body + (otherwise (if (is-identifier (first ,case-sym)) + (error "op: ~a -- Not implemented yet" + (first ,case-sym)) + (error "op: ~a -- Does not exist" + (first ,case-sym)))))))) (defun interpret-program (program) (iter (with stack = (make-array 100 :fill-pointer 0 :adjustable t)) - (for op in-sequence program) - (case (first op) - (push (vector-push-extend (second op) stack)) - (+ (vector-push-extend (+ (vector-pop stack) - (vector-pop stack)) - stack)) - (- (vector-push-extend (let ((top (vector-pop stack))) - (- (vector-pop stack) top)) - stack)) - (|.| (print (vector-pop stack))) - (= (vector-push-extend (= (vector-pop stack) - (vector-pop stack)) - stack)) - (otherwise (error "op: ~a -- Not implemented yet" (first op)))))) + ;; (for op in-sequence program) + (for i from 0 below (length program)) + (let ((op (aref program i))) + (op-case (first op) + (push (vector-push-extend (second op) stack)) + (+ (vector-push-extend (+ (vector-pop stack) + (vector-pop stack)) + stack)) + (- (vector-push-extend (let ((top (vector-pop stack))) + (- (vector-pop stack) top)) + stack)) + (|.| (print (vector-pop stack))) + (= (vector-push-extend (if (= (vector-pop stack) + (vector-pop stack)) + 1 0) + stack)) + (yap (next-iteration)) + (ise (if (= (vector-pop stack) 1) + nil + (setf i (second op)))) + (eş (let ((top (vector-pop stack))) + (vector-push-extend top stack) + (vector-push-extend top stack))) + (değiş (let* ((fst (vector-pop stack)) + (snd (vector-pop stack))) + (vector-push-extend fst stack) + (vector-push-extend snd stack))) + (düş (vector-pop stack)) + (üst (let* ((fst (vector-pop stack)) + (snd (vector-pop stack))) + (vector-push-extend snd stack) + (vector-push-extend fst stack) + (vector-push-extend snd stack))) + (rot (let* ((fst (vector-pop stack)) + (snd (vector-pop stack)) + (trd (vector-pop stack))) + (vector-push-extend snd stack) + (vector-push-extend fst stack) + (vector-push-extend trd stack))))))) +;; swap, değiş +;; dup, eş +;; over, üst +;; rot, rot +;; drop, düşür (defun gen-header (op str) (format str " ;; -- ~s --~%" op)) |