[racket] Compiler for despair 1
Do you have a link to a complete reference of this language? I
couldn't find it with Google.
Some ideas to gain a few lines:
** Replace the ":" operator with "#%app"
(http://docs.racket-lang.org/reference/application.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._~23~25app%29%29
)
In file pref.rkt replace
Line 14:
- [(:) 7]
+ [(#%app) 7]
Line 31:
- (p (cons ': e) o a)]
+ (p (cons '#%app e) o a)]
And now you can simplify "f" to
(define-for-syntax (f c y x r)
(cons (list c y x) r)))
Or perhaps inline it.
If the ":" may appear explicitly in the source code, you must add a
line in despair.rkt to replace ":" by "#%app".
** Rewrite w? with another implicit lambda:
(define-for-syntax ((w? e) x)
(> (w (car e))(w x)))
(I prefer the name "w>?".)
** Rewrite pre:
(define-for-syntax(pre x)
(if (not (pair? x)) x
(p (cdr x) '()
(list (pre (car x))) ))))
(This is almost cheating and is a bad code style, but you can gain 1 LOC.)
Gustavo
On Fri, Oct 31, 2014 at 11:47 PM, Eduardo Costa <edu500ac at gmail.com> wrote:
> I tried to implement despair 1 in Racket, and have a few questions about my
> solution. By the way, I am not a student trying to get my homework done by
> somebody else.
>
> The restrictions for despair 1 are:
>
> 1 - The whole implementation must have less than 100 lines. Comments and
> tests don't count as lines
>
> 2- No line should be longer than 30 chars
>
> 3- No function should have more than 12 lines
>
> 4- A blank line after each function is mandatory
>
> 5- The implementation can be done in any language and must pass despair
> stOne.dsp
>
>
> Here are two functions from stOne.dsp:
>
> def (fib n (f-1 1) (f-2 1))
> if [n<2] then f-1
> else (fib [n - 1]
> [f-1+f-2] f-1)
> end
> end
>
> def (fibo n)
> let loop
> local (i n) (a 1) (b 1)//
> cond
> ift [i<2] then a//
> otherwise
> (loop [i - 1] [a+b] a)//
> end
> end
> end
>
> My question is about the Implementation of the infix to prefix function. My
> pref macro consumed almost half of the allowed number of lines. The
> algorithm used is described in Lisp by Winston and Horn, third edition,
> chapter 32. Is there a way to reduce the size of the pref macro (perhaps
> changing the algorithm)?
>
> In order to keep the (p e o a) function in the 12 lines limit, I was forced
> to move the w? predicate out of (p e o a). Since Racket match requires one
> parameter predicates, (w? e) returns a closure. My question is: Does Racket
> rebuilds the closure for each iteration of (p e o a)? If this is the case,
> the algorithm is very inefficient. I hope that Racket somehow builds the
> closure just once. Thanks in advance for any piece of information or
> suggestion on how to improve the program.
>
> Special thanks to any member of this group who could tell me how to
> transform my implementation into #lang despair (no need to maintain the
> restriction of 100 lines). By the way, I tried to understand the chapter
> about building new language in the Racket documentation, but it still
> puzzles me.
>
> ;File: pref.rkt
> #lang racket
> (require (for-syntax racket))
> (provide pref)
>
> (define-for-syntax(w s)
> (case s ;10 lines
> [(or) 1] [(and) 2]
> [(< = > >= <=) 3]
> [(+ -) 4] [(* /) 5]
> [(^) 6][(:) 7]
> [else 9]))
>
> (define-for-syntax(:? x)
> (= (w x) 9))
>
> (define-for-syntax(w? e)
> (lambda(x)
> (> (w (car e))(w x))))
>
> (define-for-syntax(pre x)
> (if (pair? x)
> (p (cdr x) '()
> (list (pre (car x))) )
> x))
>
> (define-for-syntax(p e o a)
> (match/values (values e o a)
> [('() '() (cons x _)) x]
> [[(cons (? :?) _) _ _ ]
> (p (cons ': e) o a)]
> [[(list-rest x y es) (or
> '() (cons (? (w? e))_))_]
> (p es (cons x o)
> (cons (pre y) a))]
> [[_ (cons c os)
> (list-rest x y r)]
> (p e os (f c y x r) )]))
>
> (define-for-syntax(f c y x r)
> (if (equal? ': c)
> (cons (list y x) r)
> (cons (list c y x) r)))
>
> (define-syntax(pref s)
> (datum->syntax s (pre
> (cdr (syntax->datum s)))))
>
>
> ;File: despair.rkt
> #lang racket
> (require (for-syntax racket))
> (require "inf.rkt")
>
> (define-for-syntax(brk x)
> (regexp-match*
> (regexp (~a "\"[^\"]+\"|"
> "#t|#f|[a-z]+->[a-z]+|"
> "[a-z?A-Z~-]+[0-9-]*|"
> "-?[0-9]+\\.?[0-9]*|"
> "<=|>=|//|"
> "[][()'&;*:<>=,+/^-]")) x))
>
> (define-for-syntax (fix x)
> (match x
> ["def" "(define"]
> ["if" "(if"]
> ["then" ""]
> ["else" ""]
> ["end" ")" ]
> ["//" ")"]
> ["cond" "(cond"]
> ["ift" "("]
> ["let" "(let"]
> ["local" "("]
> ["otherwise" "(else"]
> ["[" "(pref"]
> ["]" ")"]
> [head head]))
>
> (define-for-syntax (prs xpr)
> (with-input-from-string
> (string-join (for/list
> [(token (brk xpr))]
> (fix token)) " ")
> (λ() (read)) ))
>
> (define-for-syntax(tkn stx)
> (~a "(" (file->string (cadr
> (syntax->datum stx)))
> ")"))
>
> (define-syntax(ld stx)
> (datum->syntax stx
> (cons 'begin
> (prs (tkn stx)) )))
>
> (ld "stOne.dsp")
> (fibo 5)
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
>