unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Arithmetic evaluator for Guile
@ 2010-03-20 17:41 No Itisnt
  2010-03-21 20:39 ` Thien-Thi Nguyen
  2010-03-21 23:08 ` Andy Wingo
  0 siblings, 2 replies; 3+ messages in thread
From: No Itisnt @ 2010-03-20 17:41 UTC (permalink / raw)
  To: guile-user

Here's a little expression evaluator for Guile 1.9 using the new
bytecode compiler. It does arithmetic, exponentiation, modulos, and
equality tests. See the tests at the bottom for example expressions.
This is probably the most dense Scheme program I've written and I
would really appreciate a critique of the code.

http://pastebin.com/dhADj1EM




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Arithmetic evaluator for Guile
  2010-03-20 17:41 Arithmetic evaluator for Guile No Itisnt
@ 2010-03-21 20:39 ` Thien-Thi Nguyen
  2010-03-21 23:08 ` Andy Wingo
  1 sibling, 0 replies; 3+ messages in thread
From: Thien-Thi Nguyen @ 2010-03-21 20:39 UTC (permalink / raw)
  To: No Itisnt; +Cc: guile-user

() No Itisnt <theseaisinhere@gmail.com>
() Sat, 20 Mar 2010 12:41:36 -0500

   http://pastebin.com/dhADj1EM

Could you please send the code to guile-sources@gnu.org
(with proper copyright and license notices)?

That would help those who primarily operate via mailing lists,
as well as web users (the list archive is web accessible).

thi




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Arithmetic evaluator for Guile
  2010-03-20 17:41 Arithmetic evaluator for Guile No Itisnt
  2010-03-21 20:39 ` Thien-Thi Nguyen
@ 2010-03-21 23:08 ` Andy Wingo
  1 sibling, 0 replies; 3+ messages in thread
From: Andy Wingo @ 2010-03-21 23:08 UTC (permalink / raw)
  To: No Itisnt; +Cc: guile-user

Hi!

On Sat 20 Mar 2010 18:41, No Itisnt <theseaisinhere@gmail.com> writes:

> Here's a little expression evaluator for Guile 1.9 using the new
> bytecode compiler. It does arithmetic, exponentiation, modulos, and
> equality tests. See the tests at the bottom for example expressions.
> This is probably the most dense Scheme program I've written and I
> would really appreciate a critique of the code.

Lovely, clear code. I have only a few comments.

> (define (pp . ls) (for-each (lambda (y) (write y) (display #\space)) ls) (newline))

There is (ice-9 pretty-print), if that's what you want.

> ;;;;; PROPERTIES

> ;; The following object properties may be set on tokens[...]

Using object properties for the various operators is fine, but hash
tables would probably be better, because they can be iterated over.
Though, object properties do have a pleasant syntax.

Using object properties for the "moving parts" of the compiler is a bit
unfortunate, though; I feel like it decreases the referential
transparency of the parser. If it were me, I would write read-calculator
as one big function, containing e.g. read-expression and the rest as
internal definitions, and the body of the function would just kick off
the read. It would be easier for me to see how the parameters flow that
way. But, your code is pleasantly succint.

Another option would be to use lalr-scm (there is a copy in Guile that
will get documented for the next release), or write a PEG parser
generator (that would be fun!), or some sort of parser combinator lib.
But what you have is fine.

> ;; Input port
> (define port (make-parameter #f))

Why bother? Just use (current-input-port), no? Lets you use peek-char
instead of %peek-char too.

> (define (initialize)
>   (letrec-syntax

Nice syntax-rules use here :)

>     ;; eugh -- for define-infix-operator
>     (define (char->symbol c)
>       (string->symbol (list->string (list c))))

(string->symbol (string c))
    
> (define (syntax-error . args) (apply error (cons 'syntax args)))

(apply error 'syntax args); but it's better to tighten up the meaning of
these parameters, as in (define* (syntax-error message object #:optional
context) ...)

> ;; Number lexer
> (define (char-number? c) (and (not (eof-object? c)) (char-numeric? c)))
> (define (char->number c) (- (char->integer c) (char->integer #\0)))
> (define (char-delimiter? c) (or (eof-object? c) (terminal c) (char-whitespace? c)))

> ;; Read a number
> (define (read-number)
>   (let loop ((number (char->number (%read-char))))
>     (if (char-number? (%peek-char))
>         (loop (+ (* number 10) (char->number (%read-char))))
>         number)))

Guile could expose its number reader; perhaps that's a good idea. There
have been a number of bugs over the years in the number reader.

> ;; Compile any operation which takes two arguments
> (define (compile-operation2 e operation first second)
>   `(apply ,(code-object operation) ,(compile e first) ,(compile e
> second)))

Nice use of tree-il literals. One thing your parser is missing though is
source information; you can get that by attaching source info to the
tree-il literals.

Cool hack!

Andy
-- 
http://wingolog.org/




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-03-21 23:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-20 17:41 Arithmetic evaluator for Guile No Itisnt
2010-03-21 20:39 ` Thien-Thi Nguyen
2010-03-21 23:08 ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).