@@ -27,17 +27,8 @@ (import (chicken pretty-print)) (import (chicken io)) (include "../scmlib/lisp-macro.scm") -(: *code-depth* integer) -(define *code-depth* 0) ; im sry - -(: indent (string -> string)) -(define (indent str) - (define (iterate n) - (if (eq? n 0) str - (string-append "\t" (iterate (- n 1))))) - (iterate *code-depth*)) (define (first fst . lst) fst) (: string-reduce (list --> string)) (: words->string (list --> string)) @@ -78,9 +69,9 @@ (cond ((and (list? (car body)) (>= (length body) 2)) (let ([contents (words->string (map (lambda(x) (eval-code #f x)) (cdr body)))]) (string-append (c-declare (car body)) - (if (>= (length (car body)) 3) (string-append " {\n" contents "\n}") + (if (>= (length (car body)) 3) (string-append " {" contents "}") (string-append " = " contents))))) (else (abort '(exn syntax define))))) (: c-call-function (list -> string)) @@ -87,8 +78,31 @@ (define (c-call-function body) (unless (> (length body) 0) (abort '(exn parse call))) (string-append (eval-code #t (car body)) "(" (separate "," (map (lambda(x) (eval-code #t x)) (cdr body))) ")")) + +(: c-array-index (list -> string)) +(define (c-array-index body) + (unless (= (length body) 2) (abort '(exn parse call))) + (string-append + (eval-code #t (car body)) + "[" (eval-code #t (cadr body)) "]")) + +(: c-conditional (list -> string)) +(define (c-conditional body) + (unless (> (length body) 0) (abort '(exn parse cond))) + (define (mk-block acc code) + (string-append + (if (eq? 'else (car code)) (string-append acc "else {") + (string-append acc + (if (equal? acc "") "if (" " else if (") + (eval-code #t (car code)) ") {")) + + (string-reduce (map (lambda(x)(eval-code #f x)) (cdr code))) + "}" + )) + (foldl mk-block "" body)) + (define (c-cpp-include body) (case (length body) ((1) (if (string? (car body)) (string-append "#include \"" (car body) "\"\n") @@ -120,18 +134,10 @@ (let ([arg-str (separate ", " (map parse-arg args))] [ret-fn (eval-type ret)]) (ret-fn (string-append (ensure-string name) "(" arg-str ")")))) -(define-macro (with-deeper-context . body) - `(begin - (set! *code-depth* (+ 1 *code-depth*)) - (first - ,@body - (set! *code-depth* (- *code-depth* 1)) - ))) - (: c-statement (string -> string)) -(define (c-statement s) (indent (with-deeper-context (string-append s ";\n")))) +(define (c-statement s) (string-append s ";")) (: eval-type ((or null symbol list) -> ((or symbol string) -> string))) (define (eval-type t) ; a type object is a function that is called with a name to @@ -184,55 +190,72 @@ ('llong (simple "long long")) ('ldouble (simple "long double")) ('u128 (simple "unsigned __int128_t")) ('s128 (simple "__int128_t")) + ('ptr (simple "void*")) (else (simple (symbol->string t))))) ((list? t) (parse-type t)) ((string? t) (simple t)) (else (abort '(exn syntax))))) (define (c-construct type name body) - (string-append type " " name " {\n" - (string-reduce (map (lambda(x) (indent (eval-code #f x))) body)) - "\n}")) + (string-append type " " name " {" + (string-reduce (map (lambda(x) (eval-code #f x)) body)) + "}")) (define (c-fn-return body) (string-append "return " (string-reduce (map (lambda(x) (eval-code #t x)) body)))) -(define (c-math-op op body) - (unless (= 2 (length body)) (abort '(exn syntax math))) +(define (c-binary-op op body) + (unless (= 2 (length body)) (abort '(exn syntax binary-op))) (string-append "((" (eval-code #t (car body)) ")" op "(" (eval-code #t (cadr body)) "))")) -(define (inter s x) (print* "-- " s ": ") (pretty-print x) x) +(define (c-unary-op op body) + (unless (= 1 (length body)) (abort '(exn syntax unary-op))) + (string-append "(" op "(" (eval-code #t (car body)) "))")) + +(define (c-typecast body) + (unless (= 2 (length body)) (abort '(exn syntax binary-op))) + (string-append "((" ((eval-type (car body))"") ")" (eval-code #t (cadr body)) ")")) + +(define (wiretap s x) (print* "-- " s ": ") (pretty-print x) x) (: eval-code (boolean list -> string)) (define (eval-code inexpr data) (define (ctx x) inexpr (if (eq? inexpr #t) x (c-statement x))) - (define (deepen n) (set! *code-depth* (+ *code-depth* n))) (: dispatch (list -> string)) (define (dispatch form body) (case form ('* (eval-code inexpr (evaluate-list body))) ('= (eval-code inexpr (evaluate-list (cons 'begin body)))) ('@ (eval (cons 'begin body)) "") ('use (c-cpp-include body)) - ('def (first (c-statement (with-deeper-context (c-define body))) )) - ('decl (first (c-statement (with-deeper-context (c-declare body))) )) + ('def (first (c-statement (c-define body))) ) + ('decl (first (c-statement (c-declare body)) )) ('call (ctx (c-call-function body))) + ('cond (c-statement (c-conditional body))) ('list (first (string-append "{" (separate "," (map (lambda(x) (eval-code #t x)) body)) "}") )) ('struct (first (ctx (c-construct "struct" (car form) (cdr form))) )) ('enum (first (ctx (c-construct "enum" (car form) (cdr form))) )) ('ret (c-statement (c-fn-return body))) - ('add (c-math-op "+" body)) - ('add-> (ctx (c-math-op "+=" body))) - ('sub (c-math-op "-" body)) - ('sub-> (ctx (c-math-op "-=" body))) - ('mul (c-math-op "*" body)) - ('mul-> (ctx (c-math-op "*=" body))) - ('div (c-math-op "/" body)) - ('div-> (ctx (c-math-op "/=" body))) - ('== (c-math-op "==" body)) - ('-> (ctx (c-math-op "=" body))) - ('→ (ctx (c-math-op "=" body))) + ('cast (c-typecast body)) + ('idx (c-array-index body)) + ('add (c-binary-op "+" body)) + ('add-> (ctx (c-binary-op "+=" body))) + ('sub (c-binary-op "-" body)) + ('sub-> (ctx (c-binary-op "-=" body))) + ('mul (c-binary-op "*" body)) + ('mul-> (ctx (c-binary-op "*=" body))) + ('div (c-binary-op "/" body)) + ('div-> (ctx (c-binary-op "/=" body))) + ('ref (c-unary-op "&" body)) + ('eq (c-binary-op "==" body)) + ('neq (c-binary-op "!=" body)) + ('gte (c-binary-op ">=" body)) + ('lte (c-binary-op "<=" body)) + ('lt (c-binary-op "<" body)) + ('gt (c-binary-op ">" body)) + ('-> (ctx (c-binary-op "=" body))) + ('→ (ctx (c-binary-op "=" body))) ('; ";") (else (string-append "string form) ">")) ))) (cond