#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) (<= n 57)))) (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) (or (iswordchar? ch) (isdigit? ch)) (let ((restword (take-while isrestwordchar? rest)) (rest2 (substr (length restword) -1 rest))) (if (and (all isdigit? restword) (or (isdigit? ch) (and (= ch "-") (> (length restword) 0)))) (list (parse-int (concat ch restword)) rest2) (list (concat ch restword) rest2))) (error (concat "Invalid token: " ch))))) (define go (lambdarec rec (str) (let ((pair (next-token str))) (if (null? pair) '() (let ((token (car pair)) (rest (cadr pair))) (do (print token) (rec rest))))))) (go (read-file "tests/closuretest.lisp"))