blob: 3cd4f009a2b26fadbbab5bd97b2f7af25975b3b8 (
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
44
45
46
47
|
(ns cljcc.emit
(:require [cljcc.parser :as p]
[cljcc.util :refer [get-os]]
[clojure.string :as str]))
(defn handle-function-name [name]
(if (= :mac (get-os))
(str "_" name)
name))
(defn emit-instruction
([inst]
(str " " (symbol inst)))
([inst src dst]
(str " " (symbol inst) " " "$" src ", %" (symbol dst))))
(defn statement-fn [stmt]
(condp = (:op stmt)
:ret (emit-instruction :ret)
:movl (emit-instruction (:op stmt) (:src stmt) (:dst stmt))))
(defn emit-function-assembly [fn-ast]
(let [name (handle-function-name (:identifier fn-ast))
globl-line (str " .globl " name)
fn-start-line (str name ":")
body-statements (map statement-fn (:body fn-ast))]
(flatten [globl-line fn-start-line body-statements])))
(def linux-assembly-end ".section .note.GNU-stack,\"\",@progbits")
(defn emit-assembly [ast]
(let [fn-assembly (emit-function-assembly (first ast))]
(if (= :linux (get-os))
(concat fn-assembly [linux-assembly-end])
fn-assembly)))
(defn join-assembly [assembly-lines]
(str/join "\n" assembly-lines))
(comment
(def ex "int main(void) {return 2;}")
(-> ex
p/parse)
())
|