code accumulator

Oct 02, 2007 15:11

В копилку scheme-кода: написал макрос для одного товарища с лора, который генерит код из строки (http://www.linux.org.ru/view-message.jsp?msgid=2175324):

#;49> (execve->lisp "{+ 3 4 {- 10 2} 7}")
22

#;50> (execve->lisp "{define f {lambda {x} {* x 2}}}")
#;51> (f 4)
8

Обожаю схему, просто приятно писать программы :)



(require 'regex)

(define-macro (execve->lisp expr)
(car (parse-list expr)))

(define parse-list
(lambda (terms-list)
(parse-list-ready (skip-leading-whitespaces terms-list))))

(define skip-leading-whitespaces
(lambda (string) (string-substitute "^\\s+" "" string)))

(define parse-list-ready
(lambda (terms-list)
(if (zero? (string-length terms-list))
'()
(let ((first-term-proc (extract-first-term terms-list)))
(first-term-proc
(lambda (first-term rest-terms)
(cons first-term (parse-list rest-terms))))))))

(define extract-first-term
(lambda (terms-list)
(if (char=? #\{ (string-ref terms-list 0))
(extract-function terms-list)
(extract-term terms-list))))

(define extract-function
(lambda (terms-list)
(let ((function-end-index (search-closing-paren terms-list 1)))
(lambda (proc)
(proc (parse-list (string-copy terms-list
1
(- function-end-index 1)))
(string-copy terms-list
function-end-index
(string-length terms-list)))))))

(define search-closing-paren
(lambda (string index)
(search-closing-paren-count string index 1)))

(define search-closing-paren-count
(lambda (string index count)
(if (zero? count)
index
(let ((current (string-ref string index)))
(search-closing-paren-count
string
(+ index 1)
(cond
((char=? #\{ current) (+ count 1))
((char=? #\} current) (- count 1))
(else count)))))))

(define extract-term
(lambda (terms-list)
(let ((term-match (string-match "^(\\S+).*" terms-list)))
(lambda (proc)
(proc (string->scheme (cadr term-match))
(string-substitute "^(\\S+)"
""
terms-list))))))

(define string->scheme
(lambda (string)
(if (string-match "^\\d+$" string)
(string->number string)
(string->symbol string))))

lor, code, scheme

Previous post Next post
Up