adding some ast functions
This commit is contained in:
parent
5bff23e790
commit
6ed023e966
|
@ -30,6 +30,42 @@
|
||||||
(let ((new-t (map (lambda (e) (maptree-post f e)) tr)))
|
(let ((new-t (map (lambda (e) (maptree-post f e)) tr)))
|
||||||
(f new-t))))
|
(f new-t))))
|
||||||
|
|
||||||
|
(define (foldtree-pre f t zero)
|
||||||
|
(if (not (pair? t))
|
||||||
|
(f t zero)
|
||||||
|
(foldl t (lambda (e state) (foldtree-pre f e state)) (f t zero))))
|
||||||
|
|
||||||
|
(define (foldtree-post f t zero)
|
||||||
|
(if (not (pair? t))
|
||||||
|
(f t zero)
|
||||||
|
(f t (foldl t (lambda (e state) (foldtree-post f e state)) zero))))
|
||||||
|
|
||||||
|
; general tree transformer
|
||||||
|
; folds in preorder (foldtree-pre), maps in postorder (maptree-post)
|
||||||
|
; therefore state changes occur immediately, just by looking at the current node,
|
||||||
|
; while transformation follows evaluation order. this seems to be the most natural
|
||||||
|
; approach.
|
||||||
|
; (mapper tree state) - should return transformed tree given current state
|
||||||
|
; (folder tree state) - should return new state
|
||||||
|
(define (map&fold t zero mapper folder)
|
||||||
|
(let ((head (and (pair? t) (car t))))
|
||||||
|
(cond ((eq? head 'quote)
|
||||||
|
t)
|
||||||
|
((or (eq? head 'the) (eq? head 'meta))
|
||||||
|
(list head
|
||||||
|
(cadr t)
|
||||||
|
(map&fold (caddr t) zero mapper folder)))
|
||||||
|
(else
|
||||||
|
(let ((new-s (folder t zero)))
|
||||||
|
(mapper
|
||||||
|
(if (pair? t)
|
||||||
|
; head symbol is a tag; never transform it
|
||||||
|
(cons (car t)
|
||||||
|
(map (lambda (e) (map&fold e new-s mapper folder))
|
||||||
|
(cdr t)))
|
||||||
|
t)
|
||||||
|
new-s))))))
|
||||||
|
|
||||||
; collapse forms like (&& (&& (&& (&& a b) c) d) e) to (&& a b c d e)
|
; collapse forms like (&& (&& (&& (&& a b) c) d) e) to (&& a b c d e)
|
||||||
(define (flatten-left-op op e)
|
(define (flatten-left-op op e)
|
||||||
(maptree-post (lambda (node)
|
(maptree-post (lambda (node)
|
||||||
|
@ -78,6 +114,27 @@
|
||||||
n))
|
n))
|
||||||
e))
|
e))
|
||||||
|
|
||||||
|
; alpha renaming
|
||||||
|
; transl is an assoc list ((old-sym-name . new-sym-name) ...)
|
||||||
|
(define (alpha-rename e transl)
|
||||||
|
(map&fold e
|
||||||
|
()
|
||||||
|
; mapper: replace symbol if unbound
|
||||||
|
(lambda (t env)
|
||||||
|
(if (symbol? t)
|
||||||
|
(let ((found (assq t transl)))
|
||||||
|
(if (and found
|
||||||
|
(not (memq t env)))
|
||||||
|
(cdr found)
|
||||||
|
t))
|
||||||
|
t))
|
||||||
|
; folder: add locals to environment if entering a new scope
|
||||||
|
(lambda (t env)
|
||||||
|
(if (and (pair? t) (or (eq? (car t) 'let)
|
||||||
|
(eq? (car t) 'lambda)))
|
||||||
|
(append (cadr t) env)
|
||||||
|
env))))
|
||||||
|
|
||||||
; flatten op with any associativity
|
; flatten op with any associativity
|
||||||
(defmacro flatten-all-op (op e)
|
(defmacro flatten-all-op (op e)
|
||||||
`(pattern-expand
|
`(pattern-expand
|
||||||
|
|
Loading…
Reference in New Issue