The power of Lists
Keith Wright
(15 Aug 2005 03:14 UTC)
|
Re: The power of Lists Jens Axel Søgaard (15 Aug 2005 20:43 UTC)
|
Re: The power of Lists
Keith Wright
(16 Aug 2005 04:16 UTC)
|
Re: The power of Lists
Michael Sperber
(16 Aug 2005 06:19 UTC)
|
Re: The power of Lists
Andre van Tonder
(19 Aug 2005 13:35 UTC)
|
Re: The power of Lists
Michael Sperber
(20 Aug 2005 07:00 UTC)
|
Re: The power of Lists
Andre van Tonder
(20 Aug 2005 15:28 UTC)
|
Re: The power of Lists
Andre van Tonder
(22 Aug 2005 14:30 UTC)
|
Hi Keith, > If it were done with some procedural macro system that represents > syntax as a special type, it could not have been tested on lists of > symbols, it would have been full of syntax->list and list->syntax > conversions in non-obvious places, and I just don't think it would > have been so much fun that I would have stayed up half the night > working on it, or finished it before morning. I liked your example so much I decided to put in the conversions. (define wall '#(wall)) ;; and end marker The first change is that the table isn't syntax, but a list. You defined the table as (define table (syntax ((:= . 8)(or . 7) (and . 6) (< . 5) (= . 4)(+ . 3)(* . 2)))) although it is only the identifiers are syntax-objects in this context. (Btw - that's an example of "breaking the abstraction") The assocations from identifiers to weights can be written directly as: (define table `((,#':= . 8) (,#'or . 7) (,#'and . 6) (,#'< . 5) (,#'= . 4) (,#'+ . 3) (,#'* . 2))) or if you prefer your way better, then the a syntax->list must be added, since table needs to be a list. (define table (syntax->list (syntax ((:= . 8)(or . 7) (and . 6) (< . 5) (= . 4)(+ . 3)(* . 2))))) These versions will work in both macro systems. The definitions of assoid and weight requires no changes. (define (assoid key == tab) (let look ((tab tab)) (if (null? tab) (begin (display (list key " not found in " table)) (newline) #f) (if (== key (caar tab)) (cdar tab) (look (cdr tab)))))) (define (weight op) (if (eq? op wall) 500 (assoid op free-identifier=? table))) The routine parse is changed to be a function which takes a list of syntax-objects representing sub-expressions as input. Since parse is recursive and calls it selv with a subexpression (which now is syntax-object) we let parse convert a syntax-objects representing lists into lists of syntax-objects automaticcally. I.e. the body of parse is changed from (get 10) into (if (syntax? tokens) (parse (syntax->list tokens)) (get 10)). Since your version uses list? and pair? to check whether a subexpression is a compound expression, we need stx-list? and stx-pair? when checking for compund subexpressions. (require (lib "stx.ss" "syntax")) ; for stx-list? and stx-pair? ; parse : (list stx) -> stx (define (parse tokens) ; this : -> stx (define (this) (if (null? tokens) wall (car tokens))) (define (next) (set! tokens (cdr tokens))) (define (get greed) (if (zero? greed) (let ((a (this))) (next) (if (stx-list? (this)) (let ((arg (this))) (next) (list a (parse arg))) (if (stx-pair? a) (parse a) a))) (let ((a (get (- greed 1)))) (let more ((a a) (op (this))) (if (< greed (weight op)) a (begin (next) (let ((b (get (- greed 1)))) (list op a (more b (this)))))))))) (if (syntax? tokens) (parse (syntax->list tokens)) (get 10))) ; parse just primes the pump (parse #'((1 + 2) * 3)) -- Jens Axel Søgaard