summaryrefslogtreecommitdiff
path: root/src/modules/emitter/emitter.scm
blob: 5e4b7d4feb4940d63ba2edd0b3fa5110434fff4e (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
(define-module (modules emitter emitter)
  #:use-module (modules ast syntax-tree)
  #:use-module (modules ast assembly-tree)
  #:export (e-program))


(define emit #f)
(define emitln #f)
(let ((p ""))
  (set! emit
        (lambda (str)
          (set! p (string-append/shared p str))
          p))
  (set! emitln
        (lambda (str)
          (emit (string-append/shared str "\n"))
          p))
  )

(define (e-program p)
  (e-subroutine (program-function p))
  (emitln ".section .note.GNU-stack,\"\",@progbits"))

(define (e-subroutine s)
  (let ((label (subroutine-label s)))
    (emitln (format #f "    .globl ~a" label))
    (emitln (format #f "~a:" label)))
  (e-instructions (subroutine-instructions s)))

(define (e-instructions lst)
  (unless (null? lst)
    (begin (e-instruction (car lst))
           (e-instructions (cdr lst)))))

(define (e-instruction i)
  (emit (format #f "    ~a" (instruction-operator i)))
  (let ((oper1 (instruction-operand-1 i))
        (oper2 (instruction-operand-2 i)))
    (when oper1
      (emit (format #f " ~a" oper1))
      (when oper2
        (emit (format #f ", ~a" oper2)))))
  (emitln ""))