wmc.py 30 KB

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