-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse.rkt
68 lines (61 loc) · 1.99 KB
/
parse.rkt
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#lang racket
(provide parse parse-e)
(require "ast.rkt")
;; S-Expr -> Prog
(define (parse s)
(match s
[(list 'begin (and ds (list 'define _ _)) ... e)
(Prog (map parse-d ds) (parse-e e))]
[e (Prog '() (parse-e e))]))
;; S-Expr -> Defn
(define (parse-d s)
(match s
[(list 'define (list (? symbol? f) (? symbol? xs) ...) e)
(Defn f xs (parse-e e))]
[_ (error "Parse defn error" s)]))
;; S-Expr -> Expr
(define (parse-e s)
(match s
[(? integer?) (Int s)]
[(? boolean?) (Bool s)]
[(? char?) (Char s)]
['eof (Eof)]
[(? symbol?) (Var s)]
[(list 'quote (list)) (Empty)]
[(list (? (op? op0) p0)) (Prim0 p0)]
[(list (? (op? op1) p1) e) (Prim1 p1 (parse-e e))]
[(list (? (op? op2) p2) e1 e2) (Prim2 p2 (parse-e e1) (parse-e e2))]
[(list 'begin e1 e2)
(Begin (parse-e e1) (parse-e e2))]
[(list 'if e1 e2 e3)
(If (parse-e e1) (parse-e e2) (parse-e e3))]
[(list 'let (list (list (? symbol? x) e1)) e2)
(Let x (parse-e e1) (parse-e e2))]
[(list 'letrec bs e1)
(LetRec (parse-bindings bs) (parse-e e1))]
[(list 'λ (? symbol-list? as) e1) (Lam '() as (parse-e e1))]
[(list 'lambda (? symbol-list? as) e1) (Lam '() as (parse-e e1))]
[(cons f es)
(App (parse-e f) (map parse-e es))]
[_ (error "Parse error" s)]))
(define (parse-bindings bs)
(match bs
['() '()]
[(cons (list (? symbol? x) e1) rest)
(cons (list x (parse-e e1)) (parse-bindings rest))]))
(define (symbol-list? xs)
(match xs
[(list (? symbol?) ...) xs]))
(define op0
'(read-byte peek-byte void))
(define op1
'(add1 sub1 zero? char? write-byte eof-object?
integer->char char->integer box unbox empty? car cdr
string? string-length
procedure-arity))
(define op2
'(+ - eq? cons string-ref make-string))
(define (op? ops)
(λ (x)
(and (symbol? x)
(memq x ops))))