summaryrefslogtreecommitdiff
path: root/src/modules/emitter/emitter.scm
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/emitter/emitter.scm')
-rw-r--r--src/modules/emitter/emitter.scm43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/modules/emitter/emitter.scm b/src/modules/emitter/emitter.scm
new file mode 100644
index 0000000..5e4b7d4
--- /dev/null
+++ b/src/modules/emitter/emitter.scm
@@ -0,0 +1,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 ""))