diff options
author | mRnea <akannemre@gmail.com> | 2024-08-03 19:34:43 +0300 |
---|---|---|
committer | mRnea <akannemre@gmail.com> | 2024-08-03 19:34:43 +0300 |
commit | 2cbb10fc6b1daacfc331880ef39245307e976b1d (patch) | |
tree | 593c37fa03c17ce6ac49653fd4c198355804b575 | |
parent | 724519dad14aeb62571866923c46bf47d5963d02 (diff) |
Added string literals
-rw-r--r-- | README.org | 17 | ||||
-rw-r--r-- | assembly.lisp | 29 | ||||
-rw-r--r-- | cl-forth.lisp | 23 |
3 files changed, 57 insertions, 12 deletions
@@ -5,11 +5,18 @@ Tsoding'in Porth (Forth in Python) serisinden esinlenme. [[https://www.youtube.com/playlist?list=PLpM-Dvs8t0VbMZA7wW9aR3EtBqe2kinu4][Porth playlist]] [[https://gitlab.com/tsoding/porth][gitlab]] +* Kurulum + +* Örnekler + * Yol Haritası -koşullu dallanma (if) -döngüler ++ koşullu dallanma (if) ++ döngüler fonksiyon tanımı -string literal ++ string literal +static typing (belki) +windows ve macos desteği + +* Kaynak +[[https://concatenative.org/wiki/][Concatenative languages]] -* readme TODO -örnek ekle vb. diff --git a/assembly.lisp b/assembly.lisp index e872ee8..c1efe45 100644 --- a/assembly.lisp +++ b/assembly.lisp @@ -127,9 +127,14 @@ ;;; Hopefully these two are done, need testing... ;; ( -- a) -(defop (push a) (:lex nil) +(defop (push-int a) (:lex nil) ("push ~d" a)) +(defop (push-str len addr str) (:lex nil) + (progn (:write ("push ~d" len) + ("push str_~d" addr)) + (list :string addr str))) + (defop + () (rbx rax -- (:add rax rbx))) @@ -236,14 +241,28 @@ (:write ("pop ~a" (aref call-regs i))) (finally (:write "syscall")))) +(defun comment-safe-str (str) + "Handle newlines for asm comment" + (with-output-to-string (new-str) + (iter (for ch in-string str with-index i) + (cond ((> i 10) + (princ "..." new-str) + (finish)) + ((char= #\Newline ch) + (princ "\\n" new-str)) + (t (write-char ch new-str)))))) + (defun gen-header (op str) - (format str " ;; -- ~s --~%" op)) + (format str " ;; -- ~s --~%" + (mapcar (lambda (x) (if (stringp x) (comment-safe-str x) x)) + op))) (defun gen-code (op str) (let ((op-fn (gethash (string (car op)) *operations*))) - (if (null op-fn) - (error "~s is not a valid op" op) - (apply op-fn str (cdr op))))) + (when (null op-fn) + (error "~s is not a valid op" op)) + (gen-header op str) + (apply op-fn str (cdr op)))) (defun gen-dump (str) (format str "~{~a~%~}" diff --git a/cl-forth.lisp b/cl-forth.lisp index 7cee812..d935956 100644 --- a/cl-forth.lisp +++ b/cl-forth.lisp @@ -1,7 +1,7 @@ (in-package :cl-forth) (defun make-token (sym? line col) - (if (or (numberp sym?) (is-identifier sym?)) + (if (or (numberp sym?) (stringp sym?) (is-identifier sym?)) (values (list sym? :line line :col col) nil) (values (list sym? :line line :col col :error t) t))) @@ -9,6 +9,17 @@ (car token)) ;;; LEXER +(defun read-string (stream) + ;; TODO: Handle unmatched " and give proper error message + (with-output-to-string (str) + (iter (for ch = (read-char stream)) + (cond ((char= ch #\") + (finish)) + ((and (char= ch #\\) (char= (peek-char nil stream) #\n)) + (read-char stream) + (write-char #\Newline str)) + (t (write-char ch str)))))) + (defun lex-line (line &optional (line-num 0)) (iter (with line-stream = (make-string-input-stream line)) (with col = 0) @@ -25,6 +36,11 @@ ((char= #\Space next-char) (read-char line-stream)) ((char= #\; next-char) ;; and not in string (finish)) + ((char= #\" next-char) + (read-char line-stream) + (collect (make-token (read-string line-stream) + line-num col) + into tokens)) (t (setf flag nil))) (when flag (incf col) @@ -95,7 +111,10 @@ (for token in tokens) (let ((op (token-op token))) (cond ((numberp op) - (vector-push-extend `(push ,op) ops)) + (vector-push-extend `(push-int ,op) ops)) + ((stringp op) + (vector-push-extend `(push-str ,(length op) ,i ,op) + ops)) ((string= 'ise op) (push (list 'ise i) stack) (vector-push-extend (list 'ise nil) ops)) |