[racket] Compiler for despair 1

From: Gustavo Massaccesi (gustavo at oma.org.ar)
Date: Mon Nov 3 06:21:16 EST 2014

 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
>


Posted on the users mailing list.