wmc.py 29 KB

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