-
Notifications
You must be signed in to change notification settings - Fork 0
/
type-check-Lif.rkt
79 lines (67 loc) · 2.69 KB
/
type-check-Lif.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
69
70
71
72
73
74
75
76
77
78
#lang racket
(require "utilities.rkt")
(require "type-check-Lvar.rkt")
(provide type-check-Lif type-check-Lif-class type-check-if-mixin)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Booleans and Control Flow ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; type-check-if-mixin (reusable for Lif and Cif)
(define (type-check-if-mixin super-class)
(class super-class
(super-new)
(inherit check-type-equal?)
(define/override (type-equal? t1 t2)
(debug 'type-equal? "lenient" t1 t2)
(match* (t1 t2)
[('_ t2) #t]
[(t1 '_) #t]
[(other wise) (super type-equal? t1 t2)]))
(define/public (combine-types t1 t2)
(match (list t1 t2)
[(list '_ t2) t2]
[(list t1 '_) t1]
[else
t1]))
(define/override (operator-types)
(append '((and . ((Boolean Boolean) . Boolean))
(or . ((Boolean Boolean) . Boolean))
(< . ((Integer Integer) . Boolean))
(<= . ((Integer Integer) . Boolean))
(> . ((Integer Integer) . Boolean))
(>= . ((Integer Integer) . Boolean))
(not . ((Boolean) . Boolean))
)
(super operator-types)))
(define/override (type-check-exp env)
(lambda (e)
(debug 'type-check-exp "Lif" e)
(match e
[(Bool b) (values (Bool b) 'Boolean)]
[(Prim 'eq? (list e1 e2))
(define-values (e1^ T1) ((type-check-exp env) e1))
(define-values (e2^ T2) ((type-check-exp env) e2))
(check-type-equal? T1 T2 e)
(values (Prim 'eq? (list e1^ e2^)) 'Boolean)]
[else ((super type-check-exp env) e)])))
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; type-check-Lif
(define type-check-Lif-class
(class (type-check-if-mixin type-check-Lvar-class)
(super-new)
(inherit check-type-equal? combine-types)
(define/override (type-check-exp env)
(lambda (e)
(match e
[(If cnd thn els)
(define-values (cnd^ Tc) ((type-check-exp env) cnd))
(define-values (thn^ Tt) ((type-check-exp env) thn))
(define-values (els^ Te) ((type-check-exp env) els))
(check-type-equal? Tc 'Boolean e)
(check-type-equal? Tt Te e)
(values (If cnd^ thn^ els^) (combine-types Tt Te))]
[else ((super type-check-exp env) e)])))
))
(define (type-check-Lif p)
(send (new type-check-Lif-class) type-check-program p))