#!./eval (define __MACH__ '(x)) ; non-nil for Darwin / Mac OS X (deal with the convoluted ABI) (define __UNIX__ '( )) ; nin-nil for Unix, MinGW, etc. (external symbols have underscore prefix) (define __LINUX__ '( )) ; non-nil for Linux, Cygwin, etc. (external symbols have no underscore prefix) ;;;---------------------------------------------------------------- (define __PREFIX__ (if __LINUX__ "" "_")) (define-function string->type-name (str) (string->symbol (concat-string "<" (concat-string str ">")))) (define-function symbol->type-name (sym) (string->type-name (symbol->string sym))) (define-function align (alignment value) (& (- alignment) (+ (- alignment 1) value ))) ;;; EXTERN (define-structure (name stub)) (define-function extern (name) (let ((self (new ))) (set (-name self) name) self)) (define-function extern? (obj) (= (type-of obj))) ;;; DEFINE-OPERAND (define-function define-operand-make-setters (tname fields) (if (pair? fields) (cons `(set (,(concat-symbol (concat-symbol tname '-) (car fields)) self) ,(car fields)) (define-operand-make-setters tname (cdr fields))))) (define-form define-operand (name fields . printing) (let* ((sname (symbol->string name)) (tname (string->symbol (concat-string "<" (concat-string sname ">"))))) (eval `(define-structure ,tname ,fields)) (eval `(define-function ,name ,fields (let ((self (new ,tname))) ,@(define-operand-make-setters tname fields) self))) `(define-method do-print ,tname () (print ,@printing)))) ;;; DEFINE-INSTRUCTION (define-form define-instruction (name) (let* ((sname (symbol->string name)) (tname (string->symbol (concat-string "<" (concat-string sname ">"))))) `(let () (define-structure ,tname ()) (define-method do-print ,tname () (print ,sname)) (define ,name (new ,tname))))) ;;; DEFINE-EMIT (define-generic emit op-args (print "\nemit: illegal instruction: "op-args) (error "aborted")) (define-multimethod emit (( program)) (while program (apply emit (car program)) (set program (cdr program)))) (define-function %define-emit-param-name (index) (string->symbol (concat-string "$" (long->string index)))) (define-function %define-emit-params (index types) (if (pair? types) (cons (list (symbol->type-name (car types)) (%define-emit-param-name index)) (%define-emit-params (+ index 1) (cdr types))))) (define-form define-emit (op-args . body) (let* ((opsym (car op-args)) (sname (symbol->string opsym)) (tname (string->type-name sname))) `(let () ,@(if (not (assq opsym *globals*)) `((define-instruction ,opsym))) (define-multimethod emit ((,tname op) ,@(%define-emit-params 1 (cdr op-args))) ,@body)))) (define-function digit-for (c) (if (< c 10) (+ c 0x30) (+ c 0x37))) (define-function mangle-label (name) (let* ((plain (symbol->string name)) (mangled (array)) (index 0) (outdex 0) (size (string-length plain))) (while (< index size) (let ((c (string-at plain index))) (cond ((or (and (<= 0x61 c) (<= c 0x7a)) (and (<= 0x41 c) (<= c 0x5a)) (and (<= 0x30 c) (<= c 0x39))) (let () (set-array-at mangled outdex c) (set outdex (+ outdex 1)))) ((= ?_ c) (let () (set-array-at mangled outdex c) (set outdex (+ outdex 1)) (set-array-at mangled outdex c) (set outdex (+ outdex 1)))) (else (let () (set-array-at mangled outdex 0x5f) (set outdex (+ outdex 1)) (set-array-at mangled outdex (digit-for (>> c 4))) (set outdex (+ outdex 1)) (set-array-at mangled outdex (digit-for (& c 15))) (set outdex (+ outdex 1)))))) (set index (+ 1 index))) (array->string mangled))) ;;; IA32 -- OPERANDS (let ((counter 0)) (define-function temp-label-name () (concat-string "_L_" (long->string (set counter (+ counter 1)))))) (define-operand LABEL (name) __PREFIX__(mangle-label (