Просмотр исходного кода

Implement if 💃

?!

Like, does this actually actually work?!  It seems like it does, as in
the almost most-trivial example works, but it is pretty exciting!  Is it
turing complete yet?  (I don't think so, but... maybe?)

Yaaaay!
Lucas Stadler лет назад: 8
Родитель
Сommit
b836861cf0
2 измененных файлов с 31 добавлено и 1 удалено
  1. 30 0
      scm/inc/compiler.scm
  2. 1 1
      scm/inc/program.scm

+ 30 - 0
scm/inc/compiler.scm

5
  (display (apply format instr args))
5
  (display (apply format instr args))
6
  (display "\n"))
6
  (display "\n"))
7
7
8
(define label-counter 0)
9
10
(define (unique-label)
11
  (let ((c label-counter))
12
    (set! label-counter (+ c 1))
13
    (format "label_~d" c)))
14
8
(define wordsize 4)
15
(define wordsize 4)
9
16
10
(define fixnum-shift 2)
17
(define fixnum-shift 2)
48
(define (let? x)
55
(define (let? x)
49
  (and (list? x) (eq? (car x) 'let) (list? (cadr x)) (list? (caadr x))))
56
  (and (list? x) (eq? (car x) 'let) (list? (cadr x)) (list? (caadr x))))
50
57
58
(define (if? x)
59
  (and (list? x) (eq? (car x) 'if)))
60
51
(define (emit-expr x si env)
61
(define (emit-expr x si env)
52
  (cond
62
  (cond
53
    ((immediate? x)
63
    ((immediate? x)
56
     (emit "movl ~a(%rsp), %eax" (lookup x env)))
66
     (emit "movl ~a(%rsp), %eax" (lookup x env)))
57
    ((let? x)
67
    ((let? x)
58
     (emit-let (bindings x) (body x) si env))
68
     (emit-let (bindings x) (body x) si env))
69
    ((if? x)
70
     (emit-if (test x) (conseq x) (altern x) si env))
59
    ((primcall? x) (emit-primitive-call x si env))))
71
    ((primcall? x) (emit-primitive-call x si env))))
60
72
61
(define (lookup x env)
73
(define (lookup x env)
90
(define (lhs binding) (car binding))
102
(define (lhs binding) (car binding))
91
(define (rhs binding) (cadr binding))
103
(define (rhs binding) (cadr binding))
92
104
105
(define (emit-if test conseq altern si env)
106
  (let ((L0 (unique-label)) (L1 (unique-label)))
107
    (emit-expr test si env)
108
    (emit "cmpl $~a, %eax" (immediate-rep #f))
109
    (emit "je ~a" L0)
110
    (emit-expr conseq si env)
111
    (emit "jmp ~a" L1)
112
    (emit-label L0)
113
    (emit-expr altern si env)
114
    (emit-label L1)))
115
116
(define (emit-label L)
117
  (display (format "~a:\n" L)))
118
119
(define (test if-expr)   (cadr if-expr))
120
(define (conseq if-expr) (caddr if-expr))
121
(define (altern if-expr) (cadddr if-expr))
122
93
(define (emit-primitive-call x si env)
123
(define (emit-primitive-call x si env)
94
  (case (primcall-op x)
124
  (case (primcall-op x)
95
    ((add1)
125
    ((add1)

+ 1 - 1
scm/inc/program.scm

1
(load "compiler.scm")
1
(load "compiler.scm")
2
2
3
(compile-program '(let ((x 3) (y 4)) (+ x y)))
3
(compile-program '(let ((x 3) (y 4)) (if (integer? (+ x y)) 42 #f)))