From 7486de914e5a797017129f432490b8c235364659 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Thu, 21 Nov 2019 23:24:15 +0100 Subject: WIP lisp parser in lisp --- tests/lispparser.lisp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/lispparser.lisp 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) +; ...) -- cgit v1.2.3-54-g00ecf