;;; -*-scheme-*- ;;; Mes --- Maxwell Equations of Software ;;; Copyright © 2016 Jan Nieuwenhuizen ;;; ;;; compiler.mes: This file is part of Mes. ;;; ;;; Mes is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; Mes is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with Mes. If not, see . ;;; Commentary: ;;; compiler.mes produces an i386 binary from the C produced by ;;; c-parser. ;;; Code: (mes-use-module (mes elf)) (mes-use-module (mes libc-i386)) (mes-use-module (mes match)) (mes-use-module (srfi srfi-1)) (mes-use-module (language c lexer)) (mes-use-module (language c parser)) (define mescc (let ((errorp (lambda args (for-each display args) (newline)))) (lambda () (c-parser (c-lexer errorp) errorp)))) (define (write-any x) (write-char (if (char? x) x (integer->char (if (>= x 0) x (+ x 256)))))) (define (ast:function? o) (and (pair? o) (eq? (car o) 'function))) (define (.name o) (cadr o)) ;; (define (.statement o) ;; (match o ;; (('function name signature statement) statement) ;; (_ #f))) ;; (define (statement->data o) ;; (match o ;; (('call 'puts ('arguments string)) (string->list string)) ;; (_ '()))) ;; (define (statement->text o) ;; (match o ;; (('call 'puts ('arguments string)) (list (lambda (data) (i386:puts data (string-length string))))) ;; (('return code) (list (lambda (data) (i386:exit code)))) ;; (_ '()))) (define (.statement o) (and (pair? o) (eq? (car o) 'function) (cadddr o))) (define (statement->data o) (or (and (pair? o) (eq? (car o) 'call) (string->list (cadr (caddr o)))) (and (pair? o) (eq? (car o) 'for) (let ((statement (cadr (cdddr o)))) (statement->data statement))) '())) (define (statement->text data o) (cond ((and (pair? o) (eq? (car o) 'call)) (let ((string (cadr (caddr o))) (offset (length data))) (list (lambda (data) (i386:puts (+ data offset) (string-length string)))))) ((and (pair? o) (eq? (car o) 'for)) (let ((start (cadr o)) (test (caddr o)) (step (cadddr o)) (statement (cadr (cdddr o)))) (display "start:" (current-error-port)) (display start (current-error-port)) (newline (current-error-port)) (display "test:" (current-error-port)) (display test (current-error-port)) (newline (current-error-port)) (display "step:" (current-error-port)) (display step (current-error-port)) (newline (current-error-port)) (display "for-statement:" (current-error-port)) (display statement (current-error-port)) (newline (current-error-port)) (let ((start (cadr (cdadr start))) (test (cadr (cdadr test))) ;;(step (cadr (cdadr step))) (step 1) (statement (car (statement->text data statement))) ) (display "2start:" (current-error-port)) (display start (current-error-port)) (newline (current-error-port)) (display "2for-statement:" (current-error-port)) (display statement (current-error-port)) (newline (current-error-port)) (list (lambda (d) (i386:for start test step (statement d))))))) ((and (pair? o) (eq? (car o) 'return)) (list (lambda (data) (i386:exit (cadr o))))) (else '()))) (define (compile) (let* ((ast (mescc)) (functions (filter ast:function? (cdr ast))) (main (find (lambda (x) (eq? (.name x) 'main)) functions)) (statements (cdr (.statement main)))) (display "program: " (current-error-port)) (display ast (current-error-port)) (newline (current-error-port)) (let loop ((statements statements) (text '()) (data '())) (display "text:" (current-error-port)) (display text (current-error-port)) (newline (current-error-port)) (if (null? statements) (begin (display "dumping to a.out:\n" (current-error-port)) (map write-any (make-elf (lambda (data) (append-map (lambda (f) (f data)) text)) data))) (let* ((statement (car statements))) (display "statement:" (current-error-port)) (display statement (current-error-port)) (newline (current-error-port)) (loop (cdr statements) (append text (statement->text data statement)) (append data (statement->data statement))))))))