summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2019-11-21 23:24:15 +0100
committerTom Smeding <tom.smeding@gmail.com>2019-11-21 23:24:15 +0100
commit7486de914e5a797017129f432490b8c235364659 (patch)
treeb0e8ab100959e8ce0d27ceff75ac1959fe83f590
parentfcc4ad30957dc1663a07fe3ad37e937d7466e860 (diff)
WIP lisp parser in lisp
-rw-r--r--tests/lispparser.lisp61
1 files changed, 61 insertions, 0 deletions
diff --git a/tests/lispparser.lisp b/tests/lispparser.lisp
new file mode 100644
index 0000000..4579b93
--- /dev/null
+++ b/tests/lispparser.lisp
@@ -0,0 +1,61 @@
+#include "stdlib.lisp"
+
+(define str-elem (ch str)
+ (if (= str "") 0
+ (if (= ch (substr 0 1 str)) 1
+ (str-elem ch (substr 1 -1 str)))))
+
+(define isspace? (ch)
+ (str-elem ch " \n\t\r"))
+
+(define isdigit? (ch)
+ (let ((n (ord ch))) (and (<= 48 n) (<= 57 n))))
+
+(define lowercase? (ch)
+ (let ((n (ord ch))) (and (<= 97 n) (<= n 122))))
+
+(define uppercase? (ch)
+ (let ((n (ord ch))) (and (<= 65 n) (<= n 90))))
+
+(define iswordchar? (ch)
+ (or (str-elem ch "-_?")
+ (or (lowercase? ch) (uppercase? ch))))
+
+(define isrestwordchar? (ch)
+ (or (iswordchar? ch) (isdigit? ch)))
+
+(define parse-int (str)
+ (let ((helper (lambdarec rec (str n)
+ (let ((ch (substr 0 1 str))
+ (rest (substr 1 -1 str)))
+ (if (isdigit? ch)
+ (rec rest (+ (* 10 n) (- (ord ch) 48)))
+ n)))))
+ (helper str 0)))
+
+(define next-token (str)
+ (let ((ch (substr 0 1 str))
+ (rest (substr 1 -1 str)))
+ (cond
+ (= ch "")
+ '()
+ (isspace? ch)
+ (next-token rest)
+ (= ch ";")
+ (next-token (drop-while (lambda (c) (not (= c "\n"))) rest))
+ (= ch "(")
+ (list "(" rest)
+ (= ch ")")
+ (list ")" rest)
+ (iswordchar? ch)
+ (let ((restword (take-while isrestwordchar? rest)))
+ (list (concat ch restword) (substr (length restword) -1 rest)))
+ (isdigit? ch)
+ (let ((word (concat ch (take-while isdigit? rest))))
+ (list (parse-int word) (substr (length word) -1 str)))
+ (do
+ (print (concat "Invalid token: " ch))
+ (exit)))))
+
+; (define parse-sexpr (tokens)
+; ...)