wmc.py 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. import os
  2. import os.path
  3. import sys
  4. import lark
  5. GRAMMAR = r"""
  6. start: toplevel+
  7. ?toplevel: include
  8. | funcdef
  9. | arrdec ";"
  10. | vardec ";"
  11. | varinit ";"
  12. | arrinit ";"
  13. | asm ";"
  14. include: "#" "include" FILENAME
  15. FILENAME: "<" /.+/ ">"
  16. funcdef: NAME "(" params ")" block
  17. varinit: NAME
  18. arrinit: NAME "[" INTEGER "]"
  19. vardec: NAME "=" expr
  20. arrdec: NAME "[" expr "]" ("=" expr)?
  21. params:
  22. | NAME ("," NAME)*
  23. block: "{" op* "}"
  24. asm: "asm" "(" STRING+ ")"
  25. ?op: block
  26. | label
  27. | goto ";"
  28. | vardec ";"
  29. | arrdec ";"
  30. | varinit ";"
  31. | arrinit ";"
  32. | inc ";"
  33. | dec ";"
  34. | rinc ";"
  35. | rdec ";"
  36. | asm ";"
  37. | funcall ";"
  38. | if
  39. | while
  40. | for
  41. | return ";"
  42. label: NAME ":"
  43. goto: "goto" NAME
  44. if: "if" "(" expr ")" op ("else" op)?
  45. while: "while" "(" expr ")" op
  46. for: "for" "(" vardec ";" expr ";" (inc|dec|vardec|funcall) ")" op
  47. return: "return" expr
  48. inc: NAME "++"
  49. dec: NAME "--"
  50. rinc: "++" NAME
  51. rdec: "--" NAME
  52. funcall: NAME "(" args ")"
  53. args:
  54. | [expr ("," expr)*]
  55. ?expr: op1
  56. | op1 "?" op1 ":" expr -> ifexpr
  57. ?op1: op2
  58. | vardec
  59. | op1 "==" op1 -> equals
  60. | op1 "!=" op1 -> not_equals
  61. | op1 "+" op2 -> plus
  62. | op1 "-" op2 -> minus
  63. ?op2: op3
  64. | op2 "*" op2 -> times
  65. | op2 "/" op3 -> divide
  66. | op2 "%" op3 -> modulo
  67. | op2 "<" op3 -> less
  68. | op2 ">" op3 -> greater
  69. | op2 "<=" op3 -> less_or_equals
  70. | op2 ">=" op3 -> greater_or_equals
  71. ?op3: op4
  72. | op3 "**" op4 -> raise
  73. ?op4: op5
  74. | op4 "||" op4 -> or
  75. | op4 "&&" op4 -> and
  76. | "!" atom -> not
  77. | "*" atom -> deref
  78. ?op5: atom
  79. | op5 "[" op1 "]" -> index
  80. ?atom: "(" op1 ")"
  81. | NAME
  82. | INTEGER
  83. | FLOAT
  84. | CHAR
  85. | STRING
  86. | "-" atom -> negate
  87. | array
  88. | funcall
  89. | inc
  90. | dec
  91. | rinc
  92. | rdec
  93. array: "{" atom ("," atom)* "}"
  94. NAME: /[A-Za-z_][a-zA-Z0-9_]*/
  95. INTEGER: /[0-9]+/
  96. FLOAT: /[0-9]+\.[0-9]+/
  97. CHAR: /'(.|(\\.))'/
  98. _STRING_INNER: /(.|\n)*?/
  99. _STRING_ESC_INNER: _STRING_INNER /(?<!\\)(\\\\)*?/
  100. STRING: "\"" _STRING_ESC_INNER "\""
  101. IG: /[ \t\r\n]+/
  102. COM: /\/\*(.|\!)*\*\//
  103. %ignore IG
  104. %ignore COM
  105. """
  106. def parse_escape(s):
  107. return bytes(s, "utf-8").decode("unicode_escape")
  108. class Buffer:
  109. def __init__(self, *init):
  110. self.buffer = list(init)
  111. def emit(self, asm, *args):
  112. if type(asm) is list:
  113. self.buffer.extend(asm)
  114. elif type(asm) is Buffer:
  115. self.buffer.extend(asm.buffer)
  116. else:
  117. self.buffer.append(asm.format(*args))
  118. def generate(self):
  119. return "\n".join(self.buffer)
  120. def __add__(self, other):
  121. if type(other) is Buffer:
  122. return Buffer(
  123. *self.buffer + other.buffer
  124. )
  125. raise TypeError
  126. class Scope:
  127. def __init__(self):
  128. self.scopes = []
  129. self.ndx = 0
  130. self.names = set()
  131. def new(self):
  132. self.scopes.append((self.ndx, {}, {}))
  133. self.ndx += 1
  134. def leave(self):
  135. self.scopes.pop()
  136. def add_label(self, name):
  137. renamed = f"__{self.scopes[-1][0]}l_{name}"
  138. self.scopes[-1][2][name] = renamed
  139. return renamed
  140. def get_label(self, name):
  141. if name not in self.scopes[-1][2]:
  142. raise Exception(f"Undeclared label: '{name}`.")
  143. return self.scopes[-1][2][name]
  144. def is_local(self, name):
  145. return name in self.scopes[-1][1]
  146. def insert(self, name):
  147. renamed = f"__{self.scopes[-1][0]}_{name}"
  148. self.scopes[-1][1][name] = renamed
  149. self.names.add(renamed)
  150. return renamed
  151. def find(self, name):
  152. for _, scope, _ in self.scopes[::-1]:
  153. if name in scope:
  154. return scope[name]
  155. raise Exception(f"Undeclared identifier: '{name}`.")
  156. def __contains__(self, name):
  157. for _, scope, _ in self.scopes[::-1]:
  158. if name in scope:
  159. return True
  160. return False
  161. def __getitem__(self, name):
  162. if name in self:
  163. return self.find(name)
  164. return self.insert(name)
  165. def __iter__(self):
  166. for _, scope, _ in self.scopes[::-1]:
  167. for name in scope:
  168. yield (name, scope[name])
  169. @property
  170. def is_toplevel(self):
  171. return self.scopes[-1][0] == 0
  172. class Func:
  173. def __init__(self, argc, params):
  174. self.argc = argc
  175. self.params = params
  176. class WMC:
  177. def __init__(self):
  178. self.funcs = {}
  179. self.used_symbols = {}
  180. self.where = "toplevel"
  181. self.scope = Scope()
  182. self.scope.new()
  183. self.compiled_funcs = {}
  184. self.arrays_buffer = Buffer()
  185. self.init_buffer = Buffer()
  186. self.buffer = Buffer(
  187. "jw __main",
  188. "pop Y",
  189. "mov 80 _dirBuf",
  190. "mov Y _dirBuf+1",
  191. "dir _dirBuf",
  192. "hlt",
  193. "_dirBuf:0*4",
  194. )
  195. self.label_ndx = 0
  196. self.included_files = set()
  197. self.parser = lark.Lark(GRAMMAR)
  198. def record_usage(self, name):
  199. if name in self.used_symbols:
  200. self.used_symbols[name].add(self.where)
  201. else:
  202. self.used_symbols[name] = set([self.where])
  203. def is_used(self, name):
  204. if name in ("main", "toplevel"):
  205. return True
  206. if name not in self.used_symbols:
  207. return False
  208. for other in self.used_symbols[name]:
  209. if other == name:
  210. continue
  211. if self.is_used(other):
  212. return True
  213. return False
  214. def make_label(self):
  215. name = f"__{self.label_ndx}l"
  216. self.label_ndx += 1
  217. return name
  218. def make_array(self, value):
  219. name = self.make_label()
  220. self.arrays_buffer.emit(
  221. "{}:{}",
  222. name, value
  223. )
  224. return name
  225. def compile_literal(self, node):
  226. if type(node) is lark.Token:
  227. if node.type == "NAME":
  228. value = self.scope.find(node.value)
  229. self.record_usage(value)
  230. return value
  231. elif node.type in ("INTEGER", "FLOAT"):
  232. return node.value
  233. elif node.type == "CHAR":
  234. return str(ord(parse_escape(node.value[1:-1])))
  235. elif node.type == "STRING":
  236. value = parse_escape(node.value[1:-1])
  237. value = map(ord, value)
  238. value = map(str, value)
  239. value = " ".join(value)
  240. value += " 0"
  241. return value
  242. elif node.data == "array":
  243. value = []
  244. for child in node.children:
  245. value.append(
  246. self.compile_literal(child)
  247. )
  248. return " ".join(value)
  249. raise Exception(f"Not implemented: {node}")
  250. def compile_unary_expr(self, node, *ops):
  251. buffer = Buffer()
  252. buffer.emit(
  253. self.compile_expr(
  254. node.children[0]
  255. )
  256. )
  257. for op in ops:
  258. buffer.emit(op)
  259. return buffer
  260. def compile_binary_expr(self, node):
  261. buffer = Buffer()
  262. buffer.emit(
  263. self.compile_expr(
  264. node.children[0]
  265. )
  266. )
  267. buffer.emit('push Y')
  268. buffer.emit(
  269. self.compile_expr(
  270. node.children[1]
  271. )
  272. )
  273. buffer.emit('push Y')
  274. buffer.emit('pop X')
  275. buffer.emit('pop Y')
  276. return buffer
  277. def compile_compare_expr(self, node, *ops, true='1', false='0'):
  278. buffer = Buffer()
  279. ret_label = self.make_label()
  280. exit_label = self.make_label()
  281. buffer.emit(
  282. self.compile_binary_expr(
  283. node
  284. )
  285. )
  286. for op in ops:
  287. buffer.emit(
  288. op,
  289. ret_label
  290. )
  291. buffer.emit(
  292. "mov {} Y",
  293. false
  294. )
  295. buffer.emit(
  296. "jmp {}",
  297. exit_label
  298. )
  299. buffer.emit(
  300. "{}:",
  301. ret_label
  302. )
  303. buffer.emit(
  304. "mov {} Y",
  305. true
  306. )
  307. buffer.emit(
  308. "{}:",
  309. exit_label
  310. )
  311. return buffer
  312. def compile_expr(self, node):
  313. buffer = Buffer()
  314. if type(node) is lark.Token:
  315. if node.type == "NAME":
  316. buffer.emit(
  317. "mov {} Y",
  318. self.compile_literal(node)
  319. )
  320. elif node.type in ("INTEGER", "FLOAT"):
  321. buffer.emit(
  322. "mov {} Y",
  323. self.compile_literal(node)
  324. )
  325. elif node.type == "CHAR":
  326. buffer.emit(
  327. "mov {} Y",
  328. self.compile_literal(node)
  329. )
  330. elif node.type == "STRING":
  331. buffer.emit(
  332. "ld {} Y",
  333. self.make_array(
  334. self.compile_literal(node)
  335. )
  336. )
  337. else:
  338. raise Exception(f"Not implemented: {node}")
  339. elif node.data == "ifexpr":
  340. else_label = self.make_label()
  341. exit_label = self.make_label()
  342. buffer.emit(
  343. self.compile_expr(
  344. node.children[0]
  345. )
  346. )
  347. buffer.emit(
  348. "nbnz Y {}",
  349. else_label
  350. )
  351. buffer.emit(
  352. self.compile_expr(
  353. node.children[1]
  354. )
  355. )
  356. buffer.emit(
  357. "jmp {}",
  358. exit_label
  359. )
  360. buffer.emit(
  361. "{}:",
  362. else_label
  363. )
  364. buffer.emit(
  365. self.compile_expr(
  366. node.children[2]
  367. )
  368. )
  369. buffer.emit(
  370. "{}:",
  371. exit_label
  372. )
  373. elif node.data == "equals":
  374. buffer.emit(
  375. self.compile_compare_expr(
  376. node,
  377. "sblez X Y !",
  378. "nbnz Y {}",
  379. true='1',
  380. false='0'
  381. )
  382. )
  383. elif node.data == "not_equals":
  384. buffer.emit(
  385. self.compile_compare_expr(
  386. node,
  387. "sblez X Y !",
  388. "nbnz Y {}",
  389. true='0',
  390. false='1'
  391. )
  392. )
  393. elif node.data == "plus":
  394. buffer.emit(
  395. self.compile_binary_expr(
  396. node
  397. )
  398. )
  399. buffer.emit(
  400. "ablez X Y !"
  401. )
  402. elif node.data == "minus":
  403. buffer.emit(
  404. self.compile_binary_expr(
  405. node
  406. )
  407. )
  408. buffer.emit(
  409. "sblez X Y !"
  410. )
  411. elif node.data == "times":
  412. buffer.emit(
  413. self.compile_binary_expr(
  414. node
  415. )
  416. )
  417. buffer.emit(
  418. "mbnz X Y !"
  419. )
  420. elif node.data == "divide":
  421. buffer.emit(
  422. self.compile_binary_expr(
  423. node
  424. )
  425. )
  426. buffer.emit(
  427. "vblz X Y !"
  428. )
  429. elif node.data == "modulo":
  430. buffer.emit(
  431. self.compile_binary_expr(
  432. node
  433. )
  434. )
  435. buffer.emit(
  436. "modbz X Y !"
  437. )
  438. elif node.data == "raise":
  439. buffer.emit(
  440. self.compile_binary_expr(
  441. node
  442. )
  443. )
  444. buffer.emit(
  445. "mov 12 _dirBuf"
  446. )
  447. buffer.emit(
  448. "mov X _dirBuf+1"
  449. )
  450. buffer.emit(
  451. "mov Y _dirBuf+2"
  452. )
  453. buffer.emit(
  454. "dir _dirBuf"
  455. )
  456. buffer.emit(
  457. "mov _dirBuf+2 Y"
  458. )
  459. elif node.data == "or":
  460. true_label = self.make_label()
  461. exit_label = self.make_label()
  462. buffer.emit(
  463. self.compile_expr(
  464. node.children[0]
  465. )
  466. )
  467. buffer.emit(
  468. "nbnz Y !"
  469. )
  470. buffer.emit(
  471. "nbnz Y {}",
  472. true_label
  473. )
  474. buffer.emit(
  475. self.compile_expr(
  476. node.children[1]
  477. )
  478. )
  479. buffer.emit(
  480. "jmp {}",
  481. exit_label
  482. )
  483. buffer.emit(
  484. "{}:",
  485. true_label
  486. )
  487. buffer.emit(
  488. "mov 1 Y"
  489. )
  490. buffer.emit(
  491. "{}:",
  492. exit_label
  493. )
  494. elif node.data == "and":
  495. false_label = self.make_label()
  496. exit_label = self.make_label()
  497. buffer.emit(
  498. self.compile_expr(
  499. node.children[0]
  500. )
  501. )
  502. buffer.emit(
  503. "nbnz Y {}",
  504. false_label
  505. )
  506. buffer.emit(
  507. self.compile_expr(
  508. node.children[1]
  509. )
  510. )
  511. buffer.emit(
  512. "jmp {}",
  513. exit_label
  514. )
  515. buffer.emit(
  516. "{}:",
  517. false_label
  518. )
  519. buffer.emit(
  520. "mov 0 Y"
  521. )
  522. buffer.emit(
  523. "{}:",
  524. exit_label
  525. )
  526. elif node.data == "less":
  527. buffer.emit(
  528. self.compile_compare_expr(
  529. node,
  530. "inc Y",
  531. "sblez X Y {}"
  532. )
  533. )
  534. elif node.data == "greater":
  535. buffer.emit(
  536. self.compile_compare_expr(
  537. node,
  538. "dec Y",
  539. "sblez X Y {}",
  540. true='0',
  541. false='1'
  542. )
  543. )
  544. elif node.data == "less_or_equals":
  545. buffer.emit(
  546. self.compile_compare_expr(
  547. node,
  548. "sblez X Y {}"
  549. )
  550. )
  551. elif node.data == "greater_or_equals":
  552. buffer.emit(
  553. self.compile_compare_expr(
  554. node,
  555. "inc Y",
  556. "sblez X Y {}",
  557. true='0',
  558. false='1'
  559. )
  560. )
  561. elif node.data == "not":
  562. buffer.emit(
  563. self.compile_unary_expr(
  564. node,
  565. "nbnz Y !"
  566. )
  567. )
  568. elif node.data == "deref":
  569. buffer.emit(
  570. self.compile_unary_expr(
  571. node,
  572. "la Y Y"
  573. )
  574. )
  575. elif node.data == "index":
  576. buffer.emit(
  577. self.compile_binary_expr(
  578. node
  579. )
  580. )
  581. buffer.emit(
  582. "ablez X Y !"
  583. )
  584. buffer.emit(
  585. "la Y Y"
  586. )
  587. elif node.data == "negate":
  588. buffer.emit(
  589. self.compile_unary_expr(
  590. node,
  591. "mov Y X",
  592. "sblez X Y !",
  593. "sblez X Y !",
  594. )
  595. )
  596. elif node.data == "array":
  597. buffer.emit(
  598. "ld {} Y",
  599. self.make_array(
  600. self.compile_literal(node)
  601. )
  602. )
  603. elif node.data == "inc":
  604. name = self.scope[node.children[0].value]
  605. self.record_usage(name)
  606. buffer.emit(
  607. "mov {} Y",
  608. name
  609. )
  610. buffer.emit(
  611. "inc {}",
  612. name
  613. )
  614. elif node.data == "dec":
  615. name = self.scope[node.children[0].value]
  616. self.record_usage(name)
  617. buffer.emit(
  618. "mov {} Y"
  619. )
  620. buffer.emit(
  621. "dec {}",
  622. name
  623. )
  624. elif node.data == "rinc":
  625. name = self.scope[node.children[0].value]
  626. self.record_usage(name)
  627. buffer.emit(
  628. "inc {}",
  629. name
  630. )
  631. buffer.emit(
  632. "mov {} Y",
  633. name
  634. )
  635. elif node.data == "rdec":
  636. name = self.scope[node.children[0].value]
  637. self.record_usage(name)
  638. buffer.emit(
  639. "dec {}",
  640. name
  641. )
  642. buffer.emit(
  643. "mov {} Y"
  644. )
  645. elif node.data == "funcall":
  646. buffer.emit(
  647. self.compile_funcall(node, dest='Y')
  648. )
  649. else:
  650. raise Exception(f"Not implemented: {node}")
  651. return buffer
  652. def compile_funcall(self, node, dest='Y'):
  653. buffer = Buffer()
  654. name = node.children[0].value
  655. if name not in self.funcs:
  656. raise Exception(f"Call to an undeclared function: '{name}`.")
  657. if self.funcs[name].argc != len(node.children[1].children):
  658. raise Exception(f"Function '{name}` expects {self.funcs[name].argc} arguments, but got {node.children[1].children}.")
  659. for arg in node.children[1].children[::-1]:
  660. buffer.emit(
  661. self.compile_expr(arg)
  662. )
  663. buffer.emit(
  664. "push Y"
  665. )
  666. buffer.emit(
  667. "jw __{}",
  668. name
  669. )
  670. buffer.emit(
  671. "pop {}",
  672. dest
  673. )
  674. self.record_usage(name)
  675. return buffer
  676. def compile_asm(self, node):
  677. buffer = Buffer()
  678. table = {}
  679. for name, renamed in self.scope:
  680. table[name] = renamed
  681. for child in node.children:
  682. value = parse_escape(child.value[1:-1])
  683. for name in table:
  684. if f"{{{name}}}" in value:
  685. self.record_usage(table[name])
  686. try:
  687. value = value.format(
  688. **table
  689. )
  690. except:
  691. raise Exception("Malformed asm directive.")
  692. buffer.emit(value)
  693. return buffer
  694. def compile_arrdec(self, node):
  695. buffer = Buffer()
  696. name = node.children[0].value
  697. if name in self.scope and len(node.children) == 3: # Index assignment.
  698. name = self.scope.find(name)
  699. self.record_usage(name)
  700. buffer.emit(
  701. self.compile_expr(
  702. node.children[1]
  703. )
  704. )
  705. buffer.emit(
  706. "mov {} X",
  707. name
  708. )
  709. buffer.emit(
  710. "ablez X Y !"
  711. )
  712. buffer.emit(
  713. "push Y"
  714. )
  715. buffer.emit(
  716. self.compile_expr(
  717. node.children[2]
  718. )
  719. )
  720. buffer.emit(
  721. "pop X"
  722. )
  723. buffer.emit(
  724. "str Y X"
  725. )
  726. return buffer
  727. if not self.scope.is_toplevel and self.scope.is_local(name):
  728. raise Exception(f"Duplicated declaration of a local variable: '{node.children[0].value}`.")
  729. name = self.scope[name]
  730. self.record_usage(name)
  731. count = int(node.children[1].value)
  732. if count <= 0:
  733. raise Exception(f"Illegal array declaration '{node.children[0].value}`: array size should be >0, but it is {count}.")
  734. if len(node.children) == 3:
  735. value = self.compile_literal(node.children[2])
  736. size = len(value.split(" ")) # Dirty.
  737. if size < count:
  738. value += f" 0*{count-size}"
  739. elif size != count:
  740. raise Exception(f"Illegal array declaration '{node.children[0].value}`: value size is {size}, but expected {count}.")
  741. buffer.emit(
  742. "ld {} Y",
  743. self.make_array(value)
  744. )
  745. else:
  746. buffer.emit(
  747. "ld {} Y",
  748. self.make_array(f"0*{count}")
  749. )
  750. buffer.emit(
  751. "mov Y {}",
  752. name
  753. )
  754. return buffer
  755. def compile_op(self, node):
  756. buffer = Buffer()
  757. if node.data == "block":
  758. buffer.emit(
  759. self.compile_block(
  760. node
  761. )
  762. )
  763. elif node.data == "label":
  764. buffer.emit(
  765. "{}:",
  766. self.scope.get_label(node.children[0].value)
  767. )
  768. elif node.data == "goto":
  769. buffer.emit(
  770. "jmp {}",
  771. self.scope.get_label(node.children[0].value)
  772. )
  773. elif node.data == "varinit":
  774. name = node.children[0].value
  775. if self.scope.is_local(name):
  776. raise Exception(f"Duplicated declaration of a local variable: '{name}`.")
  777. self.scope.insert(name)
  778. elif node.data == "vardec":
  779. name = self.scope[node.children[0].value]
  780. self.record_usage(name)
  781. buffer.emit(
  782. self.compile_expr(node.children[1])
  783. )
  784. buffer.emit(
  785. "mov Y {}",
  786. name
  787. )
  788. elif node.data in ("arrdec", "arrinit"):
  789. buffer.emit(
  790. self.compile_arrdec(node)
  791. )
  792. elif node.data in ("inc", "rinc"):
  793. name = self.scope[node.children[0].value]
  794. self.record_usage(name)
  795. buffer.emit(
  796. "inc {}",
  797. name
  798. )
  799. elif node.data == ("dec", "rdec"):
  800. name = self.scope[node.children[0].value]
  801. self.record_usage(name)
  802. buffer.emit(
  803. "dec {}",
  804. name
  805. )
  806. elif node.data == "funcall":
  807. buffer.emit(
  808. self.compile_funcall(node, dest='ZZ')
  809. )
  810. elif node.data == "return":
  811. buffer.emit(
  812. self.compile_expr(
  813. node.children[0]
  814. )
  815. )
  816. buffer.emit("push Y")
  817. buffer.emit("ret")
  818. elif node.data == "asm":
  819. buffer.emit(
  820. self.compile_asm(node)
  821. )
  822. elif node.data == "if":
  823. else_label = self.make_label()
  824. exit_label = self.make_label()
  825. buffer.emit(
  826. self.compile_expr(
  827. node.children[0]
  828. )
  829. )
  830. buffer.emit(
  831. "nbnz Y {}",
  832. else_label
  833. )
  834. buffer.emit(
  835. self.compile_op(
  836. node.children[1]
  837. )
  838. )
  839. buffer.emit(
  840. "jmp {}",
  841. exit_label
  842. )
  843. buffer.emit(
  844. "{}:",
  845. else_label
  846. )
  847. if len(node.children) == 3:
  848. buffer.emit(
  849. self.compile_op(
  850. node.children[2]
  851. )
  852. )
  853. buffer.emit(
  854. "{}:",
  855. exit_label
  856. )
  857. elif node.data == "while":
  858. loop_label = self.make_label()
  859. exit_label = self.make_label()
  860. buffer.emit(
  861. "{}:",
  862. loop_label
  863. )
  864. buffer.emit(
  865. self.compile_expr(
  866. node.children[0]
  867. )
  868. )
  869. buffer.emit(
  870. "nbnz Y {}",
  871. exit_label
  872. )
  873. buffer.emit(
  874. self.compile_op(
  875. node.children[1]
  876. )
  877. )
  878. buffer.emit(
  879. "jmp {}",
  880. loop_label
  881. )
  882. buffer.emit(
  883. "{}:",
  884. exit_label
  885. )
  886. elif node.data == "for":
  887. loop_label = self.make_label()
  888. exit_label = self.make_label()
  889. self.scope.new()
  890. buffer.emit(
  891. self.compile_op(
  892. node.children[0]
  893. )
  894. )
  895. buffer.emit(
  896. "{}:",
  897. loop_label
  898. )
  899. buffer.emit(
  900. self.compile_expr(
  901. node.children[1]
  902. )
  903. )
  904. buffer.emit(
  905. "nbnz Y {}",
  906. exit_label
  907. )
  908. buffer.emit(
  909. self.compile_op(
  910. node.children[3]
  911. )
  912. )
  913. buffer.emit(
  914. self.compile_op(
  915. node.children[2]
  916. )
  917. )
  918. self.scope.leave()
  919. buffer.emit(
  920. "jmp {}",
  921. loop_label
  922. )
  923. buffer.emit(
  924. "{}:",
  925. exit_label
  926. )
  927. else:
  928. raise Exception(f"Not implemented: {node}")
  929. return buffer
  930. def collect_labels(self, node):
  931. for child in node.children:
  932. if child.data == "label":
  933. self.scope.add_label(child.children[0].value)
  934. def compile_block(self, node, *prepend_names, scope=True):
  935. if scope:
  936. self.scope.new()
  937. for name in prepend_names:
  938. self.scope.insert(name)
  939. buffer = Buffer()
  940. self.collect_labels(node)
  941. for child in node.children:
  942. buffer.emit(
  943. self.compile_op(child)
  944. )
  945. if scope:
  946. self.scope.leave()
  947. return buffer
  948. def compile_toplevel(self, node):
  949. buffer = Buffer()
  950. if node.data == "funcdef":
  951. name = node.children[0].value
  952. params = self.funcs[name].params
  953. buffer.emit("__{}:", name)
  954. for param in params:
  955. buffer.emit(
  956. "pop __{}_{}",
  957. self.scope.ndx, param
  958. )
  959. self.where = name
  960. buffer.emit(
  961. self.compile_block(
  962. node.children[2],
  963. *params
  964. )
  965. )
  966. buffer.emit(
  967. "push Z"
  968. )
  969. buffer.emit(
  970. "ret"
  971. )
  972. elif node.data == "vardec":
  973. name = node.children[0].value
  974. self.init_buffer.emit(
  975. self.compile_expr(node.children[1])
  976. )
  977. self.init_buffer.emit(
  978. "mov Y __0_{}",
  979. name
  980. )
  981. self.record_usage(f"__0__{name}")
  982. elif node.data in ("arrdec", "arrinit"):
  983. self.init_buffer.emit(
  984. self.compile_arrdec(node)
  985. )
  986. elif node.data == "asm":
  987. buffer.emit(
  988. self.compile_asm(node)
  989. )
  990. elif node.data == "include":
  991. filename = node.children[0].value[1:-1]
  992. if not os.path.isfile(filename):
  993. filename = os.path.join(os.getenv("WC_I"), filename)
  994. if not os.path.isfile(filename):
  995. raise Exception(f"No such file: '{os.path.basename(filename)}`.")
  996. if filename not in self.included_files:
  997. with open(filename, "r") as f:
  998. self.compile_program(f.read())
  999. self.included_files.add(filename)
  1000. elif node.data == "varinit":
  1001. pass
  1002. else:
  1003. raise Exception(f"Not implemented: {node}")
  1004. return buffer
  1005. def collect_toplevel(self, ast):
  1006. for node in ast.children:
  1007. if node.data == "funcdef":
  1008. name = node.children[0].value
  1009. if name in self.funcs:
  1010. raise Exception(f"Duplicated function declaration: '{name}`.")
  1011. self.funcs[name] = Func(
  1012. len(node.children[1].children),
  1013. tuple(map(lambda t: t.value, node.children[1].children))
  1014. )
  1015. elif node.data in ("varinit", "vardec", "arrinit", "arrdec"):
  1016. name = node.children[0].value
  1017. if name in self.scope:
  1018. raise Exception(f"Duplicated top-level variable declaration: '{name}`.")
  1019. self.scope.insert(name) # Because we're at the top-level rn.
  1020. def compile_program(self, text):
  1021. ast = self.parser.parse(text)
  1022. #print(ast.pretty())
  1023. self.collect_toplevel(ast)
  1024. for node in ast.children:
  1025. buffer = self.compile_toplevel(node)
  1026. if node.data == "funcdef":
  1027. self.compiled_funcs[node.children[0].value] = buffer
  1028. else:
  1029. self.buffer.emit(buffer)
  1030. def compile(self, text):
  1031. self.compile_program(text)
  1032. for name in self.compiled_funcs:
  1033. if self.is_used(name):
  1034. self.buffer.emit(self.compiled_funcs[name])
  1035. for param in self.funcs[name].params:
  1036. self.record_usage(param)
  1037. self.buffer = self.init_buffer + self.buffer + self.arrays_buffer
  1038. for name in self.scope.names:
  1039. if self.is_used(name):
  1040. self.buffer.emit(
  1041. "{}:0", name
  1042. )
  1043. if "main" not in self.funcs:
  1044. raise Exception("Missing 'main` function.")
  1045. return self.buffer.generate() + "\n"
  1046. wmc = WMC()
  1047. try:
  1048. if len(sys.argv) == 3:
  1049. with open(sys.argv[1], "r") as fin:
  1050. with open(sys.argv[2], "w") as fout:
  1051. fout.write(wmc.compile(fin.read()))
  1052. else:
  1053. sys.stdout.write(wmc.compile(sys.stdin.read()))
  1054. except Exception as e:
  1055. #__import__('traceback').print_exc()
  1056. print(e)
  1057. sys.exit(1)