summaryrefslogtreecommitdiff
path: root/ebus-racket/3rdparty/bzlib/parseq/example/calc.ss
blob: 35ada606d73b8c1e50b7e276c2d12d5dd4c4083d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#lang scheme/base
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PARSEQ.PLT 
;; A Parser Combinator library.
;; 
;; Bonzai Lab, LLC.  All rights reserved.
;; 
;; Licensed under LGPL.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; calc.ss - a simple arithmetic calculator  
;; yc 12/31/2009 - first version 
(require "../main.ss"
         )

;; determine the operator (currently there are no precedences)... 
(define OP (tokens op <- (char-in '(#\+ #\- #\* #\/))
                   (return (case op 
                             ((#\+) +)
                             ((#\-) -)
                             ((#\*) *)
                             ((#\/) /)))))

(define NUMBER (token real-number)) 

;; expr := term op term 
(define expr (tokens lhs <- term 
                     (let loop ((lhs lhs))
                       (choice (tokens opr <- OP 
                                       rhs <- term 
                                       (loop (list opr lhs rhs)))
                               (return lhs)))))
;; term := factor op factor 
(define term (tokens lhs <- factor 
                     (let loop ((lhs lhs))
                       (choice (tokens opr <- OP 
                                       rhs <- factor 
                                       (loop (list opr lhs rhs)))
                               (return lhs)))))

;; factor := number | ( exp ) 
(define factor (choice NUMBER (bracket #\( expr #\))))

(define (calc in) 
  (define (helper exp)
    (cond ((number? exp) exp)
          ((pair? exp) 
           (apply (car exp) 
                  (map helper (cdr exp))))))
  (helper ((make-reader expr) in))) 

(provide calc)