compile.scm 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671
  1. ;;; GNU Mes --- Maxwell Equations of Software
  2. ;;; Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  3. ;;;
  4. ;;; This file is part of GNU Mes.
  5. ;;;
  6. ;;; GNU Mes is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Mes is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
  18. ;;; Commentary:
  19. ;;; Code:
  20. (define-module (mescc compile)
  21. #:use-module (srfi srfi-1)
  22. #:use-module (srfi srfi-9 gnu)
  23. #:use-module (srfi srfi-26)
  24. #:use-module (system base pmatch)
  25. #:use-module (ice-9 optargs)
  26. #:use-module (ice-9 pretty-print)
  27. #:use-module (nyacc lang c99 pprint)
  28. #:use-module (mes guile)
  29. #:use-module (mes misc)
  30. #:use-module (mescc preprocess)
  31. #:use-module (mescc info)
  32. #:use-module (mescc as)
  33. #:use-module (mescc i386 as)
  34. #:use-module (mescc M1)
  35. #:export (c99-ast->info
  36. c99-input->info
  37. c99-input->object))
  38. (define mes? (pair? (current-module)))
  39. (define mes-or-reproducible? #t)
  40. (define (cc-amd? info) #f) ; use AMD calling convention?
  41. ;; (define %reduced-register-count #f) ; use all registers?
  42. (define %reduced-register-count 2) ; use reduced instruction set
  43. (define (max-registers info)
  44. (if %reduced-register-count %reduced-register-count
  45. (length (append (.registers info) (.allocated info)))))
  46. (define* (c99-input->info info #:key (prefix "") (defines '()) (includes '()) (arch "") verbose?)
  47. (let ((ast (c99-input->ast #:prefix prefix #:defines defines #:includes includes #:arch arch #:verbose? verbose?)))
  48. (c99-ast->info info ast #:verbose? verbose?)))
  49. (define* (c99-ast->info info o #:key verbose?)
  50. (when verbose?
  51. (format (current-error-port) "compiling: input\n")
  52. (set! mescc:trace mescc:trace-verbose))
  53. (let ((info (ast->info o info)))
  54. (clean-info info)))
  55. (define (clean-info o)
  56. (make <info>
  57. #:functions (filter (compose pair? function:text cdr) (.functions o))
  58. #:globals (.globals o)
  59. #:types (.types o)))
  60. (define (ident->constant name value)
  61. (cons name value))
  62. (define (enum->type-entry name fields)
  63. (cons `(tag ,name) (make-type 'enum 4 fields)))
  64. (define (struct->type-entry info name fields)
  65. (let ((size (apply + (map (compose (cut ->size <> info) cdr) fields))))
  66. (cons `(tag ,name) (make-type 'struct size fields))))
  67. (define (union->type-entry info name fields)
  68. (let ((size (apply max (map (compose (cut ->size <> info) cdr) fields))))
  69. (cons `(tag ,name) (make-type 'union size fields))))
  70. (define (signed? o)
  71. (let ((type (->type o)))
  72. (cond ((type? type) (eq? (type:type type) 'signed))
  73. (else #f))))
  74. (define (unsigned? o)
  75. (let ((type (->type o)))
  76. (cond ((type? type) (eq? (type:type type) 'unsigned))
  77. (else #t))))
  78. (define (->size o info)
  79. (cond ((and (type? o) (eq? (type:type o) 'union))
  80. (apply max (map (compose (cut ->size <> info) cdr) (struct->fields o))))
  81. ((type? o) (type:size o))
  82. ((pointer? o) (->size (get-type "*" info) info))
  83. ((c-array? o) (* (c-array:count o) ((compose (cut ->size <> info) c-array:type) o)))
  84. ((local? o) ((compose (cut ->size <> info) local:type) o))
  85. ((global? o) ((compose (cut ->size <> info) global:type) o))
  86. ((bit-field? o) ((compose (cut ->size <> info) bit-field:type) o))
  87. ((and (pair? o) (pair? (car o)) (bit-field? (cdar o))) ((compose (cut ->size <> info) cdar) o))
  88. ((string? o) (->size (get-type o info) info))
  89. (else (error "->size>: not a <type>:" o))))
  90. (define (ast->type o info)
  91. (define (type-helper o info)
  92. (if (getenv "MESC_DEBUG")
  93. (format (current-error-port) "type-helper: ~s\n" o))
  94. (pmatch o
  95. (,t (guard (type? t)) t)
  96. (,p (guard (pointer? p)) p)
  97. (,a (guard (c-array? a)) a)
  98. (,b (guard (bit-field? b)) b)
  99. ((char ,value) (get-type "char" info))
  100. ((enum-ref . _) (get-type "default" info))
  101. ((fixed ,value)
  102. (let ((type (cond ((string-suffix? "ULL"value) "unsigned long long")
  103. ((string-suffix? "UL" value) "unsigned long")
  104. ((string-suffix? "U" value) "unsigned")
  105. ((string-suffix? "LL" value) "long long")
  106. ((string-suffix? "L" value) "long")
  107. (else "default"))))
  108. (get-type type info)))
  109. ((float ,float) (get-type "float" info))
  110. ((void) (get-type "void" info))
  111. ((ident ,name) (ident->type info name))
  112. ((tag ,name) (or (get-type o info)
  113. o))
  114. (,name (guard (string? name))
  115. (let ((type (get-type name info)))
  116. (ast->type type info)))
  117. ((type-name (decl-spec-list ,type) (abs-declr (pointer . ,pointer)))
  118. (let ((rank (pointer->rank `(pointer ,@pointer)))
  119. (type (ast->type type info)))
  120. (rank+= type rank)))
  121. ((type-name ,type) (ast->type type info))
  122. ((type-spec ,type) (ast->type type info))
  123. ((sizeof-expr ,expr) (get-type "unsigned" info))
  124. ((sizeof-type ,type) (get-type "unsigned" info))
  125. ((string ,string) (make-c-array (get-type "char" info) (1+ (string-length string))))
  126. ((decl-spec-list (type-spec ,type)) (ast->type type info))
  127. ((fctn-call (p-expr (ident ,name)) . _)
  128. (or (and=> (assoc-ref (.functions info) name) function:type)
  129. (get-type "default" info)))
  130. ((fctn-call (de-ref (p-expr (ident ,name))) . _)
  131. (or (and=> (assoc-ref (.functions info) name) function:type)
  132. (get-type "default" info)))
  133. ((fixed-type ,type) (ast->type type info))
  134. ((float-type ,type) (ast->type type info))
  135. ((type-spec ,type) (ast->type type info))
  136. ((typename ,type) (ast->type type info))
  137. ((array-ref ,index ,array) (rank-- (ast->type array info)))
  138. ((de-ref ,expr) (rank-- (ast->type expr info)))
  139. ((ref-to ,expr) (rank++ (ast->type expr info)))
  140. ((p-expr ,expr) (ast->type expr info))
  141. ((pre-inc ,expr) (ast->type expr info))
  142. ((post-inc ,expr) (ast->type expr info))
  143. ((struct-ref (ident ,type))
  144. (or (get-type type info)
  145. (let ((struct (if (pair? type) type `(tag ,type))))
  146. (ast->type struct info))))
  147. ((union-ref (ident ,type))
  148. (or (get-type type info)
  149. (let ((struct (if (pair? type) type `(tag ,type))))
  150. (ast->type struct info))))
  151. ((struct-def (ident ,name) . _)
  152. (ast->type `(tag ,name) info))
  153. ((union-def (ident ,name) . _)
  154. (ast->type `(tag ,name) info))
  155. ((struct-def (field-list . ,fields))
  156. (let ((fields (append-map (struct-field info) fields)))
  157. (make-type 'struct (apply + (map (cut field:size <> info) fields)) fields)))
  158. ((union-def (field-list . ,fields))
  159. (let ((fields (append-map (struct-field info) fields)))
  160. (make-type 'union (apply + (map (cut field:size <> info) fields)) fields)))
  161. ((enum-def (enum-def-list . ,fields))
  162. (get-type "default" info))
  163. ((d-sel (ident ,field) ,struct)
  164. (let ((type0 (ast->type struct info)))
  165. (ast->type (field-type info type0 field) info)))
  166. ((i-sel (ident ,field) ,struct)
  167. (let ((type0 (ast->type (rank-- (ast->type struct info)) info)))
  168. (ast->type (field-type info type0 field) info)))
  169. ;; arithmetic
  170. ((pre-inc ,a) (ast->type a info))
  171. ((pre-dec ,a) (ast->type a info))
  172. ((post-inc ,a) (ast->type a info))
  173. ((post-dec ,a) (ast->type a info))
  174. ((add ,a ,b) (ast->type a info))
  175. ((sub ,a ,b) (ast->type a info))
  176. ((bitwise-and ,a ,b) (ast->type a info))
  177. ((bitwise-not ,a) (ast->type a info))
  178. ((bitwise-or ,a ,b) (ast->type a info))
  179. ((bitwise-xor ,a ,b) (ast->type a info))
  180. ((lshift ,a ,b) (ast->type a info))
  181. ((rshift ,a ,b) (ast->type a info))
  182. ((div ,a ,b) (ast->type a info))
  183. ((mod ,a ,b) (ast->type a info))
  184. ((mul ,a ,b) (ast->type a info))
  185. ((not ,a) (ast->type a info))
  186. ((pos ,a) (ast->type a info))
  187. ((neg ,a) (ast->type a info))
  188. ((eq ,a ,b) (ast->type a info))
  189. ((ge ,a ,b) (ast->type a info))
  190. ((gt ,a ,b) (ast->type a info))
  191. ((ne ,a ,b) (ast->type a info))
  192. ((le ,a ,b) (ast->type a info))
  193. ((lt ,a ,b) (ast->type a info))
  194. ;; logical
  195. ((or ,a ,b) (ast->type a info))
  196. ((and ,a ,b) (ast->type a info))
  197. ((cast (type-name ,type) ,expr) (ast->type type info))
  198. ((cast (type-name ,type (abs-declr ,pointer)) ,expr)
  199. (let ((rank (pointer->rank pointer)))
  200. (rank+= (ast->type type info) rank)))
  201. ((decl-spec-list (type-spec ,type)) (ast->type type info))
  202. ;; ;; `typedef int size; void foo (unsigned size u)
  203. ((decl-spec-list (type-spec ,type) (type-spec ,type2))
  204. (ast->type type info))
  205. ((assn-expr ,a ,op ,b) (ast->type a info))
  206. ((cond-expr _ ,a ,b) (ast->type a info))
  207. (_ (get-type o info))))
  208. (let ((type (type-helper o info)))
  209. (cond ((or (type? type)
  210. (pointer? type) type
  211. (c-array? type)) type)
  212. ((and (equal? type o) (pair? type) (eq? (car type) 'tag)) o)
  213. ((equal? type o)
  214. (error "ast->type: not supported: " o))
  215. (else (ast->type type info)))))
  216. (define (ast->basic-type o info)
  217. (let ((type (->type (ast->type o info))))
  218. (cond ((type? type) type)
  219. ((equal? type o) o)
  220. (else (ast->type type info)))))
  221. (define (get-type o info)
  222. (let ((t (assoc-ref (.types info) o)))
  223. (pmatch t
  224. ((typedef ,next) (or (get-type next info) o))
  225. (_ t))))
  226. (define (ast-type->size info o)
  227. (let ((type (->type (ast->type o info))))
  228. (cond ((type? type) (type:size type))
  229. (else (format (current-error-port) "error: ast-type->size: ~s => ~s\n" o type)
  230. 4))))
  231. (define (field:name o)
  232. (pmatch o
  233. ((struct (,name ,type ,size ,pointer) . ,rest) name)
  234. ((union (,name ,type ,size ,pointer) . ,rest) name)
  235. ((,name . ,type) name)
  236. (_ (error "field:name not supported:" o))))
  237. (define (field:pointer o)
  238. (pmatch o
  239. ((struct (,name ,type ,size ,pointer) . ,rest) pointer)
  240. ((union (,name ,type ,size ,pointer) . ,rest) pointer)
  241. ((,name . ,type) (->rank type))
  242. (_ (error "field:pointer not supported:" o))))
  243. (define (field:size o info)
  244. (pmatch o
  245. ((struct . ,type) (apply + (map (cut field:size <> info) (struct->fields type))))
  246. ((union . ,type) (apply max (map (cut field:size <> info) (struct->fields type))))
  247. ((,name . ,type) (->size type info))
  248. (_ (error (format #f "field:size: ~s\n" o)))))
  249. (define (field-field info struct field)
  250. (let ((fields (type:description struct)))
  251. (let loop ((fields fields))
  252. (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
  253. (let ((f (car fields)))
  254. (cond ((equal? (car f) field) f)
  255. ((and (memq (car f) '(struct union)) (type? (cdr f))
  256. (find (lambda (x) (equal? (car x) field)) (struct->fields (cdr f)))))
  257. ((eq? (car f) 'bits) (assoc field (cdr f)))
  258. (else (loop (cdr fields)))))))))
  259. (define (field-offset info struct field)
  260. (if (eq? (type:type struct) 'union) 0
  261. (let ((fields (type:description struct)))
  262. (let loop ((fields fields) (offset 0))
  263. (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
  264. (let ((f (car fields)))
  265. (cond ((equal? (car f) field) offset)
  266. ((and (eq? (car f) 'struct) (type? (cdr f)))
  267. (let ((fields (type:description (cdr f))))
  268. (find (lambda (x) (equal? (car x) field)) fields)
  269. (apply + (cons offset
  270. (map (cut field:size <> info)
  271. (member field (reverse fields)
  272. (lambda (a b)
  273. (equal? a (car b) field))))))))
  274. ((and (eq? (car f) 'union) (type? (cdr f))
  275. (let ((fields (struct->fields (cdr f))))
  276. (and (find (lambda (x) (equal? (car x) field)) fields)
  277. offset))))
  278. ((and (eq? (car f) 'bits) (assoc-ref (cdr f) field)) offset)
  279. (else (loop (cdr fields) (+ offset (field:size f info)))))))))))
  280. (define (field-pointer info struct field)
  281. (let ((field (field-field info struct field)))
  282. (field:pointer field)))
  283. (define (field-size info struct field)
  284. (let ((field (field-field info struct field)))
  285. (field:size field info)))
  286. (define (field-type info struct field)
  287. (let ((field (field-field info struct field)))
  288. (ast->type (cdr field) info)))
  289. (define (struct->fields o)
  290. (pmatch o
  291. (_ (guard (and (type? o) (eq? (type:type o) 'struct)))
  292. (append-map struct->fields (type:description o)))
  293. (_ (guard (and (type? o) (eq? (type:type o) 'union)))
  294. (append-map struct->fields (type:description o)))
  295. ((struct . ,type) (list (car (type:description type))))
  296. ((union . ,type) (list (car (type:description type))))
  297. ((bits . ,bits) bits)
  298. (_ (list o))))
  299. (define (struct->init-fields o) ;; FIXME REMOVEME: non-recursive unroll
  300. (pmatch o
  301. (_ (guard (and (type? o) (eq? (type:type o) 'struct)))
  302. (append-map struct->init-fields (type:description o)))
  303. (_ (guard (and (type? o) (eq? (type:type o) 'union)))
  304. (list (car (type:description o))))
  305. ((struct . ,type) (struct->init-fields type))
  306. ((union . ,type) (list (car (type:description type))))
  307. (_ (list o))))
  308. (define (byte->hex.m1 o)
  309. (string-drop o 2))
  310. (define (asm->m1 o)
  311. (let ((prefix ".byte "))
  312. (if (not (string-prefix? prefix o)) (map (cut string-split <> #\space) (string-split o #\newline))
  313. (let ((s (string-drop o (string-length prefix))))
  314. (list (format #f "'~a'" (string-join (map byte->hex.m1 (cdr (string-split o #\space))) " ")))))))
  315. (define (ident->variable info o)
  316. (or (assoc-ref (.locals info) o)
  317. (assoc-ref (.statics info) o)
  318. (assoc-ref (filter (negate static-global?) (.globals info)) o)
  319. (assoc-ref (.constants info) o)
  320. (assoc-ref (.functions info) o)
  321. (begin
  322. (error "ident->variable: undefined variable:" o))))
  323. (define (static-global? o)
  324. ((compose global:function cdr) o))
  325. (define (string-global? o)
  326. (and (pair? (car o))
  327. (eq? (caar o) #:string)))
  328. (define (ident->type info o)
  329. (let ((var (ident->variable info o)))
  330. (cond ((global? var) (global:type var))
  331. ((local? var) (local:type var))
  332. ((function? var) (function:type var))
  333. ((assoc-ref (.constants info) o) (assoc-ref (.types info) "default"))
  334. ((pair? var) (car var))
  335. (else (format (current-error-port) "error: ident->type ~s => ~s\n" o var)
  336. #f))))
  337. (define (local:pointer o)
  338. (->rank o))
  339. (define (ident->rank info o)
  340. (->rank (ident->variable info o)))
  341. (define (ident->size info o)
  342. ((compose type:size (cut ident->type info <>)) o))
  343. (define (pointer->rank o)
  344. (pmatch o
  345. ((pointer) 1)
  346. ((pointer ,pointer) (1+ (pointer->rank pointer)))))
  347. (define (expr->rank info o)
  348. (->rank (ast->type o info)))
  349. (define (ast->size o info)
  350. (->size (ast->type o info) info))
  351. (define (append-text info text)
  352. (clone info #:text (append (.text info) text)))
  353. (define (make-global-entry name storage type value)
  354. (cons name (make-global name type value storage #f)))
  355. (define (string->global-entry string)
  356. (let ((value (append (string->list string) (list #\nul))))
  357. (make-global-entry `(#:string ,string) '() "char" value)))
  358. (define (make-local-entry name type id)
  359. (cons name (make-local name type id)))
  360. (define* (mescc:trace-verbose name #:optional (type ""))
  361. (format (current-error-port) " :~a~a\n" name type))
  362. (define* (mescc:trace name #:optional (type ""))
  363. #t)
  364. (define (expr->arg o i info)
  365. (pmatch o
  366. ((p-expr (string ,string))
  367. (let* ((globals ((globals:add-string (.globals info)) string))
  368. (info (clone info #:globals globals))
  369. (info (allocate-register info))
  370. (info (append-text info (wrap-as (as info 'label->arg `(#:string ,string) i))))
  371. (no-swap? (zero? (.pushed info)))
  372. (info (if (cc-amd? info) info (free-register info)))
  373. (info (if no-swap? info
  374. (append-text info (wrap-as (as info 'swap-r1-stack))))))
  375. info))
  376. (_ (let* ((info (expr->register o info))
  377. (info (append-text info (wrap-as (as info 'r->arg i))))
  378. (no-swap? (zero? (.pushed info)))
  379. (info (if (cc-amd? info) info (free-register info)))
  380. (info (if no-swap? info
  381. (append-text info (wrap-as (as info 'swap-r1-stack))))))
  382. info))))
  383. (define (globals:add-string globals)
  384. (lambda (o)
  385. (let ((string `(#:string ,o)))
  386. (if (assoc-ref globals string) globals
  387. (append globals (list (string->global-entry o)))))))
  388. (define (ident->r info)
  389. (lambda (o)
  390. (cond ((assoc-ref (.locals info) o) => (cut local->r <> info))
  391. ((assoc-ref (.statics info) o) => (cut global->r <> info))
  392. ((assoc-ref (filter (negate static-global?) (.globals info)) o) => (cut global->r <> info))
  393. ((assoc-ref (.constants info) o) => (cut value->r <> info))
  394. (else (wrap-as (as info 'label->r `(#:address ,o)))))))
  395. (define (value->r o info)
  396. (wrap-as (as info 'value->r o)))
  397. (define (local->r o info)
  398. (let* ((type (local:type o)))
  399. (cond ((or (c-array? type)
  400. (structured-type? type))
  401. (wrap-as (as info 'local-ptr->r (local:id o))))
  402. (else (append (wrap-as (as info 'local->r (local:id o)))
  403. (convert-r0 info type))))))
  404. (define (global->r o info)
  405. (let ((type (global:type o)))
  406. (cond ((or (c-array? type)
  407. (structured-type? type)) (wrap-as (as info 'label->r `(#:address ,o))))
  408. (else (append (wrap-as (as info 'label-mem->r `(#:address ,o)))
  409. (convert-r0 info type))))))
  410. (define (ident-address->r info)
  411. (lambda (o)
  412. (cond ((assoc-ref (.locals info) o)
  413. =>
  414. (lambda (local) (wrap-as (as info 'local-ptr->r (local:id local)))))
  415. ((assoc-ref (.statics info) o)
  416. =>
  417. (lambda (global) (wrap-as (as info 'label->r `(#:address ,global)))))
  418. ((assoc-ref (filter (negate static-global?) (.globals info)) o)
  419. =>
  420. (lambda (global) (wrap-as (as info 'label->r `(#:address ,global)))))
  421. (else (wrap-as (as info 'label->r `(#:address ,o)))))))
  422. (define (r->local+n-text info local n)
  423. (let* ((id (local:id local))
  424. (type (local:type local))
  425. (type* (cond
  426. ((pointer? type) type)
  427. ((c-array? type) (c-array:type type))
  428. ((type? type) type)
  429. (else
  430. (format (current-error-port) "unexpected type: ~s\n" type)
  431. type)))
  432. (size (->size type* info))
  433. (reg-size (->size "*" info))
  434. (size (if (= size reg-size) 0 size)))
  435. (case size
  436. ((0) (wrap-as (as info 'r->local+n id n)))
  437. ((1) (wrap-as (as info 'byte-r->local+n id n)))
  438. ((2) (wrap-as (as info 'word-r->local+n id n)))
  439. ((4) (wrap-as (as info 'long-r->local+n id n)))
  440. (else
  441. (format (current-error-port) "unexpected size:~s\n" size)
  442. (wrap-as (as info 'r->local+n id n))))))
  443. (define (r->ident info)
  444. (lambda (o)
  445. (cond ((assoc-ref (.locals info) o)
  446. =>
  447. (lambda (local) (let ((size (->size local info))
  448. (r-size (->size "*" info)))
  449. (wrap-as (as info 'r->local (local:id local))))))
  450. ((assoc-ref (.statics info) o)
  451. =>
  452. (lambda (global) (let* ((size (->size global info))
  453. (reg-size (->size "*" info))
  454. (size (if (= size reg-size) 0 size)))
  455. (case size
  456. ((0) (wrap-as (as info 'r->label global)))
  457. ((1) (wrap-as (as info 'r->byte-label global)))
  458. ((2) (wrap-as (as info 'r->word-label global)))
  459. ((4) (wrap-as (as info 'r->long-label global)))
  460. (else (wrap-as (as info 'r->label global)))))))
  461. ((assoc-ref (filter (negate static-global?) (.globals info)) o)
  462. =>
  463. (lambda (global) (let* ((size (->size global info))
  464. (reg-size (->size "*" info))
  465. (size (if (= size reg-size) 0 size)))
  466. (case size
  467. ((0) (wrap-as (as info 'r->label global)))
  468. ((1) (wrap-as (as info 'r->byte-label global)))
  469. ((2) (wrap-as (as info 'r->word-label global)))
  470. ((4) (wrap-as (as info 'r->long-label global)))
  471. (else (wrap-as (as info 'r->label global))))))))))
  472. (define (ident-add info)
  473. (lambda (o n)
  474. (cond ((assoc-ref (.locals info) o)
  475. =>
  476. (lambda (local) (wrap-as (as info 'local-add (local:id local) n))))
  477. ((assoc-ref (.statics info) o)
  478. =>
  479. (lambda (global)
  480. (let* ((size (->size global info))
  481. (reg-size (->size "*" info))
  482. (size (if (= size reg-size) 0 size)))
  483. (case size
  484. ((0) (wrap-as (as info 'label-mem-add `(#:address ,o) n)))
  485. ((1) (wrap-as (as info 'byte-label-mem-add `(#:address ,o) n)))
  486. ((2) (wrap-as (as info 'word-label-mem-add `(#:address ,o) n)))
  487. ((4) (wrap-as (as info 'long-mem-add `(#:address ,o) n)))
  488. (else (as info 'label-mem-add `(#:address ,o) n))))))
  489. ((assoc-ref (filter (negate static-global?) (.globals info)) o)
  490. =>
  491. (lambda (global)
  492. (let* ((size (->size global info))
  493. (reg-size (->size "*" info))
  494. (size (if (= size reg-size) 0 size)))
  495. (case size
  496. ((0) (wrap-as (as info 'label-mem-add `(#:address ,o) n)))
  497. ((1) (wrap-as (as info 'byte-label-mem-add `(#:address ,o) n)))
  498. ((2) (wrap-as (as info 'word-label-mem-add `(#:address ,o) n)))
  499. ((4) (wrap-as (as info 'long-mem-add `(#:address ,o) n)))
  500. (else (as info 'label-mem-add `(#:address ,o) n)))))))))
  501. (define (make-comment o)
  502. (wrap-as `((#:comment ,o))))
  503. (define (ast->comment o)
  504. (if mes-or-reproducible? '()
  505. (let* ((source (with-output-to-string (lambda () (pretty-print-c99 o))))
  506. ;; Nyacc fixups
  507. (source (string-substitute source "\\" "\\\\"))
  508. (source (string-substitute source "'\\'" "'\\\\'"))
  509. (source (string-substitute source "'\"'" "'\\\"'"))
  510. (source (string-substitute source "'''" "'\\''"))
  511. (source (string-substitute source "\n" "\\n"))
  512. (source (string-substitute source "\r" "\\r")))
  513. (make-comment source))))
  514. (define (r*n info n)
  515. (case n
  516. ((1) info)
  517. ((2) (append-text info (wrap-as (as info 'r+r))))
  518. ((3) (let* ((info (allocate-register info))
  519. (info (append-text info (wrap-as (append (as info 'r0->r1)
  520. (as info 'r+r)
  521. (as info 'r0+r1)))))
  522. (info (free-register info)))
  523. info))
  524. ((4) (append-text info (wrap-as (as info 'shl-r 2))))
  525. ((5) (let* ((info (allocate-register info))
  526. (info (append-text info (wrap-as (append (as info 'r0->r1)
  527. (as info 'r+r)
  528. (as info 'r+r)
  529. (as info 'r0+r1)))))
  530. (info (free-register info)))
  531. info))
  532. ((6) (let* ((info (allocate-register info))
  533. (info (append-text info (wrap-as (append (as info 'r0->r1)
  534. (as info 'r+r)
  535. (as info 'r0+r1)))))
  536. (info (free-register info))
  537. (info (append-text info (wrap-as (append (as info 'shl-r 1))))))
  538. info))
  539. ((8) (append-text info (wrap-as (append (as info 'shl-r 3)))))
  540. ((10) (let* ((info (allocate-register info))
  541. (info (append-text info (wrap-as (append (as info 'r0->r1)
  542. (as info 'r+r)
  543. (as info 'r+r)
  544. (as info 'r0+r1)))))
  545. (info (free-register info))
  546. (info (append-text info (wrap-as (append (as info 'shl-r 1))))))
  547. info))
  548. ((12) (let* ((info (allocate-register info))
  549. (info (append-text info (wrap-as (append (as info 'r0->r1)
  550. (as info 'r+r)
  551. (as info 'r0+r1)))))
  552. (info (free-register info))
  553. (info (append-text info (wrap-as (append (as info 'shl-r 2))))))
  554. info))
  555. ((16) (append-text info (wrap-as (as info 'shl-r 4))))
  556. ((20) (let* ((info (allocate-register info))
  557. (info (append-text info (wrap-as (append (as info 'r0->r1)
  558. (as info 'r+r)
  559. (as info 'r+r)
  560. (as info 'r0+r1)))))
  561. (info (free-register info))
  562. (info (append-text info (wrap-as (append (as info 'shl-r 2))))))
  563. info))
  564. ((24) (let* ((info (allocate-register info))
  565. (info (append-text info (wrap-as (append (as info 'r0->r1)
  566. (as info 'r+r)
  567. (as info 'r0+r1)))))
  568. (info (free-register info))
  569. (info (append-text info (wrap-as (append (as info 'shl-r 3))))))
  570. info))
  571. (else (let* ((info (allocate-register info))
  572. (info (append-text info (wrap-as (as info 'value->r n))))
  573. (info (append-text info (wrap-as (as info 'r0*r1))))
  574. (info (free-register info)))
  575. info))))
  576. (define (allocate-register info)
  577. (let ((registers (.registers info))
  578. (allocated (.allocated info)))
  579. (if (< (length allocated) (max-registers info))
  580. (clone info #:allocated (cons (car registers) (.allocated info)) #:registers (cdr registers))
  581. (let* ((info (clone info #:pushed (1+ (.pushed info))))
  582. (info (append-text info (wrap-as (append (as info 'push-r0)
  583. (as info 'r1->r0))))))
  584. info))))
  585. (define (free-register info)
  586. (let ((allocated (.allocated info))
  587. (pushed (.pushed info)))
  588. (if (zero? pushed)
  589. (clone info #:allocated (cdr allocated) #:registers (cons (car allocated) (.registers info)))
  590. (let* ((info (clone info #:pushed (1- pushed)))
  591. (info (append-text info (wrap-as (append (as info 'r0->r1)
  592. (as info 'pop-r0))))))
  593. info))))
  594. (define (push-register r info)
  595. (append-text info (wrap-as (as info 'push-register r))))
  596. (define (pop-register r info)
  597. (append-text info (wrap-as (as info 'pop-register r))))
  598. (define (r0->r1-mem*n- info n size)
  599. (let ((reg-size (->size "*" info)))
  600. (wrap-as
  601. (cond
  602. ((= n 1) (as info 'byte-r0->r1-mem))
  603. ((= n 2) (cond ((= size 1) (append (as info 'byte-r0->r1-mem)
  604. (as info 'r+value 1)
  605. (as info 'value->r0 0)
  606. (as info 'byte-r0->r1-mem)))
  607. (else (as info 'word-r0->r1-mem))))
  608. ((= n 4) (as info 'long-r0->r1-mem))
  609. ((and (= n 8) (or (= reg-size 8)
  610. (= size 4)))
  611. (cond ((= size 4) (append (as info 'long-r0->r1-mem)
  612. (as info 'r+value 4)
  613. (as info 'value->r0 0)
  614. (as info 'long-r0->r1-mem)))
  615. ((and (= size 8) (= reg-size 8)) (as info 'quad-r0->r1-mem))
  616. (else (error "r0->r1-mem*n-: not supported"))))
  617. (else (let loop ((i 0))
  618. (if (>= i n) '()
  619. (case (- n i)
  620. ((1) (as info 'byte-r0-mem->r1-mem))
  621. ((2) (as info 'word-r0-mem->r1-mem))
  622. ((3) (append (as info 'word-r0-mem->r1-mem)
  623. (as info 'r+value 2)
  624. (as info 'r0+value 2)
  625. (loop (+ i 2))))
  626. ((4) (append (as info 'long-r0-mem->r1-mem)))
  627. (else (append (as info 'r0-mem->r1-mem)
  628. (as info 'r+value reg-size)
  629. (as info 'r0+value reg-size)
  630. (loop (+ i reg-size))))))))))))
  631. (define (r0->r1-mem*n info n size)
  632. (append-text info (r0->r1-mem*n- info n size)))
  633. (define (expr->register* o info)
  634. (pmatch o
  635. ((p-expr (ident ,name))
  636. (let ((info (allocate-register info)))
  637. (append-text info ((ident-address->r info) name))))
  638. ((de-ref ,expr)
  639. (expr->register expr info))
  640. ((d-sel (ident ,field) ,struct)
  641. (let* ((type (ast->basic-type struct info))
  642. (offset (field-offset info type field))
  643. (info (expr->register* struct info)))
  644. (append-text info (wrap-as (as info 'r+value offset)))))
  645. ((i-sel (ident ,field) (fctn-call (p-expr (ident ,function)) . ,rest))
  646. (let* ((type (ast->basic-type `(fctn-call (p-expr (ident ,function)) ,@rest) info))
  647. (offset (field-offset info type field))
  648. (info (expr->register `(fctn-call (p-expr (ident ,function)) ,@rest) info)))
  649. (append-text info (wrap-as (as info 'r+value offset)))))
  650. ((i-sel (ident ,field) ,struct)
  651. (let* ((type (ast->basic-type struct info))
  652. (offset (field-offset info type field))
  653. (info (expr->register* struct info))
  654. (type (ast->type struct info)))
  655. (append-text info (append (if (c-array? type) '()
  656. (wrap-as (as info 'mem->r)))
  657. (wrap-as (as info 'r+value offset))))))
  658. ((array-ref ,index ,array)
  659. (let* ((info (expr->register index info))
  660. (size (ast->size o info))
  661. (info (r*n info size))
  662. (info (expr->register array info))
  663. (info (append-text info (wrap-as (as info 'r0+r1))))
  664. (info (free-register info)))
  665. info))
  666. ((cast ,type ,expr)
  667. (expr->register `(ref-to ,expr) info))
  668. ((add ,a ,b)
  669. (let* ((rank (expr->rank info a))
  670. (rank-b (expr->rank info b))
  671. (type (ast->basic-type a info))
  672. (struct? (structured-type? type))
  673. (reg-size (->size "*" info))
  674. (size (cond ((= rank 1) (ast-type->size info a))
  675. ((> rank 1) reg-size)
  676. ((and struct? (= rank 2)) reg-size)
  677. (else 1))))
  678. (if (or (= size 1)) ((binop->r* info) a b 'r0+r1)
  679. (let* ((info (expr->register b info))
  680. (info (allocate-register info))
  681. (info (append-text info (wrap-as (append (as info 'value->r size)
  682. (as info 'r0*r1)))))
  683. (info (free-register info))
  684. (info (expr->register* a info))
  685. (info (append-text info (wrap-as (as info 'r0+r1))))
  686. (info (free-register info)))
  687. info))))
  688. ((sub ,a ,b)
  689. (let* ((rank (expr->rank info a))
  690. (rank-b (expr->rank info b))
  691. (type (ast->basic-type a info))
  692. (struct? (structured-type? type))
  693. (size (->size type info))
  694. (reg-size (->size "*" info))
  695. (size (cond ((= rank 1) size)
  696. ((> rank 1) reg-size)
  697. ((and struct? (= rank 2)) reg-size)
  698. (else 1))))
  699. (if (or (= size 1) (or (= rank-b 2) (= rank-b 1)))
  700. (let ((info ((binop->r* info) a b 'r0-r1)))
  701. (if (and (not (= rank-b 2)) (not (= rank-b 1))) info
  702. ;; FIXME: c&p 1158
  703. (let* ((info (allocate-register info))
  704. (info (append-text info (wrap-as (append
  705. (as info 'value->r size)
  706. (as info 'swap-r0-r1)
  707. (as info 'r0/r1 #f)))))
  708. (info (append-text info (wrap-as (append (as info 'swap-r0-r1)))))
  709. (free-register info))
  710. info)))
  711. (let* ((info (expr->register* b info))
  712. (info (allocate-register info))
  713. (info (append-text info (wrap-as (append (as info 'value->r size)
  714. (as info 'r0*r1)))))
  715. (info (free-register info))
  716. (info (expr->register* a info))
  717. (info (append-text info (wrap-as (append (as info 'swap-r0-r1)))))
  718. (info (append-text info (wrap-as (as info 'r0-r1))))
  719. (info (free-register info)))
  720. info))))
  721. ((post-dec ,expr)
  722. (let* ((info (expr->register* expr info))
  723. (post (clone info #:text '()))
  724. (post (allocate-register post))
  725. (post (append-text post (wrap-as (as post 'r0->r1))))
  726. (rank (expr->rank post expr))
  727. (reg-size (->size "*" info))
  728. (size (cond ((= rank 1) (ast-type->size post expr))
  729. ((> rank 1) reg-size)
  730. (else 1)))
  731. (post ((expr-add post) expr (- size))))
  732. (clone info #:post (.text post))))
  733. ((post-inc ,expr)
  734. (let* ((info (expr->register* expr info))
  735. (post (clone info #:text '()))
  736. (post (allocate-register post))
  737. (post (append-text post (wrap-as (as post 'r0->r1))))
  738. (rank (expr->rank post expr))
  739. (reg-size (->size "*" info))
  740. (size (cond ((= rank 1) (ast-type->size post expr))
  741. ((> rank 1) reg-size)
  742. (else 1)))
  743. (post ((expr-add post) expr size)))
  744. (clone info #:post (.text post))))
  745. ((pre-dec ,expr)
  746. (let* ((rank (expr->rank info expr))
  747. (reg-size (->size "*" info))
  748. (size (cond ((= rank 1) (ast-type->size info expr))
  749. ((> rank 1) reg-size)
  750. (else 1)))
  751. (info ((expr-add info) expr (- size)))
  752. (info (append (expr->register* expr info))))
  753. info))
  754. ((pre-inc ,expr)
  755. (let* ((rank (expr->rank info expr))
  756. (reg-size (->size "*" info))
  757. (size (cond ((= rank 1) (ast-type->size info expr))
  758. ((> rank 1) reg-size)
  759. (else 1)))
  760. (info ((expr-add info) expr size))
  761. (info (append (expr->register* expr info))))
  762. info))
  763. (_ (error "expr->register*: not supported: " o))))
  764. (define (expr-add info)
  765. (lambda (o n)
  766. (let* ((info (expr->register* o info))
  767. (size (ast->size o info))
  768. (reg-size (->size "*" info))
  769. (size (if (= size reg-size) 0 size))
  770. (info (append-text info (wrap-as (append (as info
  771. (case size
  772. ((0) 'r-mem-add)
  773. ((1) 'r-byte-mem-add)
  774. ((2) 'r-word-mem-add)
  775. ((4) 'r-long-mem-add)) n))))))
  776. (free-register info))))
  777. (define (expr->register o info)
  778. (let* ((locals (.locals info))
  779. (text (.text info))
  780. (globals (.globals info))
  781. (r-size (->size "*" info)))
  782. (define (helper)
  783. (pmatch o
  784. ((expr) info)
  785. ((comma-expr)
  786. (allocate-register info))
  787. ((comma-expr ,a . ,rest)
  788. (let* ((info (expr->register a info))
  789. (info (free-register info)))
  790. (expr->register `(comma-expr ,@rest) info)))
  791. ((p-expr (string ,string))
  792. (let* ((globals ((globals:add-string globals) string))
  793. (info (clone info #:globals globals))
  794. (info (allocate-register info)))
  795. (append-text info (wrap-as (as info 'label->r `(#:string ,string))))))
  796. ((p-expr (string . ,strings))
  797. (let* ((string (apply string-append strings))
  798. (globals ((globals:add-string globals) string))
  799. (info (clone info #:globals globals))
  800. (info (allocate-register info)))
  801. (append-text info (wrap-as (as info 'label->r `(#:string ,string))))))
  802. ((p-expr (fixed ,value))
  803. (let* ((value (cstring->int value))
  804. (reg-size (->size "*" info))
  805. (info (allocate-register info))
  806. (info (append-text info (wrap-as (as info 'value->r value)))))
  807. (if (or #t (> value 0) (= reg-size 4)) info
  808. (append-text info (wrap-as (as info 'long-signed-r))))))
  809. ((p-expr (float ,value))
  810. (let ((value (cstring->float value))
  811. (info (allocate-register info)))
  812. (append-text info (wrap-as (as info 'value->r value)))))
  813. ((neg (p-expr (fixed ,value)))
  814. (let* ((value (- (cstring->int value)))
  815. (info (allocate-register info))
  816. (info (append-text info (append (wrap-as (as info 'value->r value)))))
  817. (reg-size (->size "*" info)))
  818. (if (or #t (> value 0) (= reg-size 4)) info
  819. (append-text info (wrap-as (as info 'long-signed-r))))))
  820. ((p-expr (char ,char))
  821. (let ((char (char->integer (car (string->list char))))
  822. (info (allocate-register info)))
  823. (append-text info (wrap-as (as info 'value->r char)))))
  824. (,char (guard (char? char))
  825. (let ((info (allocate-register info)))
  826. (append-text info (wrap-as (as info 'value->r (char->integer char))))))
  827. ((p-expr (ident ,name))
  828. (let ((info (allocate-register info)))
  829. (append-text info ((ident->r info) name))))
  830. ((initzer ,initzer)
  831. (expr->register initzer info))
  832. (((initzer ,initzer))
  833. (expr->register initzer info))
  834. ;; offsetoff
  835. ((ref-to (i-sel (ident ,field) (cast (type-name (decl-spec-list ,struct) (abs-declr (pointer))) (p-expr (fixed ,base)))))
  836. (let* ((type (ast->basic-type struct info))
  837. (offset (field-offset info type field))
  838. (base (cstring->int base))
  839. (info (allocate-register info)))
  840. (append-text info (wrap-as (as info 'value->r (+ base offset))))))
  841. ;; &foo
  842. ((ref-to (p-expr (ident ,name)))
  843. (let ((info (allocate-register info)))
  844. (append-text info ((ident-address->r info) name))))
  845. ;; &*foo
  846. ((ref-to (de-ref ,expr))
  847. (expr->register expr info))
  848. ((ref-to ,expr)
  849. (expr->register* expr info))
  850. ((sizeof-expr ,expr)
  851. (let ((info (allocate-register info)))
  852. (append-text info (wrap-as (as info 'value->r (ast->size expr info))))))
  853. ((sizeof-type ,type)
  854. (let ((info (allocate-register info)))
  855. (append-text info (wrap-as (as info 'value->r (ast->size type info))))))
  856. ((array-ref ,index ,array)
  857. (let* ((info (expr->register* o info))
  858. (type (ast->type o info)))
  859. (append-text info (mem->r type info))))
  860. ((d-sel ,field ,struct)
  861. (let* ((info (expr->register* o info))
  862. (info (append-text info (ast->comment o)))
  863. (type (ast->type o info))
  864. (size (->size type info))
  865. (array? (c-array? type)))
  866. (if array? info
  867. (append-text info (mem->r type info)))))
  868. ((i-sel ,field ,struct)
  869. (let* ((info (expr->register* o info))
  870. (info (append-text info (ast->comment o)))
  871. (type (ast->type o info))
  872. (size (->size type info))
  873. (array? (c-array? type)))
  874. (if array? info
  875. (append-text info (mem->r type info)))))
  876. ((de-ref ,expr)
  877. (let* ((info (expr->register expr info))
  878. (type (ast->type o info)))
  879. (append-text info (mem->r type info))))
  880. ((fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list))
  881. (if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list))))
  882. (append-text info (wrap-as (asm->m1 arg0))))
  883. (let* ((info (append-text info (ast->comment o)))
  884. (info (allocate-register info))
  885. (allocated (.allocated info))
  886. (pushed (.pushed info))
  887. (registers (.registers info))
  888. (info (fold push-register info (cdr allocated)))
  889. (reg-size (->size "*" info))
  890. (info (if (cc-amd? info) (fold expr->arg info expr-list (iota (length expr-list)))
  891. (fold-right expr->arg info expr-list (reverse (iota (length expr-list))))))
  892. (info (clone info #:allocated '() #:pushed 0 #:registers (append (reverse allocated) registers)))
  893. (n (length expr-list))
  894. (info (if (not (assoc-ref locals name))
  895. (begin
  896. (when (and (not (assoc name (.functions info)))
  897. (not (assoc name globals))
  898. (not (equal? name (.function info))))
  899. (format (current-error-port) "warning: undeclared function: ~a\n" name))
  900. (append-text info (wrap-as (as info 'call-label name n))))
  901. (let* ((info (expr->register `(p-expr (ident ,name)) info))
  902. (info (append-text info (wrap-as (as info 'call-r n)))))
  903. info)))
  904. (info (clone info #:allocated allocated #:pushed pushed #:registers registers))
  905. (info (if (null? (cdr allocated)) info
  906. (append-text info (wrap-as (as info 'return->r)))))
  907. (info (fold-right pop-register info (cdr allocated))))
  908. info)))
  909. ((fctn-call ,function (expr-list . ,expr-list))
  910. (let* ((info (append-text info (ast->comment o)))
  911. (info (allocate-register info))
  912. (allocated (.allocated info))
  913. (pushed (.pushed info))
  914. (registers (.registers info))
  915. (info (fold push-register info (cdr allocated)))
  916. (reg-size (->size "*" info))
  917. (info (if (cc-amd? info) (fold expr->arg info expr-list (iota (length expr-list)))
  918. (fold-right expr->arg info expr-list (reverse (iota (length expr-list))))))
  919. (info (fold (lambda (x info) (free-register info)) info (.allocated info)))
  920. (n (length expr-list))
  921. (function (pmatch function
  922. ((de-ref ,function) function)
  923. (_ function)))
  924. (info (expr->register function info))
  925. (info (append-text info (wrap-as (as info 'call-r n))))
  926. (info (free-register info))
  927. (info (clone info #:allocated allocated #:pushed pushed #:registers registers))
  928. (info (if (null? (cdr allocated)) info
  929. (append-text info (wrap-as (as info 'return->r)))))
  930. (info (fold-right pop-register info (cdr allocated))))
  931. info))
  932. ((cond-expr ,test ,then ,else)
  933. (let* ((info (append-text info (ast->comment `(cond-expr ,test (ellipsis) (ellipsis)))))
  934. (here (number->string (length text)))
  935. (label (string-append "_" (.function info) "_" here "_"))
  936. (else-label (string-append label "else"))
  937. (break-label (string-append label "break"))
  938. (info ((test-jump-label->info info else-label) test))
  939. (info (expr->register then info))
  940. (info (free-register info))
  941. (info (append-text info (wrap-as (as info 'jump break-label))))
  942. (info (append-text info (wrap-as `((#:label ,else-label)))))
  943. (info (expr->register else info))
  944. (info (free-register info))
  945. (info (append-text info (wrap-as `((#:label ,break-label)))))
  946. (info (allocate-register info)))
  947. info))
  948. ((post-inc ,expr)
  949. (let* ((info (append (expr->register expr info)))
  950. (rank (expr->rank info expr))
  951. (reg-size (->size "*" info))
  952. (size (cond ((= rank 1) (ast-type->size info expr))
  953. ((> rank 1) reg-size)
  954. (else 1)))
  955. (info ((expr-add info) expr size)))
  956. info))
  957. ((post-dec ,expr)
  958. (let* ((info (append (expr->register expr info)))
  959. (rank (expr->rank info expr))
  960. (reg-size (->size "*" info))
  961. (size (cond ((= rank 1) (ast-type->size info expr))
  962. ((> rank 1) reg-size)
  963. (else 1)))
  964. (info ((expr-add info) expr (- size))))
  965. info))
  966. ((pre-inc ,expr)
  967. (let* ((rank (expr->rank info expr))
  968. (reg-size (->size "*" info))
  969. (size (cond ((= rank 1) (ast-type->size info expr))
  970. ((> rank 1) reg-size)
  971. (else 1)))
  972. (info ((expr-add info) expr size))
  973. (info (append (expr->register expr info))))
  974. info))
  975. ((pre-dec ,expr)
  976. (let* ((rank (expr->rank info expr))
  977. (reg-size (->size "*" info))
  978. (size (cond ((= rank 1) (ast-type->size info expr))
  979. ((> rank 1) reg-size)
  980. (else 1)))
  981. (info ((expr-add info) expr (- size)))
  982. (info (append (expr->register expr info))))
  983. info))
  984. ((add ,a (p-expr (fixed ,value)))
  985. (let* ((rank (expr->rank info a))
  986. (type (ast->basic-type a info))
  987. (struct? (structured-type? type))
  988. (reg-size (->size "*" info))
  989. (size (cond ((= rank 1) (ast-type->size info a))
  990. ((> rank 1) reg-size)
  991. ((and struct? (= rank 2)) reg-size)
  992. (else 1)))
  993. (info (expr->register a info))
  994. (value (cstring->int value))
  995. (value (* size value)))
  996. (append-text info (wrap-as (as info 'r+value value)))))
  997. ((add ,a ,b)
  998. (let* ((rank (expr->rank info a))
  999. (rank-b (expr->rank info b))
  1000. (type (ast->basic-type a info))
  1001. (struct? (structured-type? type))
  1002. (reg-size (->size "*" info))
  1003. (size (cond ((= rank 1) (ast-type->size info a))
  1004. ((> rank 1) reg-size)
  1005. ((and struct? (= rank 2)) reg-size)
  1006. (else 1))))
  1007. (if (or (= size 1)) ((binop->r info) a b 'r0+r1)
  1008. (let* ((info (expr->register b info))
  1009. (info (allocate-register info))
  1010. (info (append-text info (wrap-as (append (as info 'value->r size)
  1011. (as info 'r0*r1)))))
  1012. (info (free-register info))
  1013. (info (expr->register a info))
  1014. (info (append-text info (wrap-as (as info 'r0+r1))))
  1015. (info (free-register info)))
  1016. info))))
  1017. ((sub ,a (p-expr (fixed ,value)))
  1018. (let* ((rank (expr->rank info a))
  1019. (type (ast->basic-type a info))
  1020. (struct? (structured-type? type))
  1021. (size (->size type info))
  1022. (reg-size (->size "*" info))
  1023. (size (cond ((= rank 1) size)
  1024. ((> rank 1) reg-size)
  1025. ((and struct? (= rank 2)) reg-size)
  1026. (else 1)))
  1027. (info (expr->register a info))
  1028. (value (cstring->int value))
  1029. (value (* size value)))
  1030. (append-text info (wrap-as (as info 'r+value (- value))))))
  1031. ((sub ,a ,b)
  1032. (let* ((rank (expr->rank info a))
  1033. (rank-b (expr->rank info b))
  1034. (type (ast->basic-type a info))
  1035. (struct? (structured-type? type))
  1036. (size (->size type info))
  1037. (reg-size (->size "*" info))
  1038. (size (cond ((= rank 1) size)
  1039. ((> rank 1) reg-size)
  1040. ((and struct? (= rank 2)) reg-size)
  1041. (else 1))))
  1042. (if (or (= size 1) (or (= rank-b 2) (= rank-b 1)))
  1043. (let ((info ((binop->r info) a b 'r0-r1)))
  1044. (if (and (not (= rank-b 2)) (not (= rank-b 1))) info
  1045. ;; FIXME: c&p 792
  1046. (let* ((info (allocate-register info))
  1047. (info (append-text info (wrap-as (append (as info 'value->r size)
  1048. (as info 'r0/r1 #f)))))
  1049. (info (free-register info)))
  1050. info)))
  1051. (let* ((info (expr->register b info))
  1052. (info (allocate-register info))
  1053. (info (append-text info (wrap-as (append (as info 'value->r size)
  1054. (as info 'r0*r1)))))
  1055. (info (free-register info))
  1056. (info (expr->register a info))
  1057. (info (append-text info (wrap-as (append (as info 'swap-r0-r1)))))
  1058. (info (append-text info (wrap-as (as info 'r0-r1))))
  1059. (info (free-register info)))
  1060. info))))
  1061. ((bitwise-and ,a ,b) ((binop->r info) a b 'r0-and-r1))
  1062. ((bitwise-not ,expr)
  1063. (let ((info (expr->register expr info)))
  1064. (append-text info (wrap-as (as info 'not-r)))))
  1065. ((bitwise-or ,a ,b) ((binop->r info) a b 'r0-or-r1))
  1066. ((bitwise-xor ,a ,b) ((binop->r info) a b 'r0-xor-r1))
  1067. ((lshift ,a ,b) ((binop->r info) a b 'r0<<r1))
  1068. ((rshift ,a ,b) ((binop->r info) a b 'r0>>r1))
  1069. ((div ,a ,b)
  1070. ((binop->r info) a b 'r0/r1
  1071. (signed? (ast->type a info))))
  1072. ((mod ,a ,b) ((binop->r info) a b 'r0%r1
  1073. (signed? (ast->type a info))))
  1074. ((mul ,a ,b) ((binop->r info) a b 'r0*r1))
  1075. ((not ,expr)
  1076. (let* ((info (expr->register expr info))
  1077. (info (append-text info (wrap-as (as info 'test-r))))
  1078. (info (append-text info (wrap-as (as info 'r-negate)))))
  1079. (append-text info (wrap-as (as info 'test-r))))) ;; hmm, use ast->info?
  1080. ((pos ,expr)
  1081. (expr->register expr info))
  1082. ((neg ,expr)
  1083. (let* ((info (expr->register expr info))
  1084. (info (allocate-register info))
  1085. (info (append-text info (append (wrap-as (as info 'value->r 0))
  1086. (wrap-as (as info 'swap-r0-r1))
  1087. (wrap-as (as info 'r0-r1)))))
  1088. (info (free-register info)))
  1089. info))
  1090. ((eq ,a ,b) (let ((info ((binop->r info) a b 'r0-r1)))
  1091. (append-text info (wrap-as (as info 'zf->r)))))
  1092. ((ge ,a ,b)
  1093. (let* ((type-a (ast->type a info))
  1094. (type-b (ast->type b info))
  1095. (info ((binop->r info) a b 'r0-r1))
  1096. (test->r (if (or (unsigned? type-a) (unsigned? type-b)) 'ae?->r 'ge?->r))
  1097. (info (append-text info (wrap-as (as info test->r))))
  1098. (info (append-text info (wrap-as (as info 'test-r)))))
  1099. info))
  1100. ((gt ,a ,b)
  1101. (let* ((type-a (ast->type a info))
  1102. (type-b (ast->type b info))
  1103. (info ((binop->r info) a b 'r0-r1))
  1104. (test->r (if (or (unsigned? type-a) (unsigned? type-b)) 'a?->r 'g?->r))
  1105. (info (append-text info (wrap-as (as info test->r))))
  1106. (info (append-text info (wrap-as (as info 'test-r)))))
  1107. info))
  1108. ((ne ,a ,b) (let* ((info ((binop->r info) a b 'r0-r1))
  1109. (info (append-text info (wrap-as (as info 'test-r))))
  1110. (info (append-text info (wrap-as (as info 'xor-zf))))
  1111. (info (append-text info (wrap-as (as info 'zf->r)))))
  1112. info))
  1113. ((le ,a ,b)
  1114. (let* ((type-a (ast->type a info))
  1115. (type-b (ast->type b info))
  1116. (info ((binop->r info) a b 'r0-r1))
  1117. (test->r (if (or (unsigned? type-a) (unsigned? type-b)) 'be?->r 'le?->r))
  1118. (info (append-text info (wrap-as (as info test->r))))
  1119. (info (append-text info (wrap-as (as info 'test-r)))))
  1120. info))
  1121. ((lt ,a ,b)
  1122. (let* ((type-a (ast->type a info))
  1123. (type-b (ast->type b info))
  1124. (info ((binop->r info) a b 'r0-r1))
  1125. (test->r (if (or (unsigned? type-a) (unsigned? type-b)) 'b?->r 'l?->r))
  1126. (info (append-text info (wrap-as (as info test->r))))
  1127. (info (append-text info (wrap-as (as info 'test-r)))))
  1128. info))
  1129. ((or ,a ,b)
  1130. (let* ((info (expr->register a info))
  1131. (here (number->string (length (.text info))))
  1132. (skip-b-label (string-append "_" (.function info) "_" here "_or_skip_b"))
  1133. (info (append-text info (wrap-as (as info 'test-r))))
  1134. (info (append-text info (wrap-as (as info 'jump-nz skip-b-label))))
  1135. (info (append-text info (wrap-as (as info 'test-r))))
  1136. (info (free-register info))
  1137. (info (expr->register b info))
  1138. (info (append-text info (wrap-as (as info 'test-r))))
  1139. (info (append-text info (wrap-as `((#:label ,skip-b-label))))))
  1140. info))
  1141. ((and ,a ,b)
  1142. (let* ((info (expr->register a info))
  1143. (here (number->string (length (.text info))))
  1144. (skip-b-label (string-append "_" (.function info) "_" here "_and_skip_b"))
  1145. (info (append-text info (wrap-as (as info 'test-r))))
  1146. (info (append-text info (wrap-as (as info 'jump-z skip-b-label))))
  1147. (info (append-text info (wrap-as (as info 'test-r))))
  1148. (info (free-register info))
  1149. (info (expr->register b info))
  1150. (info (append-text info (wrap-as (as info 'test-r))))
  1151. (info (append-text info (wrap-as `((#:label ,skip-b-label))))))
  1152. info))
  1153. ((cast ,type ,expr)
  1154. (let ((info (expr->register expr info))
  1155. (type (ast->type o info)))
  1156. (append-text info (convert-r0 info type))))
  1157. ((assn-expr (de-ref (post-inc (p-expr (ident ,name)))) (op ,op) ,b)
  1158. (let* ((info (expr->register `(assn-expr (de-ref (p-expr (ident ,name))) (op ,op) ,b) info))
  1159. (type (ident->type info name))
  1160. (rank (ident->rank info name))
  1161. (reg-size (->size "*" info))
  1162. (size (cond ((= rank 1) (ast-type->size info `(p-expr (ident ,name))))
  1163. ((> rank 1) reg-size)
  1164. (else 1))))
  1165. (append-text info ((ident-add info) name size))))
  1166. ((assn-expr (de-ref (post-dec (p-expr (ident ,name)))) (op ,op) ,b)
  1167. (let* ((info (expr->register `(assn-expr (de-ref (p-expr (ident ,name))) (op ,op) ,b) info))
  1168. (type (ident->type info name))
  1169. (rank (ident->rank info name))
  1170. (reg-size (->size "*" info))
  1171. (size (cond ((= rank 1) (ast-type->size info `(p-expr (ident ,name))))
  1172. ((> rank 1) reg-size)
  1173. (else 1))))
  1174. (append-text info ((ident-add info) name (- size)))))
  1175. ((assn-expr ,a (op ,op) ,b)
  1176. (let* ((info (append-text info (ast->comment o)))
  1177. (type (ast->type a info))
  1178. (rank (->rank type))
  1179. (type-b (ast->type b info))
  1180. (rank-b (->rank type-b))
  1181. (reg-size (->size "*" info))
  1182. (size (if (zero? rank) (->size type info) reg-size))
  1183. (size-b (if (zero? rank-b) (->size type-b info) reg-size))
  1184. (info (expr->register b info))
  1185. (info (if (equal? op "=") info
  1186. (let* ((struct? (structured-type? type))
  1187. (size (cond ((= rank 1) (ast-type->size info a))
  1188. ((> rank 1) reg-size)
  1189. ((and struct? (= rank 2)) reg-size)
  1190. (else 1)))
  1191. (info (if (or (= size 1) (= rank-b 1)) info
  1192. (let* ((info (allocate-register info))
  1193. (info (append-text info (wrap-as (as info 'value->r size))))
  1194. (info (append-text info (wrap-as (as info 'r0*r1))))
  1195. (info (free-register info)))
  1196. info)))
  1197. (info (expr->register a info))
  1198. (info (append-text info (wrap-as (as info 'swap-r0-r1))))
  1199. (signed? (signed? type))
  1200. (info (append-text info (cond ((equal? op "+=") (wrap-as (as info 'r0+r1)))
  1201. ((equal? op "-=") (wrap-as (as info 'r0-r1)))
  1202. ((equal? op "*=") (wrap-as (as info 'r0*r1)))
  1203. ((equal? op "/=") (wrap-as (as info 'r0/r1 signed?)))
  1204. ((equal? op "%=") (wrap-as (as info 'r0%r1 signed?)))
  1205. ((equal? op "&=") (wrap-as (as info 'r0-and-r1)))
  1206. ((equal? op "|=") (wrap-as (as info 'r0-or-r1)))
  1207. ((equal? op "^=") (wrap-as (as info 'r0-xor-r1)))
  1208. ((equal? op ">>=") (wrap-as (as info 'r0>>r1)))
  1209. ((equal? op "<<=") (wrap-as (as info 'r0<<r1)))
  1210. (else (error (format #f "mescc: op ~a not supported: ~a\n" op o))))))
  1211. (info (free-register info)))
  1212. (cond ((not (and (= rank 1) (= rank-b 1))) info)
  1213. ((equal? op "-=") (let* ((info (allocate-register info))
  1214. (info (append-text info (wrap-as (append (as info 'value->r size)
  1215. (as info 'r0/r1 signed?)))))
  1216. (info (free-register info)))
  1217. info))
  1218. (else (error (format #f "invalid operands to binary ~s (have ~s* and ~s*) " op type (ast->basic-type b info)))))))))
  1219. (when (and (equal? op "=")
  1220. (not (= size size-b))
  1221. (not (and (or (= size 1) (= size 2))
  1222. (or (= size-b 2) (= size-b 4) (= size-b reg-size))))
  1223. (not (and (= size 2)
  1224. (= size-b 4)))
  1225. (not (and (= size 2)
  1226. (= size-b reg-size)))
  1227. (not (and (= size reg-size)
  1228. (or (= size-b 1) (= size-b 2) (= size-b 4)))))
  1229. (format (current-error-port) "ERROR assign: ~a" (with-output-to-string (lambda () (pretty-print-c99 o))))
  1230. (format (current-error-port) " size[~a]:~a != size[~a]:~a\n" rank size rank-b size-b))
  1231. (pmatch a
  1232. ((p-expr (ident ,name))
  1233. (if (or (<= size r-size)
  1234. (<= size-b r-size)) (append-text info ((r->ident info) name))
  1235. (let* ((info (expr->register* a info))
  1236. (info (r0->r1-mem*n info size size-b)))
  1237. (free-register info))))
  1238. (_ (let* ((info (expr->register* a info))
  1239. (reg-size (->size "*" info))
  1240. (info (if (not (bit-field? type)) info
  1241. (let* ((bit (bit-field:bit type))
  1242. (bits (bit-field:bits type))
  1243. (set-mask (- (ash bits 1) 1))
  1244. (shifted-set-mask (ash set-mask bit))
  1245. (clear-mask (logxor shifted-set-mask
  1246. (if (= reg-size 4)
  1247. #b11111111111111111111111111111111
  1248. #b1111111111111111111111111111111111111111111111111111111111111111)))
  1249. (info (append-text info (wrap-as (as info 'swap-r0-r1))))
  1250. (info (allocate-register info))
  1251. (info (append-text info (wrap-as (as info 'r2->r0))))
  1252. (info (append-text info (wrap-as (as info 'swap-r0-r1))))
  1253. (info (append-text info (wrap-as (as info 'mem->r))))
  1254. (info (append-text info (wrap-as (as info 'r-and clear-mask))))
  1255. (info (append-text info (wrap-as (as info 'swap-r0-r1))))
  1256. (info (append-text info (wrap-as (as info 'r-and set-mask))))
  1257. (info (append-text info (wrap-as (as info 'shl-r bit))))
  1258. (info (append-text info (wrap-as (as info 'r0-or-r1))))
  1259. (info (free-register info))
  1260. (info (append-text info (wrap-as (as info 'swap-r0-r1)))))
  1261. info)))
  1262. (info (r0->r1-mem*n info
  1263. (min size (max reg-size size-b))
  1264. (min size (max reg-size size-b))))
  1265. (info (free-register info)))
  1266. info)))))
  1267. (_ (error "expr->register: not supported: " o))))
  1268. (let ((info (helper)))
  1269. (if (null? (.post info)) info
  1270. (append-text (clone info #:post '()) (.post info))))))
  1271. (define (mem->r type info)
  1272. (let* ((size (->size type info))
  1273. (reg-size (->size "*" info))
  1274. (size (if (= size reg-size) 0 size)))
  1275. (case size
  1276. ((0) (wrap-as (as info 'mem->r)))
  1277. ((1) (append (wrap-as (as info 'byte-mem->r)) (convert-r0 info type)))
  1278. ((2) (append (wrap-as (as info 'word-mem->r)) (convert-r0 info type)))
  1279. ((4) (append (wrap-as (as info 'long-mem->r)) (convert-r0 info type)))
  1280. (else '()))))
  1281. (define (convert-r0 info type)
  1282. (if (not (type? type)) '()
  1283. (let ((sign (signed? type))
  1284. (size (->size type info))
  1285. (reg-size (->size "*" info)))
  1286. (cond ((and (= size 1) sign)
  1287. (wrap-as (as info 'byte-signed-r)))
  1288. ((= size 1)
  1289. (wrap-as (as info 'byte-r))
  1290. ;;(wrap-as (as info 'byte-signed-r))
  1291. )
  1292. ((and (= size 2) sign)
  1293. (wrap-as (as info 'word-signed-r)))
  1294. ((= size 2)
  1295. (wrap-as (as info 'word-r))
  1296. ;;(wrap-as (as info 'word-signed-r))
  1297. )
  1298. ((and (> reg-size 4) (= size 4) sign)
  1299. (wrap-as (as info 'long-signed-r)))
  1300. ((and (> reg-size 4) (= size 4))
  1301. ;; for 17-unsigned-le
  1302. (wrap-as (as info 'long-signed-r)) ; huh, why not long-r?
  1303. ;; for a0-call-trunc-int
  1304. ;;(wrap-as (as info 'long-r))
  1305. )
  1306. (else '())))))
  1307. (define (binop->r info)
  1308. (lambda (a b c . rest)
  1309. (let* ((info (expr->register a info))
  1310. (info (expr->register b info))
  1311. (info (append-text info (wrap-as (apply as info (cons c rest))))))
  1312. (free-register info))))
  1313. (define (binop->r* info)
  1314. (lambda (a b c)
  1315. (let* ((info (expr->register* a info))
  1316. (info (expr->register b info))
  1317. (info (append-text info (wrap-as (as info c)))))
  1318. (free-register info))))
  1319. (define (wrap-as o . annotation)
  1320. `(,@annotation ,o))
  1321. (define (comment? o)
  1322. (and (pair? o) (pair? (car o)) (eq? (caar o) #:comment)))
  1323. (define (test-jump-label->info info label)
  1324. (define (jump type . test)
  1325. (lambda (o)
  1326. (let* ((info (expr->register o info))
  1327. (info (append-text info (make-comment "jmp test LABEL")))
  1328. (jump-text (wrap-as (as info type label)))
  1329. (info (append-text info (append (if (null? test) '() ((car test) info))
  1330. jump-text)))
  1331. (info (free-register info)))
  1332. info)))
  1333. (lambda (o)
  1334. (pmatch o
  1335. ((expr) info)
  1336. ((le ,a ,b) ((jump 'jump-z) o))
  1337. ((lt ,a ,b) ((jump 'jump-z) o))
  1338. ((ge ,a ,b) ((jump 'jump-z) o))
  1339. ((gt ,a ,b) ((jump 'jump-z) o))
  1340. ((ne ,a ,b) ((jump 'jump-nz) o))
  1341. ((eq ,a ,b) ((jump 'jump-nz) o))
  1342. ((not _) ((jump 'jump-z) o))
  1343. ((and ,a ,b)
  1344. (let* ((info ((test-jump-label->info info label) a))
  1345. (info ((test-jump-label->info info label) b)))
  1346. info))
  1347. ((or ,a ,b)
  1348. (let* ((here (number->string (length (if mes-or-reproducible? (.text info)
  1349. (filter (negate comment?) (.text info))))))
  1350. (skip-b-label (string-append label "_skip_b_" here))
  1351. (b-label (string-append label "_b_" here))
  1352. (info ((test-jump-label->info info b-label) a))
  1353. (info (append-text info (wrap-as (as info 'jump skip-b-label))))
  1354. (info (append-text info (wrap-as `((#:label ,b-label)))))
  1355. (info ((test-jump-label->info info label) b))
  1356. (info (append-text info (wrap-as `((#:label ,skip-b-label))))))
  1357. info))
  1358. ((array-ref ,index ,expr) (let* ((rank (expr->rank info expr))
  1359. (reg-size (->size "*" info))
  1360. (size (if (= rank 1) (ast-type->size info expr)
  1361. reg-size)))
  1362. ((jump (if (= size 1) 'jump-byte-z
  1363. 'jump-z)
  1364. (lambda (info) (wrap-as (as info 'r-zero?)))) o)))
  1365. ((de-ref ,expr) (let* ((rank (expr->rank info expr))
  1366. (r-size (->size "*" info))
  1367. (size (if (= rank 1) (ast-type->size info expr)
  1368. r-size)))
  1369. ((jump (if (= size 1) 'jump-byte-z
  1370. 'jump-z)
  1371. (lambda (info) (wrap-as (as info 'r-zero?)))) o)))
  1372. ((assn-expr (p-expr (ident ,name)) ,op ,expr)
  1373. ((jump 'jump-z
  1374. (lambda (info)
  1375. (append ((ident->r info) name)
  1376. (wrap-as (as info 'r-zero?))))) o))
  1377. (_ ((jump 'jump-z (lambda (info) (wrap-as (as info 'r-zero?)))) o)))))
  1378. (define (cstring->int o)
  1379. (let ((o (cond ((string-suffix? "ULL" o) (string-drop-right o 3))
  1380. ((string-suffix? "UL" o) (string-drop-right o 2))
  1381. ((string-suffix? "U" o) (string-drop-right o 1))
  1382. ((string-suffix? "LL" o) (string-drop-right o 2))
  1383. ((string-suffix? "L" o) (string-drop-right o 1))
  1384. (else o))))
  1385. (or (cond ((string-prefix? "0x" o) (string->number (string-drop o 2) 16))
  1386. ((string-prefix? "0b" o) (string->number (string-drop o 2) 2))
  1387. ((string-prefix? "0" o) (string->number o 8))
  1388. (else (string->number o)))
  1389. (error "cstring->int: not supported:" o))))
  1390. (define (cstring->float o)
  1391. (or (string->number o)
  1392. (error "cstring->float: not supported:" o)))
  1393. (define (try-expr->number info o)
  1394. (pmatch o
  1395. ((fixed ,a) (cstring->int a))
  1396. ((p-expr ,expr) (expr->number info expr))
  1397. ((pos ,a)
  1398. (expr->number info a))
  1399. ((neg ,a)
  1400. (- (expr->number info a)))
  1401. ((add ,a ,b)
  1402. (+ (expr->number info a) (expr->number info b)))
  1403. ((bitwise-and ,a ,b)
  1404. (logand (expr->number info a) (expr->number info b)))
  1405. ((bitwise-not ,a)
  1406. (lognot (expr->number info a)))
  1407. ((bitwise-or ,a ,b)
  1408. (logior (expr->number info a) (expr->number info b)))
  1409. ((div ,a ,b)
  1410. (quotient (expr->number info a) (expr->number info b)))
  1411. ((mul ,a ,b)
  1412. (* (expr->number info a) (expr->number info b)))
  1413. ((sub ,a ,b)
  1414. (- (expr->number info a) (expr->number info b)))
  1415. ((sizeof-type ,type)
  1416. (->size (ast->type type info) info))
  1417. ((sizeof-expr ,expr)
  1418. (->size (ast->type expr info) info))
  1419. ((lshift ,x ,y)
  1420. (ash (expr->number info x) (expr->number info y)))
  1421. ((rshift ,x ,y)
  1422. (ash (expr->number info x) (- (expr->number info y))))
  1423. ((p-expr (ident ,name))
  1424. (let ((value (assoc-ref (.constants info) name)))
  1425. (or value
  1426. (error (format #f "expr->number: undeclared identifier: ~s\n" o)))))
  1427. ((cast ,type ,expr) (expr->number info expr))
  1428. ((cond-expr ,test ,then ,else)
  1429. (if (p-expr->bool info test) (expr->number info then) (expr->number info else)))
  1430. (,string (guard (string? string)) (cstring->int string))
  1431. ((ident ,name) (assoc-ref (.constants info) name))
  1432. (_ #f)))
  1433. (define (expr->number info o)
  1434. (or (try-expr->number info o)
  1435. (error (format #f "expr->number: not supported: ~s\n" o))))
  1436. (define (p-expr->bool info o)
  1437. (pmatch o
  1438. ((eq ,a ,b) (eq? (expr->number info a) (expr->number info b)))))
  1439. (define (struct-field info)
  1440. (lambda (o)
  1441. (pmatch o
  1442. ((comp-decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))) (comp-declr-list . ,decls))
  1443. (append-map (lambda (o)
  1444. ((struct-field info) `(comp-decl (decl-spec-list (type-spec "int")) (comp-declr-list ,o))))
  1445. decls))
  1446. ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ident ,name))))
  1447. (list (cons name (ast->type type info))))
  1448. ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ptr-declr ,pointer (ident ,name)))))
  1449. (let ((rank (pointer->rank pointer)))
  1450. (list (cons name (rank+= (ast->type type info) rank)))))
  1451. ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ftn-declr (scope (ptr-declr ,pointer (ident ,name))) _))))
  1452. (let ((rank (pointer->rank pointer)))
  1453. (list (cons name (rank+= (ast->type type info) rank)))))
  1454. ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (ptr-declr ,pointer (array-of (ident ,name) ,count)))))
  1455. (let ((rank (pointer->rank pointer))
  1456. (count (expr->number info count)))
  1457. (list (cons name (make-c-array (rank+= type rank) count)))))
  1458. ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (array-of (ident ,name) ,count))))
  1459. (let ((count (expr->number info count)))
  1460. (list (cons name (make-c-array (ast->type type info) count)))))
  1461. ((comp-decl (decl-spec-list (type-spec (struct-def (field-list . ,fields)))))
  1462. (let ((fields (append-map (struct-field info) fields)))
  1463. (list (cons 'struct (make-type 'struct (apply + (map (cut field:size <> info) fields)) fields)))))
  1464. ((comp-decl (decl-spec-list (type-spec (union-def (field-list . ,fields)))))
  1465. (let ((fields (append-map (struct-field info) fields)))
  1466. (list (cons 'union (make-type 'union (apply + (map (cut field:size <> info) fields)) fields)))))
  1467. ((comp-decl (decl-spec-list (type-spec ,type)) (comp-declr-list (comp-declr (bit-field (ident ,name) (p-expr (fixed ,bits)))) . ,fields))
  1468. (let ((type (ast->type type info)))
  1469. (list (cons 'bits (let loop ((o `((comp-declr (bit-field (ident ,name) (p-expr (fixed ,bits)))) . ,fields)) (bit 0))
  1470. (if (null? o) '()
  1471. (let ((field (car o)))
  1472. (pmatch field
  1473. ((comp-declr (bit-field (ident ,name) (p-expr (fixed ,bits))))
  1474. (let ((bits (cstring->int bits)))
  1475. (cons (cons name (make-bit-field type bit bits))
  1476. (loop (cdr o) (+ bit bits)))))
  1477. (_ (error "struct-field: not supported:" field o))))))))))
  1478. ((comp-decl (decl-spec-list ,type) (comp-declr-list . ,decls))
  1479. (append-map (lambda (o)
  1480. ((struct-field info) `(comp-decl (decl-spec-list ,type) (comp-declr-list ,o))))
  1481. decls))
  1482. (_ (error "struct-field: not supported: " o)))))
  1483. (define (local-var? o) ;; formals < 0, locals > 0
  1484. (positive? (local:id o)))
  1485. (define (ptr-declr->rank o)
  1486. (pmatch o
  1487. ((pointer) 1)
  1488. ((pointer (pointer)) 2)
  1489. ((pointer (pointer (pointer))) 3)
  1490. (_ (error "ptr-declr->rank not supported: " o))))
  1491. (define (ast->info o info)
  1492. (let ((functions (.functions info))
  1493. (globals (.globals info))
  1494. (locals (.locals info))
  1495. (constants (.constants info))
  1496. (types (.types info))
  1497. (text (.text info)))
  1498. (pmatch o
  1499. (((trans-unit . _) . _) (ast-list->info o info))
  1500. ((trans-unit . ,_) (ast-list->info _ info))
  1501. ((fctn-defn . ,_) (fctn-defn->info _ info))
  1502. ((cpp-stmt (define (name ,name) (repl ,value)))
  1503. info)
  1504. ((cast (type-name (decl-spec-list (type-spec (void)))) _)
  1505. info)
  1506. ((break)
  1507. (let ((label (car (.break info))))
  1508. (append-text info (wrap-as (as info 'jump label)))))
  1509. ((continue)
  1510. (let ((label (car (.continue info))))
  1511. (append-text info (wrap-as (as info 'jump label)))))
  1512. ;; FIXME: expr-stmt wrapper?
  1513. (trans-unit info)
  1514. ((expr-stmt) info)
  1515. ((compd-stmt (block-item-list . ,_))
  1516. (let* ((locals (.locals info))
  1517. (info (ast-list->info _ info)))
  1518. (clone info #:locals locals)))
  1519. ((asm-expr ,gnuc (,null ,arg0 . string))
  1520. (append-text info (wrap-as (asm->m1 arg0))))
  1521. ;; Nyacc 0.90.2
  1522. ((asm-expr ,gnuc (string ,arg0))
  1523. (append-text info (wrap-as (asm->m1 arg0))))
  1524. ((expr-stmt (fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))
  1525. (if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list))))
  1526. (append-text info (wrap-as (asm->m1 arg0))))
  1527. (let* ((info (expr->register `(fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)) info))
  1528. (info (free-register info))
  1529. (info (append-text info (wrap-as (as info 'r-zero?)))))
  1530. info)))
  1531. ((if ,test ,then)
  1532. (let* ((info (append-text info (ast->comment `(if ,test (ellipsis)))))
  1533. (here (number->string (length text)))
  1534. (label (string-append "_" (.function info) "_" here "_"))
  1535. (break-label (string-append label "break"))
  1536. (else-label (string-append label "else"))
  1537. (info ((test-jump-label->info info break-label) test))
  1538. (info (ast->info then info))
  1539. (info (append-text info (wrap-as (as info 'jump break-label))))
  1540. (info (append-text info (wrap-as `((#:label ,break-label))))))
  1541. (clone info
  1542. #:locals locals)))
  1543. ((if ,test ,then ,else)
  1544. (let* ((info (append-text info (ast->comment `(if ,test (ellipsis) (ellipsis)))))
  1545. (here (number->string (length text)))
  1546. (label (string-append "_" (.function info) "_" here "_"))
  1547. (break-label (string-append label "break"))
  1548. (else-label (string-append label "else"))
  1549. (info ((test-jump-label->info info else-label) test))
  1550. (info (ast->info then info))
  1551. (info (append-text info (wrap-as (as info 'jump break-label))))
  1552. (info (append-text info (wrap-as `((#:label ,else-label)))))
  1553. (info (ast->info else info))
  1554. (info (append-text info (wrap-as `((#:label ,break-label))))))
  1555. (clone info
  1556. #:locals locals)))
  1557. ;; Hmm?
  1558. ((expr-stmt (cond-expr ,test ,then ,else))
  1559. (let ((info (expr->register `(cond-expr ,test ,then ,else) info)))
  1560. (free-register info)))
  1561. ((switch ,expr (compd-stmt (block-item-list . ,statements)))
  1562. (define (clause? o)
  1563. (pmatch o
  1564. ((case . _) 'case)
  1565. ((default . _) 'default)
  1566. ((labeled-stmt _ ,statement) (clause? statement))
  1567. (_ #f)))
  1568. (define clause-number
  1569. (let ((i 0))
  1570. (lambda (o)
  1571. (let ((n i))
  1572. (when (clause? (car o))
  1573. (set! i (1+ i)))
  1574. n))))
  1575. (let* ((info (append-text info (ast->comment `(switch ,expr (compd-stmt (block-item-list (ellipsis)))))))
  1576. (here (number->string (length text)))
  1577. (label (string-append "_" (.function info) "_" here "_"))
  1578. (break-label (string-append label "break"))
  1579. (info (expr->register expr info))
  1580. (info (clone info #:break (cons break-label (.break info))))
  1581. (count (length (filter clause? statements)))
  1582. (default? (find (cut eq? <> 'default) (map clause? statements)))
  1583. (info (fold (cut switch->info #t label (1- count) <> <> <>) info statements
  1584. (unfold null? clause-number cdr statements)))
  1585. (last-clause-label (string-append label "clause" (number->string count)))
  1586. (default-label (string-append label "default"))
  1587. (info (if (not default?) info
  1588. (append-text info (wrap-as (as info 'jump break-label)))))
  1589. (info (append-text info (wrap-as `((#:label ,last-clause-label)))))
  1590. (info (if (not default?) info
  1591. (append-text info (wrap-as (as info 'jump default-label)))))
  1592. (info (append-text info (wrap-as `((#:label ,break-label))))))
  1593. (clone info
  1594. #:locals locals
  1595. #:break (cdr (.break info)))))
  1596. ((for ,init ,test ,step ,body)
  1597. (let* ((info (append-text info (ast->comment `(for ,init ,test ,step (ellipsis)))))
  1598. (here (number->string (length text)))
  1599. (label (string-append "_" (.function info) "_" here "_"))
  1600. (break-label (string-append label "break"))
  1601. (loop-label (string-append label "loop"))
  1602. (continue-label (string-append label "continue"))
  1603. (initial-skip-label (string-append label "initial_skip"))
  1604. (info (ast->info init info))
  1605. (info (clone info #:break (cons break-label (.break info))))
  1606. (info (clone info #:continue (cons continue-label (.continue info))))
  1607. (info (append-text info (wrap-as (as info 'jump initial-skip-label))))
  1608. (info (append-text info (wrap-as `((#:label ,loop-label)))))
  1609. (info (ast->info body info))
  1610. (info (append-text info (wrap-as `((#:label ,continue-label)))))
  1611. (info (if (equal? step '(expr)) info
  1612. (let ((info (expr->register step info)))
  1613. (free-register info))))
  1614. (info (append-text info (wrap-as `((#:label ,initial-skip-label)))))
  1615. (info ((test-jump-label->info info break-label) test))
  1616. (info (append-text info (wrap-as (as info 'jump loop-label))))
  1617. (info (append-text info (wrap-as `((#:label ,break-label))))))
  1618. (clone info
  1619. #:locals locals
  1620. #:break (cdr (.break info))
  1621. #:continue (cdr (.continue info)))))
  1622. ((while ,test ,body)
  1623. (let* ((info (append-text info (ast->comment `(while ,test (ellipsis)))))
  1624. (here (number->string (length text)))
  1625. (label (string-append "_" (.function info) "_" here "_"))
  1626. (break-label (string-append label "break"))
  1627. (loop-label (string-append label "loop"))
  1628. (continue-label (string-append label "continue"))
  1629. (info (append-text info (wrap-as (as info 'jump continue-label))))
  1630. (info (clone info #:break (cons break-label (.break info))))
  1631. (info (clone info #:continue (cons continue-label (.continue info))))
  1632. (info (append-text info (wrap-as `((#:label ,loop-label)))))
  1633. (info (ast->info body info))
  1634. (info (append-text info (wrap-as `((#:label ,continue-label)))))
  1635. (info ((test-jump-label->info info break-label) test))
  1636. (info (append-text info (wrap-as (as info 'jump loop-label))))
  1637. (info (append-text info (wrap-as `((#:label ,break-label))))))
  1638. (clone info
  1639. #:locals locals
  1640. #:break (cdr (.break info))
  1641. #:continue (cdr (.continue info)))))
  1642. ((do-while ,body ,test)
  1643. (let* ((info (append-text info (ast->comment `(do-while ,test (ellipsis)))))
  1644. (here (number->string (length text)))
  1645. (label (string-append "_" (.function info) "_" here "_"))
  1646. (break-label (string-append label "break"))
  1647. (loop-label (string-append label "loop"))
  1648. (continue-label (string-append label "continue"))
  1649. (info (clone info #:break (cons break-label (.break info))))
  1650. (info (clone info #:continue (cons continue-label (.continue info))))
  1651. (info (append-text info (wrap-as `((#:label ,loop-label)))))
  1652. (info (ast->info body info))
  1653. (info (append-text info (wrap-as `((#:label ,continue-label)))))
  1654. (info ((test-jump-label->info info break-label) test))
  1655. (info (append-text info (wrap-as (as info 'jump loop-label))))
  1656. (info (append-text info (wrap-as `((#:label ,break-label))))))
  1657. (clone info
  1658. #:locals locals
  1659. #:break (cdr (.break info))
  1660. #:continue (cdr (.continue info)))))
  1661. ((labeled-stmt (ident ,label) ,statement)
  1662. (let ((info (append-text info `(((#:label ,(string-append "_" (.function info) "_label_" label)))))))
  1663. (ast->info statement info)))
  1664. ((goto (ident ,label))
  1665. (append-text info (wrap-as (as info 'jump (string-append "_" (.function info) "_label_" label)))))
  1666. ((return (expr))
  1667. (let ((info (fold (lambda (x info) (free-register info)) info (.allocated info))))
  1668. (append-text info (append (wrap-as (as info 'ret))))))
  1669. ((return ,expr)
  1670. (let* ((info (fold (lambda (x info) (free-register info)) info (.allocated info)))
  1671. (info (expr->register expr info))
  1672. (info (free-register info)))
  1673. (append-text info (append (wrap-as (as info 'ret))))))
  1674. ((decl . ,decl)
  1675. (let ((info (append-text info (ast->comment o))))
  1676. (decl->info info decl)))
  1677. ((gt . _) (free-register (expr->register o info)))
  1678. ((ge . _) (free-register (expr->register o info)))
  1679. ((ne . _) (free-register (expr->register o info)))
  1680. ((eq . _) (free-register (expr->register o info)))
  1681. ((le . _) (free-register (expr->register o info)))
  1682. ((lt . _) (free-register (expr->register o info)))
  1683. ((lshift . _) (free-register (expr->register o info)))
  1684. ((rshift . _) (free-register (expr->register o info)))
  1685. ((expr-stmt ,expression)
  1686. (let* ((info (expr->register expression info))
  1687. (info (append-text info (wrap-as (as info 'r-zero?)))))
  1688. (fold (lambda (x info) (free-register info)) info (.allocated info))))
  1689. (_ (let* ((info (expr->register o info))
  1690. (info (append-text info (wrap-as (as info 'r-zero?)))))
  1691. (fold (lambda (x info) (free-register info)) info (.allocated info)))))))
  1692. (define (ast-list->info o info)
  1693. (fold ast->info info o))
  1694. (define (switch->info clause? label count o i info)
  1695. (let* ((i-string (number->string i))
  1696. (i+1-string (number->string (1+ i)))
  1697. (body-label (string-append label "body" i-string))
  1698. (next-body-label (string-append label "body" i+1-string))
  1699. (clause-label (string-append label "clause" i-string))
  1700. (last? (= i count))
  1701. (break-label (string-append label "break"))
  1702. (next-clause-label (string-append label "clause" i+1-string))
  1703. (default-label (string-append label "default")))
  1704. (define (jump label)
  1705. (wrap-as (as info 'jump label)))
  1706. (pmatch o
  1707. ((case ,test)
  1708. (define (jump-nz label)
  1709. (wrap-as (as info 'jump-nz label)))
  1710. (define (jump-z label)
  1711. (wrap-as (as info 'jump-z label)))
  1712. (define (test->text test)
  1713. (let ((value (pmatch test
  1714. (0 0)
  1715. ((p-expr (char ,value)) (char->integer (car (string->list value))))
  1716. ((p-expr (ident ,constant)) (assoc-ref (.constants info) constant))
  1717. ((p-expr (fixed ,value)) (cstring->int value))
  1718. ((neg (p-expr (fixed ,value))) (- (cstring->int value)))
  1719. (_ (error "case test: not supported: " test)))))
  1720. (append (wrap-as (as info 'r-cmp-value value))
  1721. (jump-z body-label))))
  1722. (let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1723. info)))
  1724. (append-text info (test->text test))))
  1725. ((case ,test (case . ,case1))
  1726. (let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1727. info)))
  1728. (fold (cut switch->info #f label count <> i <>) info (cons `(case ,test) `((case ,@case1))))))
  1729. ((case ,test (default . ,rest))
  1730. (let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1731. info)))
  1732. (fold (cut switch->info #f label count <> i <>) info (cons `(case ,test) `(default ,@rest)))))
  1733. ((case ,test ,statement)
  1734. (let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1735. info))
  1736. (info (switch->info #f label count `(case ,test) i info))
  1737. (info (append-text info (jump next-clause-label)))
  1738. (info (append-text info (wrap-as `((#:label ,body-label)))))
  1739. (info (ast->info statement info))
  1740. ;; 66-local-char-array -- fallthrough FIXME
  1741. ;; (info (if last? info
  1742. ;; (append-text info (jump next-body-label))))
  1743. )
  1744. info))
  1745. ((case ,test (case . ,case1) . ,rest)
  1746. (let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1747. info)))
  1748. (fold (cut switch->info #f label count <> i <>) info (cons `(case ,test) `((case ,@case1) ,@rest)))))
  1749. ((default (case . ,case1) . ,rest)
  1750. (let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1751. info))
  1752. (info (if last? info
  1753. (append-text info (jump next-clause-label))))
  1754. (info (append-text info (wrap-as `((#:label ,default-label)))))
  1755. (info (append-text info (jump body-label)))
  1756. (info (append-text info (wrap-as `((#:label ,body-label))))))
  1757. (fold (cut switch->info #f label count <> i <>) info `((case ,@case1) ,@rest))))
  1758. (default
  1759. (let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1760. info))
  1761. (info (if last? info
  1762. (append-text info (jump next-clause-label))))
  1763. (info (append-text info (wrap-as `((#:label ,default-label)))))
  1764. (info (append-text info (jump body-label)))
  1765. (info (append-text info (wrap-as `((#:label ,body-label))))))
  1766. info))
  1767. ((default ,statement)
  1768. (let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1769. info))
  1770. (info (if last? info
  1771. (append-text info (jump next-clause-label))))
  1772. (info (append-text info (wrap-as `((#:label ,default-label)))))
  1773. (info (append-text info (wrap-as `((#:label ,body-label))))))
  1774. (ast->info statement info)))
  1775. ((default ,statement ,rest)
  1776. (let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
  1777. info))
  1778. (info (if last? info
  1779. (append-text info (jump next-clause-label))))
  1780. (info (append-text info (wrap-as `((#:label ,default-label)))))
  1781. (info (append-text info (wrap-as `((#:label ,body-label))))))
  1782. (fold ast->info (ast->info statement info) rest)))
  1783. ((labeled-stmt (ident ,goto-label) ,statement)
  1784. (let ((info (append-text info `(((#:label ,(string-append "_" (.function info) "_label_" goto-label)))))))
  1785. (switch->info clause? label count statement i info)))
  1786. (_ (ast->info o info)))))
  1787. (define (global->static function)
  1788. (lambda (o)
  1789. (cons (car o) (set-field (cdr o) (global:function) function))))
  1790. (define (decl->info info o)
  1791. (pmatch o
  1792. (((decl-spec-list (type-spec ,type)) (init-declr-list . ,inits))
  1793. (let* ((info (type->info type #f info))
  1794. (type (ast->type type info)))
  1795. (fold (cut init-declr->info type 'storage <> <>) info (map cdr inits))))
  1796. (((decl-spec-list (type-spec ,type)))
  1797. (type->info type #f info))
  1798. (((decl-spec-list (stor-spec (typedef)) (type-spec ,type)) (init-declr-list (init-declr (ident ,name))))
  1799. (let* ((info (type->info type name info))
  1800. (type (ast->type type info)))
  1801. (clone info #:types (acons name type (.types info)))))
  1802. ;; FIXME: recursive types, pointer, array
  1803. (((decl-spec-list (stor-spec (typedef)) (type-spec ,type)) (init-declr-list (init-declr (array-of (ident ,name) ,count))))
  1804. (let* ((info (type->info type name info))
  1805. (type (ast->type type info))
  1806. (count (expr->number info count))
  1807. (type (make-c-array type count)))
  1808. (clone info #:types (acons name type (.types info)))))
  1809. (((decl-spec-list (stor-spec (typedef)) (type-spec ,type)) (init-declr-list (init-declr (ptr-declr ,pointer (ident ,name)))))
  1810. (let* ((info (type->info type name info))
  1811. (type (ast->type type info))
  1812. (rank (pointer->rank pointer))
  1813. (type (rank+= type rank)))
  1814. (clone info #:types (acons name type (.types info)))))
  1815. (((decl-spec-list (stor-spec (,store)) (type-spec ,type)) (init-declr-list . ,inits))
  1816. (let* ((info (type->info type #f info))
  1817. (type (ast->type type info))
  1818. (function (.function info)))
  1819. (if (not function) (fold (cut init-declr->info type store <> <>) info (map cdr inits))
  1820. (let* ((tmp (clone info #:function #f #:globals '()))
  1821. (tmp (fold (cut init-declr->info type store <> <>) tmp (map cdr inits)))
  1822. (statics (map (global->static function) (.globals tmp)))
  1823. (strings (filter string-global? (.globals tmp))))
  1824. (clone info #:globals (append (.globals info) strings)
  1825. #:statics (append statics (.statics info)))))))
  1826. (((decl-spec-list (stor-spec (,store)) (type-spec ,type)))
  1827. (type->info type #f info))
  1828. (((@ . _))
  1829. (format (current-error-port) "decl->info: skip: ~s\n" o)
  1830. info)
  1831. (_ (error "decl->info: not supported:" o))))
  1832. (define (ast->name o)
  1833. (pmatch o
  1834. ((ident ,name) name)
  1835. ((array-of ,array . ,_) (ast->name array))
  1836. ((ftn-declr (scope (ptr-declr ,pointer (ident ,name))) . _) name)
  1837. ((ptr-declr ,pointer ,decl . ,_) (ast->name decl))
  1838. ((ptr-declr ,pointer (ident ,name)) name)
  1839. (_ (error "ast->name not supported: " o))))
  1840. (define (init-declr->count info o)
  1841. (pmatch o
  1842. ((array-of (ident ,name) ,count) (expr->number info count))
  1843. (_ #f)))
  1844. (define (init->r o info)
  1845. (pmatch o
  1846. ((initzer-list (initzer ,expr))
  1847. (expr->register expr info))
  1848. (((#:string ,string))
  1849. (expr->register `(p-expr (string ,string)) info))
  1850. ((,number . _) (guard (number? number))
  1851. (expr->register `(p-expr (fixed 0)) info))
  1852. ((,c . ,_) (guard (char? c))
  1853. info)
  1854. (_
  1855. (expr->register o info))))
  1856. (define (init-struct-field local field n init info)
  1857. (let* ((offset (field-offset info (local:type local) (car field)))
  1858. (size (field:size field info))
  1859. (offset (+ offset (* n size)))
  1860. (info (expr->register init info))
  1861. (info (allocate-register info))
  1862. (info (append-text info (local->r local info)))
  1863. (info (append-text info (wrap-as (as info 'r+value offset))))
  1864. (reg-size (->size "*" info))
  1865. (size (min size reg-size))
  1866. (info (r0->r1-mem*n info size size))
  1867. (info (free-register info))
  1868. (info (free-register info)))
  1869. info))
  1870. (define (init-struct-struct-field local type offset field init info)
  1871. (let* ((offset (+ offset (field-offset info type (car field))))
  1872. (size (field:size field info))
  1873. (info (expr->register init info))
  1874. (info (allocate-register info))
  1875. (info (append-text info (local->r local info)))
  1876. (info (append-text info (wrap-as (as info 'r+value offset))))
  1877. (reg-size (->size "*" info))
  1878. (size (min size reg-size))
  1879. (info (r0->r1-mem*n info size size))
  1880. (info (free-register info))
  1881. (info (free-register info)))
  1882. info))
  1883. (define (init-array-entry local index init info)
  1884. (let* ((type (local:type local))
  1885. (size (cond ((pointer? type) (->size "*" info))
  1886. ((and (c-array? type) ((compose pointer? c-array:type) type)) (->size "*" info))
  1887. ((c-array? type) ((compose type:size c-array:type) type))
  1888. (else (type:size type))))
  1889. (offset (* index size))
  1890. (info (expr->register init info))
  1891. (info (allocate-register info))
  1892. (info (append-text info (local->r local info)))
  1893. (info (append-text info (wrap-as (as info 'r+value offset))))
  1894. (reg-size (->size "*" info))
  1895. (size (min size reg-size))
  1896. (info (r0->r1-mem*n info size size))
  1897. (info (fold (lambda (x info) (free-register info)) info (.allocated info))))
  1898. info))
  1899. (define (init-local local o n info)
  1900. (pmatch o
  1901. (#f info)
  1902. ((initzer ,init)
  1903. (init-local local init n info))
  1904. ((initzer-list . ,inits)
  1905. (let ((local-type (local:type local)))
  1906. (cond ((structured-type? local)
  1907. (let* ((fields (struct->init-fields local-type))
  1908. (field+counts (let loop ((fields fields))
  1909. (if (null? fields) '()
  1910. (let* ((field (car fields))
  1911. (type (cdr field)))
  1912. (cond ((c-array? type)
  1913. (append (map
  1914. (lambda (i)
  1915. (let ((field (cons (car field) (c-array:type type))))
  1916. (cons field i)))
  1917. (iota (c-array:count type)))
  1918. (loop (cdr fields))))
  1919. (else
  1920. (cons (cons field 0) (loop (cdr fields))))))))))
  1921. (let loop ((field+counts field+counts) (inits inits) (info info))
  1922. (if (null? field+counts) info
  1923. (let* ((field (caaar field+counts))
  1924. (type (cdaar field+counts)))
  1925. (if (and (type? type)
  1926. (eq? (type:type type) 'struct))
  1927. (let* ((field-fields (type:description type))
  1928. (field-inits (list-head inits (max (length inits) (length field-fields))))
  1929. (missing (max 0 (- (length field-fields) (length field-inits))))
  1930. (field-inits+ (append field-inits (map (const '(p-expr (fixed "0"))) (iota missing))))
  1931. (offset (field-offset info local-type field))
  1932. ;; (info (init-local local `(initzer-list ,field-inits) n info))
  1933. ;; crap, howto recurse? -- would need new local for TYPE
  1934. ;; just do two deep for now
  1935. (info (fold (cut init-struct-struct-field local type offset <> <> <>) info field-fields field-inits+)))
  1936. (loop (list-tail field+counts (min (length field+counts) (length field-fields)))
  1937. (list-tail inits (min (length field-inits) (length field-inits))) info))
  1938. (let* ((missing (max 0 (- (length field+counts) (length inits))))
  1939. (counts (map cdr field+counts))
  1940. (fields (map car field+counts))
  1941. (info (fold (cut init-struct-field local <> <> <> <>) info fields counts (append inits (map (const '(p-expr (fixed "22"))) (iota missing))))))
  1942. ;; bah, loopme!
  1943. ;;(loop (list-tail field+counts (length field-fields)) (list-tail inits (length field-inits)) info)
  1944. info)))))))
  1945. (else
  1946. (let* ((type (local:type local))
  1947. (type (if (c-array? type) (c-array:type type) type))
  1948. (size (->size type info)))
  1949. (fold (cut init-local local <> <> <>) info inits (iota (length inits) 0 size)))))))
  1950. (,string (guard (string? string))
  1951. (let ((inits (string->list string)))
  1952. (fold (cut init-array-entry local <> <> <>) info (iota (length inits)) inits)))
  1953. (((initzer (initzer-list . ,inits)))
  1954. (init-local local (car o) n info))
  1955. (() info)
  1956. (_ (let* ((info (init->r o info))
  1957. (info (append-text info (r->local+n-text info local n))))
  1958. (free-register info)))))
  1959. (define (local->info type name o init info)
  1960. (let* ((locals (.locals info))
  1961. (id (if (or (null? locals) (not (local-var? (cdar locals)))) 1
  1962. (1+ (local:id (cdar locals)))))
  1963. (local (make-local-entry name type id))
  1964. (pointer (->rank (cdr local)))
  1965. (array? (or (and (c-array? type) type)
  1966. (and (pointer? type)
  1967. (c-array? (pointer:type type))
  1968. (pointer:type type))
  1969. (and (pointer? type)
  1970. (pointer? (pointer:type type))
  1971. (c-array? (pointer:type (pointer:type type)))
  1972. (pointer:type (pointer:type type)))))
  1973. (struct? (structured-type? type))
  1974. (size (->size type info))
  1975. (string (and array? (array-init->string init)))
  1976. (init (or string init))
  1977. (reg-size (->size "*" info))
  1978. (local (if (not array?) local
  1979. (let ((size (or (and string (max size (1+ (string-length string))))
  1980. size)))
  1981. (make-local-entry name type (+ (local:id (cdr local)) -1 (quotient (+ size (1- reg-size)) reg-size))))))
  1982. (local (if struct? (make-local-entry name type (+ (local:id (cdr local)) (quotient (+ size (1- reg-size)) reg-size)))
  1983. local))
  1984. (locals (cons local locals))
  1985. (info (clone info #:locals locals))
  1986. (local (cdr local)))
  1987. (init-local local init 0 info)))
  1988. (define (global->info storage type name o init info)
  1989. (let* ((rank (->rank type))
  1990. (size (->size type info))
  1991. (data (cond ((not init) (string->list (make-string size #\nul)))
  1992. ((c-array? type)
  1993. (let* ((string (array-init->string init))
  1994. (size (or (and string (max size (1+ (string-length string))))
  1995. size))
  1996. (data (or (and=> string string->list)
  1997. (array-init->data type size init info))))
  1998. (append data (string->list (make-string (max 0 (- size (length data))) #\nul)))))
  1999. ((structured-type? type)
  2000. (let ((data (init->data type init info)))
  2001. (append data (string->list (make-string (max 0 (- size (length data))) #\nul)))))
  2002. (else
  2003. (let ((data (init->data type init info)))
  2004. (append data (string->list (make-string (max 0 (- size (length data))) #\nul)))))))
  2005. (global (make-global-entry name storage type data)))
  2006. (clone info #:globals (append (.globals info) (list global)))))
  2007. (define (array-init-element->data type o info)
  2008. (pmatch o
  2009. ((initzer (p-expr (string ,string)))
  2010. (let ((reg-size (->size "*" info)))
  2011. (if (= reg-size 8) `((#:string ,string) "%0")
  2012. `((#:string ,string)))))
  2013. ((initzer (p-expr (fixed ,fixed)))
  2014. (if (structured-type? type)
  2015. (let ((fields (map cdr (struct->init-fields type))))
  2016. (int->bv type (expr->number info fixed) info))
  2017. (int->bv type (expr->number info fixed) info)))
  2018. ((initzer (initzer-list . ,inits))
  2019. (cond ((structured-type? type)
  2020. (let* ((fields (map cdr (struct->init-fields type)))
  2021. (missing (max 0 (- (length fields) (length inits))))
  2022. (inits (append inits
  2023. (map (const '(fixed "0")) (iota missing)))))
  2024. (map (cut array-init-element->data <> <> info) fields inits)))
  2025. ((c-array? type)
  2026. (let* ((missing (max 0 (- (c-array:count type) (length inits))))
  2027. (inits (append inits
  2028. (map (const '(fixed "0")) (iota missing)))))
  2029. (map (cut array-init-element->data (c-array:type type) <> info) inits)))
  2030. (else
  2031. (format (current-error-port) "array-init-element->data: oops:~s\n" o)
  2032. (format (current-error-port) "type:~s\n" type)
  2033. (error "array-init-element->data: not supported: " o))))
  2034. (_ (init->data type o info))
  2035. (_ (error "array-init-element->data: not supported: " o))))
  2036. (define (array-init->data type size o info)
  2037. (pmatch o
  2038. ((initzer (initzer-list . ,inits))
  2039. (let ((type (c-array:type type)))
  2040. (if (structured-type? type)
  2041. (let* ((init-fields (struct->init-fields type)) ;; FIXME
  2042. (count (length init-fields)))
  2043. (let loop ((inits inits))
  2044. (if (null? inits) '()
  2045. (let ((init (car inits)))
  2046. (pmatch init
  2047. ((initzer (initzer-list . ,car-inits))
  2048. (append (array-init-element->data type init info)
  2049. (loop (cdr inits))))
  2050. (_
  2051. (let* ((count (min (length inits) (length init-fields)))
  2052. (field-inits (list-head inits count)))
  2053. (append (array-init-element->data type `(initzer-list ,@field-inits) info)
  2054. (loop (list-tail inits count))))))))))
  2055. (map (cut array-init-element->data type <> info) inits))))
  2056. (((initzer (initzer-list . ,inits)))
  2057. (array-init->data type size (car o) info))
  2058. ((initzer (p-expr (string ,string)))
  2059. (let ((data (string->list string)))
  2060. (if (not size) data
  2061. (append data (string->list (make-string (max 0 (- size (length data))) #\nul))))))
  2062. (((initzer (p-expr (string ,string))))
  2063. (array-init->data type size (car o) info))
  2064. ((initzer (p-expr (string . ,strings)))
  2065. (let ((data (string->list (apply string-append strings))))
  2066. (if (not size) data
  2067. (append data (string->list (make-string (max 0 (- size (length data))) #\nul))))))
  2068. (((initzer (p-expr (string . ,strings))))
  2069. (array-init->data type size (car o) info))
  2070. ((initzer (p-expr (fixed ,fixed)))
  2071. (int->bv type (expr->number info fixed) info))
  2072. (() (string->list (make-string size #\nul)))
  2073. (_ (error "array-init->data: not supported: " o))))
  2074. (define (array-init->string o)
  2075. (pmatch o
  2076. ((p-expr (string ,string)) string)
  2077. ((p-expr (string . ,strings)) (apply string-append strings))
  2078. ((initzer ,init) (array-init->string init))
  2079. (((initzer ,init)) (array-init->string init))
  2080. ((initzer-list (initzer (p-expr (char ,c))) . ,inits)
  2081. (list->string (map (lambda (i) (pmatch i
  2082. ((initzer (p-expr (char ,c))) ((compose car string->list) c))
  2083. ((initzer (p-expr (fixed ,fixed)))
  2084. (let ((value (cstring->int fixed)))
  2085. (if (and (>= value 0) (<= value 255))
  2086. (integer->char value)
  2087. (error "array-init->string: not supported:" i o))))
  2088. (_ (error "array-init->string: not supported:" i o))))
  2089. (cdr o))))
  2090. (_ #f)))
  2091. (define (init-declr->info type storage o info)
  2092. (pmatch o
  2093. (((ident ,name))
  2094. (if (.function info) (local->info type name o #f info)
  2095. (global->info storage type name o #f info)))
  2096. (((ident ,name) (initzer ,init))
  2097. (let* ((strings (init->strings init info))
  2098. (info (if (null? strings) info
  2099. (clone info #:globals (append (.globals info) strings)))))
  2100. (if (.function info) (local->info type name o init info)
  2101. (global->info storage type name o init info))))
  2102. (((ftn-declr (ident ,name) . ,_))
  2103. (let ((functions (.functions info)))
  2104. (if (member name functions) info
  2105. (let ((function (make-function name type #f)))
  2106. (clone info #:functions (cons (cons name function) functions))))))
  2107. (((ftn-declr (scope (ptr-declr ,pointer (ident ,name))) ,param-list) ,init)
  2108. (let* ((rank (pointer->rank pointer))
  2109. (type (rank+= type rank)))
  2110. (if (.function info) (local->info type name o init info)
  2111. (global->info storage type name o init info))))
  2112. (((ftn-declr (scope (ptr-declr ,pointer (ident ,name))) ,param-list))
  2113. (let* ((rank (pointer->rank pointer))
  2114. (type (rank+= type rank)))
  2115. (if (.function info) (local->info type name o '() info)
  2116. (global->info storage type name o '() info))))
  2117. (((ptr-declr ,pointer . ,_) . ,init)
  2118. (let* ((rank (pointer->rank pointer))
  2119. (type (rank+= type rank)))
  2120. (init-declr->info type storage (append _ init) info)))
  2121. (((array-of (ident ,name) ,count) . ,init)
  2122. (let* ((strings (init->strings init info))
  2123. (info (if (null? strings) info
  2124. (clone info #:globals (append (.globals info) strings))))
  2125. (count (expr->number info count))
  2126. (type (make-c-array type count)))
  2127. (if (.function info) (local->info type name o init info)
  2128. (global->info storage type name o init info))))
  2129. (((array-of (ident ,name)) . ,init)
  2130. (let* ((strings (init->strings init info))
  2131. (info (if (null? strings) info
  2132. (clone info #:globals (append (.globals info) strings))))
  2133. (count (length (cadar init)))
  2134. (type (make-c-array type count)))
  2135. (if (.function info) (local->info type name o init info)
  2136. (global->info storage type name o init info))))
  2137. ;; FIXME: recursion
  2138. (((array-of (array-of (ident ,name) ,count1) ,count) . ,init)
  2139. (let* ((strings (init->strings init info))
  2140. (info (if (null? strings) info
  2141. (clone info #:globals (append (.globals info) strings))))
  2142. (count (expr->number info count))
  2143. (count1 (expr->number info count1))
  2144. (type (make-c-array (make-c-array type count1) count)))
  2145. (if (.function info) (local->info type name o init info)
  2146. (global->info storage type name o init info))))
  2147. (_ (error "init-declr->info: not supported: " o))))
  2148. (define (enum-def-list->constants constants fields)
  2149. (let loop ((fields fields) (i 0) (constants constants))
  2150. (if (pair? fields)
  2151. (let ((field (car fields)))
  2152. (mescc:trace (cadr (cadr field)) " <e>")))
  2153. (if (null? fields) constants
  2154. (let* ((field (car fields))
  2155. (name (pmatch field
  2156. ((enum-defn (ident ,name) . _) name)))
  2157. (i (pmatch field
  2158. ((enum-defn ,name) i)
  2159. ((enum-defn ,name ,exp) (expr->number #f exp))
  2160. (_ (error "not supported enum field=~s\n" field)))))
  2161. (loop (cdr fields)
  2162. (1+ i)
  2163. (append constants (list (ident->constant name i))))))))
  2164. (define (init->data type o info)
  2165. (pmatch o
  2166. ((p-expr ,expr) (init->data type expr info))
  2167. ((fixed ,fixed) (int->bv type (expr->number info o) info))
  2168. ((char ,char) (int->bv type (char->integer (string-ref char 0)) info))
  2169. ((string ,string)
  2170. (let ((reg-size (->size "*" info)))
  2171. (if (= reg-size 8) `((#:string ,string) "%0")
  2172. `((#:string ,string)))))
  2173. ((string . ,strings)
  2174. (let ((reg-size (->size "*" info)))
  2175. (if (= reg-size 8) `((#:string ,(string-join strings "")) "%0")
  2176. `((#:string ,(string-join strings ""))))))
  2177. ((ident ,name) (let ((var (ident->variable info name)))
  2178. (if (number? var) (int->bv type var info)
  2179. `((#:address ,var)))))
  2180. ((initzer-list . ,inits)
  2181. (cond ((structured-type? type)
  2182. (map (cut init->data <> <> info) (map cdr (struct->init-fields type)) inits))
  2183. ((c-array? type)
  2184. (let ((size (->size type info)))
  2185. (array-init->data type size `(initzer ,o) info)))
  2186. (else
  2187. (append-map (cut init->data type <> info) inits))))
  2188. (((initzer (initzer-list . ,inits)))
  2189. (init->data type `(initzer-list . ,inits) info))
  2190. ((ref-to (p-expr (ident ,name)))
  2191. (let ((var (ident->variable info name))
  2192. (reg-size (->size "*" info)))
  2193. `((#:address ,var)
  2194. ,@(if (= reg-size 8) '((#:address 0))
  2195. '()))))
  2196. ((ref-to (i-sel (ident ,field) (cast (type-name (decl-spec-list ,struct) (abs-declr (pointer))) (p-expr (fixed ,base)))))
  2197. (let* ((type (ast->type struct info))
  2198. (offset (field-offset info type field))
  2199. (base (cstring->int base)))
  2200. (int->bv type (+ base offset) info)))
  2201. ((,char . _) (guard (char? char)) o)
  2202. ((,number . _) (guard (number? number))
  2203. (append (map (cut int->bv <> <> info) type o)))
  2204. ((initzer ,init) (init->data type init info))
  2205. (((initzer ,init)) (init->data type init info))
  2206. ((cast _ ,expr) (init->data type expr info))
  2207. (() '())
  2208. (_ (let ((number (try-expr->number info o)))
  2209. (cond (number (int->bv type number info))
  2210. (else (error "init->data: not supported: " o)))))))
  2211. (define (int->bv type o info)
  2212. (let ((size (->size type info)))
  2213. (case size
  2214. ((1) (int->bv8 o))
  2215. ((2) (int->bv16 o))
  2216. ((4) (int->bv32 o))
  2217. ((8) (int->bv64 o))
  2218. (else (int->bv64 o)))))
  2219. (define (init->strings o info)
  2220. (let ((globals (.globals info)))
  2221. (pmatch o
  2222. ((p-expr (string ,string))
  2223. (let ((g `(#:string ,string)))
  2224. (if (assoc g globals) '()
  2225. (list (string->global-entry string)))))
  2226. ((p-expr (string . ,strings))
  2227. (let* ((string (string-join strings ""))
  2228. (g `(#:string ,string)))
  2229. (if (assoc g globals) '()
  2230. (list (string->global-entry string)))))
  2231. (((initzer (initzer-list . ,init)))
  2232. (append-map (cut init->strings <> info) init))
  2233. ((initzer ,init)
  2234. (init->strings init info))
  2235. (((initzer ,init))
  2236. (init->strings init info))
  2237. ((initzer-list . ,init)
  2238. (append-map (cut init->strings <> info) init))
  2239. (_ '()))))
  2240. (define (type->info o name info)
  2241. (pmatch o
  2242. ((enum-def (ident ,name) (enum-def-list . ,fields))
  2243. (mescc:trace name " <t>")
  2244. (let* ((type-entry (enum->type-entry name fields))
  2245. (constants (enum-def-list->constants (.constants info) fields)))
  2246. (clone info
  2247. #:types (cons type-entry (.types info))
  2248. #:constants (append constants (.constants info)))))
  2249. ((enum-def (enum-def-list . ,fields))
  2250. (mescc:trace name " <t>")
  2251. (let* ((type-entry (enum->type-entry name fields))
  2252. (constants (enum-def-list->constants (.constants info) fields)))
  2253. (clone info
  2254. #:types (cons type-entry (.types info))
  2255. #:constants (append constants (.constants info)))))
  2256. ((struct-def (field-list . ,fields))
  2257. (mescc:trace name " <t>")
  2258. (let* ((info (fold field->info info fields))
  2259. (type-entry (struct->type-entry info name (append-map (struct-field info) fields))))
  2260. (clone info #:types (cons type-entry (.types info)))))
  2261. ((struct-def (ident ,name) (field-list . ,fields))
  2262. (mescc:trace name " <t>")
  2263. (let* ((info (fold field->info info fields))
  2264. (type-entry (struct->type-entry info name (append-map (struct-field info) fields))))
  2265. (clone info #:types (cons type-entry (.types info)))))
  2266. ((union-def (ident ,name) (field-list . ,fields))
  2267. (mescc:trace name " <t>")
  2268. (let ((type-entry (union->type-entry info name (append-map (struct-field info) fields))))
  2269. (clone info #:types (cons type-entry (.types info)))))
  2270. ((union-def (field-list . ,fields))
  2271. (mescc:trace name " <t>")
  2272. (let ((type-entry (union->type-entry info name (append-map (struct-field info) fields))))
  2273. (clone info #:types (cons type-entry (.types info)))))
  2274. ((enum-ref . _) info)
  2275. ((struct-ref . _) info)
  2276. ((typename ,name) info)
  2277. ((union-ref . _) info)
  2278. ((fixed-type . _) info)
  2279. ((float-type . _) info)
  2280. ((void) info)
  2281. (_ ;;(error "type->info: not supported:" o)
  2282. info
  2283. )))
  2284. (define (field->info o info)
  2285. (pmatch o
  2286. ((comp-decl (decl-spec-list (type-spec (struct-def (ident ,name) (field-list . ,fields)))) . _)
  2287. (let* ((fields (append-map (struct-field info) fields))
  2288. (struct (make-type 'struct (apply + (map (cut field:size <> info) fields)) fields)))
  2289. (clone info #:types (acons `(tag ,name) struct (.types info)))))
  2290. ((comp-decl (decl-spec-list (type-spec (union-def (ident ,name) (field-list . ,fields)))) . _)
  2291. (let* ((fields (append-map (struct-field info) fields))
  2292. (union (make-type 'union (apply + (map (cut field:size <> info) fields)) fields)))
  2293. (clone info #:types (acons `(tag ,name) union (.types info))) ))
  2294. ((comp-decl (decl-spec-list (type-spec (enum-def (enum-def-list . ,fields)))) . _)
  2295. (let ((constants (enum-def-list->constants (.constants info) fields)))
  2296. (clone info
  2297. #:constants (append constants (.constants info)))))
  2298. ((comp-decl (decl-spec-list (type-spec (enum-def (ident ,name) (enum-def-list . ,fields)))) . _)
  2299. (let ((constants (enum-def-list->constants (.constants info) fields))
  2300. (type-entry (enum->type-entry name fields)))
  2301. (clone info
  2302. #:types (cons type-entry (.types info))
  2303. #:constants (append constants (.constants info)))))
  2304. (_ info)))
  2305. ;;; fctn-defn
  2306. (define (param-decl:get-name o)
  2307. (pmatch o
  2308. ((ellipsis) #f)
  2309. ((param-decl (decl-spec-list (type-spec (void)))) #f)
  2310. ((param-decl _ (param-declr ,ast)) (ast->name ast))
  2311. (_ (error "param-decl:get-name not supported:" o))))
  2312. (define (fctn-defn:get-name o)
  2313. (pmatch o
  2314. ((_ (ftn-declr (ident ,name) _) _) name)
  2315. ((_ (ftn-declr (scope (ident ,name)) _) _) name)
  2316. ((_ (ptr-declr (pointer . _) (ftn-declr (ident ,name) _)) _) name)
  2317. (_ (error "fctn-defn:get-name not supported:" o))))
  2318. (define (param-decl:get-type o info)
  2319. (pmatch o
  2320. ((ellipsis) #f)
  2321. ((param-decl (decl-spec-list ,type)) (ast->type type info))
  2322. ((param-decl (decl-spec-list (type-spec ,type)) (param-declr (ptr-declr ,pointer (ident ,name))))
  2323. (let ((rank (pointer->rank pointer)))
  2324. (rank+= (ast->type type info) rank)))
  2325. ((param-decl (decl-spec-list ,type) (param-declr (ptr-declr ,pointer (array-of _))))
  2326. (let ((rank (pointer->rank pointer)))
  2327. (rank+= (ast->type type info) (1+ rank))))
  2328. ((param-decl ,type _) (ast->type type info))
  2329. (_ (error "param-decl:get-type not supported:" o))))
  2330. (define (fctn-defn:get-formals o)
  2331. (pmatch o
  2332. ((_ (ftn-declr _ ,formals) _) formals)
  2333. ((_ (ptr-declr (pointer . _) (ftn-declr _ ,formals)) _) formals)
  2334. (_ (error "fctn-defn->formals: not supported:" o))))
  2335. (define (formal->text n)
  2336. (lambda (o i)
  2337. ;;(i386:formal i n)
  2338. '()
  2339. ))
  2340. (define (param-list->text o info)
  2341. (pmatch o
  2342. ((param-list . ,formals)
  2343. (let ((n (length formals)))
  2344. (wrap-as (append (as info 'function-preamble formals)
  2345. (append-map (formal->text n) formals (iota n))
  2346. (as info 'function-locals)))))
  2347. (_ (error "param-list->text: not supported: " o))))
  2348. (define (param-list->locals o info)
  2349. (pmatch o
  2350. ((param-list . ,formals)
  2351. (let ((n (length formals)))
  2352. (map make-local-entry
  2353. (map param-decl:get-name formals)
  2354. (map (cut param-decl:get-type <> info) formals)
  2355. (iota n -2 -1))))
  2356. (_ (error "param-list->locals: not supported:" o))))
  2357. (define (fctn-defn:get-type info o)
  2358. (pmatch o
  2359. (((decl-spec-list (type-spec ,type)) (ptr-declr ,pointer . _) ,statement)
  2360. (let* ((type (ast->type type info))
  2361. (rank (ptr-declr->rank pointer)))
  2362. (if (zero? rank) type
  2363. (make-pointer type rank))))
  2364. (((decl-spec-list (stor-spec ,store) (type-spec ,type)) (ptr-declr ,pointer . _) ,statement)
  2365. (let* ((type (ast->type type info))
  2366. (rank (ptr-declr->rank pointer)))
  2367. (if (zero? rank) type
  2368. (make-pointer type rank))))
  2369. (((decl-spec-list (type-spec ,type)) . _)
  2370. (ast->type type info))
  2371. (((decl-spec-list (stor-spec ,store) (type-spec ,type)) . _)
  2372. (ast->type type info))
  2373. (_ (error "fctn-defn:get-type: not supported:" o))))
  2374. (define (fctn-defn:get-statement o)
  2375. (pmatch o
  2376. ((_ (ftn-declr (ident _) _) ,statement) statement)
  2377. ((_ (ftn-declr (scope (ident _)) _) ,statement) statement)
  2378. ((_ (ptr-declr (pointer . _) (ftn-declr (ident _) . _)) ,statement) statement)
  2379. (_ (error "fctn-defn:get-statement: not supported: " o))))
  2380. (define (fctn-defn->info o info)
  2381. (define (assert-return text)
  2382. (let ((return (wrap-as (as info 'ret))))
  2383. (if (equal? (list-tail text (- (length text) (length return))) return) text
  2384. (append text return))))
  2385. (let ((name (fctn-defn:get-name o)))
  2386. (mescc:trace name)
  2387. (let* ((type (fctn-defn:get-type info o))
  2388. (formals (fctn-defn:get-formals o))
  2389. (text (param-list->text formals info))
  2390. (locals (param-list->locals formals info))
  2391. (statement (fctn-defn:get-statement o))
  2392. (function (cons name (make-function name type '())))
  2393. (functions (cons function (.functions info)))
  2394. (info (clone info #:locals locals #:function name #:text text #:functions functions #:statics '()))
  2395. (info (ast->info statement info))
  2396. (locals (.locals info))
  2397. (local (and (pair? locals) (car locals)))
  2398. (count (and=> local (compose local:id cdr)))
  2399. (reg-size (->size "*" info))
  2400. (stack (and count (* count reg-size))))
  2401. (if (and stack (getenv "MESC_DEBUG")) (format (current-error-port) " stack: ~a\n" stack))
  2402. (clone info
  2403. #:function #f
  2404. #:globals (append (.statics info) (.globals info))
  2405. #:statics '()
  2406. #:functions (append (.functions info) (list (cons name (make-function name type (assert-return (.text info))))))))))