mm0.g 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. # This file is part of asmc, a bootstrapping OS with minimal seed
  2. # Copyright (C) 2019 Giovanni Mascellani <gio@debian.org>
  3. # https://gitlab.com/giomasce/asmc
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. fun mm0_is_digit 1 {
  15. $c
  16. @c 0 param = ;
  17. '0' c <= c '9' <= && ret ;
  18. }
  19. fun mm0_is_alpha 1 {
  20. $c
  21. @c 0 param = ;
  22. 'a' c <= c 'z' <= && 'A' c <= c 'Z' <= && || ret ;
  23. }
  24. fun mm0_is_white 1 {
  25. $c
  26. @c 0 param = ;
  27. c ' ' == c '\n' == || c '\r' == || c '\t' == || ret ;
  28. }
  29. const MM0TOK_TYPE 0
  30. const MM0TOK_VALUE 4
  31. const SIZEOF_MM0TOK 8
  32. const MM0TOK_TYPE_SYMBOL 1
  33. const MM0TOK_TYPE_IDENT 2
  34. const MM0TOK_TYPE_NUMBER 3
  35. const MM0TOK_TYPE_MATH 4
  36. const MM0TOK_SYMB_STAR 1
  37. const MM0TOK_SYMB_DOT 2
  38. const MM0TOK_SYMB_COLON 3
  39. const MM0TOK_SYMB_SEMICOLON 4
  40. const MM0TOK_SYMB_OPEN 5
  41. const MM0TOK_SYMB_CLOSED 6
  42. const MM0TOK_SYMB_ARROW 7
  43. const MM0TOK_SYMB_OPENBR 8
  44. const MM0TOK_SYMB_CLOSEDBR 9
  45. const MM0TOK_SYMB_ASSIGN 10
  46. fun mm0tok_init 2 {
  47. $type
  48. $value
  49. @type 1 param = ;
  50. @value 0 param = ;
  51. $tok
  52. @tok SIZEOF_MM0TOK malloc = ;
  53. tok MM0TOK_TYPE take_addr type = ;
  54. tok MM0TOK_VALUE take_addr value = ;
  55. tok ret ;
  56. }
  57. fun mm0tok_destroy 1 {
  58. $tok
  59. @tok 0 param = ;
  60. $type
  61. @type tok MM0TOK_TYPE take = ;
  62. if type MM0TOK_TYPE_IDENT == type MM0TOK_TYPE_MATH == || {
  63. tok MM0TOK_VALUE take free ;
  64. }
  65. tok free ;
  66. }
  67. fun mm0tok_cmp_value 3 {
  68. $tok
  69. $type
  70. $value
  71. @tok 2 param = ;
  72. @type 1 param = ;
  73. @value 0 param = ;
  74. if tok MM0TOK_TYPE take type != { 0 ret ; }
  75. if type MM0TOK_TYPE_SYMBOL == {
  76. tok MM0TOK_VALUE take value == ret ;
  77. }
  78. if type MM0TOK_TYPE_IDENT == {
  79. tok MM0TOK_VALUE take value strcmp 0 == ret ;
  80. }
  81. if type MM0TOK_TYPE_NUMBER == {
  82. tok MM0TOK_VALUE take value == ret ;
  83. }
  84. if type MM0TOK_TYPE_MATH == {
  85. tok MM0TOK_VALUE take value strcmp 0 == ret ;
  86. }
  87. 0 "mm0tok_expect_type_value: illegal token type" assert_msg ;
  88. }
  89. fun mm0tok_dump 1 {
  90. $tok
  91. @tok 0 param = ;
  92. $type
  93. $value
  94. @type tok MM0TOK_TYPE take = ;
  95. @value tok MM0TOK_VALUE take = ;
  96. if type MM0TOK_TYPE_SYMBOL == {
  97. if value MM0TOK_SYMB_STAR == { "STAR" log ; ret ; }
  98. if value MM0TOK_SYMB_DOT == { "DOT" log ; ret ; }
  99. if value MM0TOK_SYMB_COLON == { "COLON" log ; ret ; }
  100. if value MM0TOK_SYMB_SEMICOLON == { "SEMICOLON" log ; ret ; }
  101. if value MM0TOK_SYMB_OPEN == { "OPEN" log ; ret ; }
  102. if value MM0TOK_SYMB_CLOSED == { "CLOSED" log ; ret ; }
  103. if value MM0TOK_SYMB_ARROW == { "ARROW" log ; ret ; }
  104. if value MM0TOK_SYMB_OPENBR == { "OPENBR" log ; ret ; }
  105. if value MM0TOK_SYMB_CLOSEDBR == { "CLOSEDBR" log ; ret ; }
  106. if value MM0TOK_SYMB_ASSIGN == { "ASSIGN" log ; ret ; }
  107. }
  108. if type MM0TOK_TYPE_IDENT == {
  109. value log ;
  110. ret ;
  111. }
  112. if type MM0TOK_TYPE_NUMBER == {
  113. value itoa log ;
  114. ret ;
  115. }
  116. if type MM0TOK_TYPE_MATH == {
  117. "$" log ;
  118. value log ;
  119. "$" log ;
  120. ret ;
  121. }
  122. }
  123. const MM0LEXER_FILENAME 0
  124. const MM0LEXER_FD 4
  125. const MM0LEXER_UNREAD 8
  126. const SIZEOF_MM0LEXER 12
  127. fun mm0lexer_init 1 {
  128. $filename
  129. @filename 0 param = ;
  130. $fd
  131. @fd filename vfs_open = ;
  132. if fd ! {
  133. 0 ret ;
  134. }
  135. $lexer
  136. @lexer SIZEOF_MM0LEXER malloc = ;
  137. lexer MM0LEXER_FILENAME take_addr filename = ;
  138. lexer MM0LEXER_FD take_addr fd = ;
  139. lexer MM0LEXER_UNREAD take_addr 0 = ;
  140. lexer ret ;
  141. }
  142. fun mm0lexer_destroy 1 {
  143. $lexer
  144. @lexer 0 param = ;
  145. lexer MM0LEXER_FD take vfs_close ;
  146. lexer free ;
  147. }
  148. fun mm0lexer_read 1 {
  149. $lexer
  150. @lexer 0 param = ;
  151. $c
  152. @c lexer MM0LEXER_UNREAD take = ;
  153. if c {
  154. lexer MM0LEXER_UNREAD take_addr 0 = ;
  155. c ret ;
  156. } else {
  157. lexer MM0LEXER_FD take vfs_read ret ;
  158. }
  159. }
  160. fun mm0lexer_unread 2 {
  161. $lexer
  162. $c
  163. @lexer 1 param = ;
  164. @c 0 param = ;
  165. lexer MM0LEXER_UNREAD take ! "mm0lexer_unread: unread buffer already used" assert_msg ;
  166. lexer MM0LEXER_UNREAD take_addr c = ;
  167. }
  168. fun mm0lexer_read_skip 1 {
  169. $lexer
  170. @lexer 0 param = ;
  171. while 1 {
  172. $c
  173. @c lexer mm0lexer_read = ;
  174. # Check comment
  175. if c '-' == {
  176. @c lexer mm0lexer_read = ;
  177. c '-' == "mm0lexer_read_skip: invalid single dash" assert_msg ;
  178. while c '\n' != {
  179. @c lexer mm0lexer_read = ;
  180. }
  181. } else {
  182. if c mm0_is_white ! {
  183. c ret ;
  184. }
  185. }
  186. }
  187. }
  188. fun mm0lexer_get_token_or_eof_ 1 {
  189. $lexer
  190. @lexer 0 param = ;
  191. $c
  192. @c lexer mm0lexer_read_skip = ;
  193. # End of file
  194. if c 0xffffffff == {
  195. 0 ret ;
  196. }
  197. # Symbol token
  198. if c '*' == {
  199. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_STAR mm0tok_init ret ;
  200. }
  201. if c '.' == {
  202. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_DOT mm0tok_init ret ;
  203. }
  204. if c ':' == {
  205. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_COLON mm0tok_init ret ;
  206. }
  207. if c ';' == {
  208. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_SEMICOLON mm0tok_init ret ;
  209. }
  210. if c '(' == {
  211. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_OPEN mm0tok_init ret ;
  212. }
  213. if c ')' == {
  214. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_CLOSED mm0tok_init ret ;
  215. }
  216. if c '>' == {
  217. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_ARROW mm0tok_init ret ;
  218. }
  219. if c '{' == {
  220. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_OPENBR mm0tok_init ret ;
  221. }
  222. if c '}' == {
  223. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_CLOSEDBR mm0tok_init ret ;
  224. }
  225. if c '=' == {
  226. MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_ASSIGN mm0tok_init ret ;
  227. }
  228. # Number token
  229. if c mm0_is_digit {
  230. $zero
  231. @zero c '0' == = ;
  232. $value
  233. @value c '0' - = ;
  234. @c lexer mm0lexer_read = ;
  235. while c mm0_is_digit {
  236. zero ! "mm0lexer_get_token_or_eof_: invalid 0 prefix in number token" assert_msg ;
  237. @value value 10 * c '0' - + = ;
  238. @c lexer mm0lexer_read = ;
  239. }
  240. c mm0_is_alpha ! "mm0lexer_get_token_or_eof_: unexpected alphabetic character in number token" assert_msg ;
  241. lexer c mm0lexer_unread ;
  242. MM0TOK_TYPE_NUMBER value mm0tok_init ret ;
  243. }
  244. # Identifier token
  245. if c mm0_is_alpha c '_' == || {
  246. $size
  247. $cap
  248. $value
  249. @size 0 = ;
  250. @cap 4 = ;
  251. @value cap malloc = ;
  252. while c mm0_is_digit c mm0_is_alpha || c '_' == || c '-' == || {
  253. # +1 to be sure there is space for the terminator
  254. if size 1 + cap >= {
  255. @cap cap 2 * = ;
  256. @value cap value realloc = ;
  257. }
  258. value size + c =c ;
  259. @size size 1 + = ;
  260. @c lexer mm0lexer_read = ;
  261. }
  262. lexer c mm0lexer_unread ;
  263. value size + '\0' =c ;
  264. MM0TOK_TYPE_IDENT value mm0tok_init ret ;
  265. }
  266. # Math token
  267. if c '$' == {
  268. $size
  269. $cap
  270. $value
  271. @size 0 = ;
  272. @cap 4 = ;
  273. @value cap malloc = ;
  274. @c lexer mm0lexer_read = ;
  275. $cont
  276. @cont 1 = ;
  277. while c '$' != {
  278. # +1 to be sure there is space for the terminator
  279. if size 1 + cap >= {
  280. @cap cap 2 * = ;
  281. @value cap value realloc = ;
  282. }
  283. if c mm0_is_white {
  284. @c ' ' = ;
  285. }
  286. value size + c =c ;
  287. @size size 1 + = ;
  288. @c lexer mm0lexer_read = ;
  289. }
  290. value size + '\0' =c ;
  291. MM0TOK_TYPE_MATH value mm0tok_init ret ;
  292. }
  293. 0 "mm0lexer_get_token_or_eof_: invalid character in input file" assert_msg ;
  294. }
  295. fun mm0lexer_get_token_or_eof 1 {
  296. $lexer
  297. @lexer 0 param = ;
  298. $token
  299. @token lexer mm0lexer_get_token_or_eof_ = ;
  300. if token {
  301. token mm0tok_dump ;
  302. " " log ;
  303. } else {
  304. "EOF" log ;
  305. }
  306. token ret ;
  307. }
  308. fun mm0lexer_get_token 1 {
  309. $lexer
  310. @lexer 0 param = ;
  311. $token
  312. @token lexer mm0lexer_get_token_or_eof = ;
  313. token "mm0lexer_get_token: unexpected end of file" assert_msg ;
  314. token ret ;
  315. }
  316. fun mm0lexer_get_token_type 2 {
  317. $lexer
  318. $type
  319. @lexer 1 param = ;
  320. @type 0 param = ;
  321. $tok
  322. @tok lexer mm0lexer_get_token = ;
  323. tok MM0TOK_TYPE take type == "mm0lexer_get_token_type: wrong token type" assert_msg ;
  324. tok ret ;
  325. }
  326. fun mm0lexer_expect 3 {
  327. $lexer
  328. $type
  329. $value
  330. @lexer 2 param = ;
  331. @type 1 param = ;
  332. @value 0 param = ;
  333. $tok
  334. @tok lexer mm0lexer_get_token = ;
  335. tok type value mm0tok_cmp_value "mm0lexer_expect: illegal token" assert_msg ;
  336. tok mm0tok_destroy ;
  337. }
  338. const MM0SORT_PURE 0
  339. const MM0SORT_STRICT 4
  340. const MM0SORT_PROVABLE 8
  341. const MM0SORT_NONEMPTY 12
  342. const SIZEOF_MM0SORT 16
  343. fun mm0sort_init 0 {
  344. $sort
  345. @sort SIZEOF_MM0SORT malloc = ;
  346. sort MM0SORT_PURE take_addr 0 = ;
  347. sort MM0SORT_STRICT take_addr 0 = ;
  348. sort MM0SORT_PROVABLE take_addr 0 = ;
  349. sort MM0SORT_NONEMPTY take_addr 0 = ;
  350. sort ret ;
  351. }
  352. fun mm0sort_destroy 1 {
  353. $sort
  354. @sort 0 param = ;
  355. sort free ;
  356. }
  357. const MM0TH_LEXER 0
  358. const MM0TH_LEVEL 4
  359. const MM0TH_SORTS 8
  360. const SIZEOF_MM0TH 12
  361. fun mm0th_init 0 {
  362. $theory
  363. @theory SIZEOF_MM0TH malloc = ;
  364. theory MM0TH_LEVEL take_addr 0 = ;
  365. theory MM0TH_SORTS take_addr map_init = ;
  366. theory ret ;
  367. }
  368. fun mm0th_sorts_destroy_closure 3 {
  369. $ctx
  370. $key
  371. $value
  372. @ctx 2 param = ;
  373. @key 1 param = ;
  374. @value 0 param = ;
  375. value mm0sort_destroy ;
  376. }
  377. fun mm0th_destroy 1 {
  378. $theory
  379. @theory 0 param = ;
  380. theory MM0TH_SORTS take @mm0th_sorts_destroy_closure 0 map_foreach ;
  381. theory MM0TH_SORTS take map_destroy ;
  382. theory free ;
  383. }
  384. fun mm0_parse_sort 2 {
  385. $theory
  386. $tok
  387. @theory 1 param = ;
  388. @tok 0 param = ;
  389. $lexer
  390. @lexer theory MM0TH_LEXER take = ;
  391. "(sort-stmt) " log ;
  392. $sort
  393. @sort mm0sort_init = ;
  394. # Read sort properties
  395. $cont
  396. @cont 1 = ;
  397. while cont {
  398. $ok
  399. @ok 0 = ;
  400. if tok MM0TOK_TYPE_IDENT "pure" mm0tok_cmp_value { @ok 1 = ; sort MM0SORT_PURE take_addr 1 = ; }
  401. if tok MM0TOK_TYPE_IDENT "strict" mm0tok_cmp_value { @ok 1 = ; sort MM0SORT_STRICT take_addr 1 = ; }
  402. if tok MM0TOK_TYPE_IDENT "provable" mm0tok_cmp_value { @ok 1 = ; sort MM0SORT_PROVABLE take_addr 1 = ; }
  403. if tok MM0TOK_TYPE_IDENT "nonempty" mm0tok_cmp_value { @ok 1 = ; sort MM0SORT_NONEMPTY take_addr 1 = ; }
  404. if tok MM0TOK_TYPE_IDENT "sort" mm0tok_cmp_value { @ok 1 = ; @cont 0 = ; }
  405. ok "mm0_parse_sort: parsing failed" assert_msg ;
  406. tok mm0tok_destroy ;
  407. @tok lexer MM0TOK_TYPE_IDENT mm0lexer_get_token_type = ;
  408. }
  409. # Register the sort
  410. $sorts
  411. @sorts theory MM0TH_SORTS take = ;
  412. $value
  413. @value tok MM0TOK_VALUE take = ;
  414. sorts value map_has ! "mm0_parse_sort: sort already exists" assert_msg ;
  415. sorts value sort map_set ;
  416. tok mm0tok_destroy ;
  417. # Expect semicolon
  418. lexer MM0TOK_TYPE_SYMBOL MM0TOK_SYMB_SEMICOLON mm0lexer_expect ;
  419. }
  420. fun mm0_parse_var 2 {
  421. $theory
  422. $tok
  423. @theory 1 param = ;
  424. @tok 0 param = ;
  425. $lexer
  426. @lexer theory MM0TH_LEXER take = ;
  427. "(var-stmt) " log ;
  428. # Discard tokens up to the semicolon
  429. $cont
  430. @cont 1 = ;
  431. tok mm0tok_destroy ;
  432. while cont {
  433. @tok lexer mm0lexer_get_token = ;
  434. if tok MM0TOK_TYPE take MM0TOK_TYPE_SYMBOL ==
  435. tok MM0TOK_VALUE take MM0TOK_SYMB_SEMICOLON == && {
  436. @cont 0 = ;
  437. }
  438. tok mm0tok_destroy ;
  439. }
  440. }
  441. fun mm0_parse_term 2 {
  442. $theory
  443. $tok
  444. @theory 1 param = ;
  445. @tok 0 param = ;
  446. $lexer
  447. @lexer theory MM0TH_LEXER take = ;
  448. "(term-stmt) " log ;
  449. # Discard tokens up to the semicolon
  450. $cont
  451. @cont 1 = ;
  452. tok mm0tok_destroy ;
  453. while cont {
  454. @tok lexer mm0lexer_get_token = ;
  455. if tok MM0TOK_TYPE take MM0TOK_TYPE_SYMBOL ==
  456. tok MM0TOK_VALUE take MM0TOK_SYMB_SEMICOLON == && {
  457. @cont 0 = ;
  458. }
  459. tok mm0tok_destroy ;
  460. }
  461. }
  462. fun mm0_parse_assert 2 {
  463. $theory
  464. $tok
  465. @theory 1 param = ;
  466. @tok 0 param = ;
  467. $lexer
  468. @lexer theory MM0TH_LEXER take = ;
  469. "(assert-stmt) " log ;
  470. # Discard tokens up to the semicolon
  471. $cont
  472. @cont 1 = ;
  473. tok mm0tok_destroy ;
  474. while cont {
  475. @tok lexer mm0lexer_get_token = ;
  476. if tok MM0TOK_TYPE take MM0TOK_TYPE_SYMBOL ==
  477. tok MM0TOK_VALUE take MM0TOK_SYMB_SEMICOLON == && {
  478. @cont 0 = ;
  479. }
  480. tok mm0tok_destroy ;
  481. }
  482. }
  483. fun mm0_parse_def 2 {
  484. $theory
  485. $tok
  486. @theory 1 param = ;
  487. @tok 0 param = ;
  488. $lexer
  489. @lexer theory MM0TH_LEXER take = ;
  490. "(def-stmt) " log ;
  491. # Discard tokens up to the open brace
  492. $cont
  493. @cont 1 = ;
  494. tok mm0tok_destroy ;
  495. while cont {
  496. @tok lexer mm0lexer_get_token = ;
  497. if tok MM0TOK_TYPE take MM0TOK_TYPE_SYMBOL ==
  498. tok MM0TOK_VALUE take MM0TOK_SYMB_OPENBR == && {
  499. theory MM0TH_LEVEL take_addr theory MM0TH_LEVEL take 1 + = ;
  500. @cont 0 = ;
  501. }
  502. tok mm0tok_destroy ;
  503. }
  504. }
  505. fun mm0_parse_notation 2 {
  506. $theory
  507. $tok
  508. @theory 1 param = ;
  509. @tok 0 param = ;
  510. $lexer
  511. @lexer theory MM0TH_LEXER take = ;
  512. "(notation-stmt) " log ;
  513. # Discard tokens up to the semicolon
  514. $cont
  515. @cont 1 = ;
  516. tok mm0tok_destroy ;
  517. while cont {
  518. @tok lexer mm0lexer_get_token = ;
  519. if tok MM0TOK_TYPE take MM0TOK_TYPE_SYMBOL ==
  520. tok MM0TOK_VALUE take MM0TOK_SYMB_SEMICOLON == && {
  521. @cont 0 = ;
  522. }
  523. tok mm0tok_destroy ;
  524. }
  525. }
  526. fun mm0_parse_output 2 {
  527. $theory
  528. $tok
  529. @theory 1 param = ;
  530. @tok 0 param = ;
  531. $lexer
  532. @lexer theory MM0TH_LEXER take = ;
  533. "(output-stmt) " log ;
  534. # Discard tokens up to the semicolon
  535. $cont
  536. @cont 1 = ;
  537. tok mm0tok_destroy ;
  538. while cont {
  539. @tok lexer mm0lexer_get_token = ;
  540. if tok MM0TOK_TYPE take MM0TOK_TYPE_SYMBOL ==
  541. tok MM0TOK_VALUE take MM0TOK_SYMB_SEMICOLON == && {
  542. @cont 0 = ;
  543. }
  544. tok mm0tok_destroy ;
  545. }
  546. }
  547. fun mm0_parse_statement 2 {
  548. $theory
  549. $tok
  550. @theory 1 param = ;
  551. @tok 0 param = ;
  552. $value
  553. @value tok MM0TOK_VALUE take = ;
  554. if value "pure" strcmp 0 ==
  555. value "strict" strcmp 0 == ||
  556. value "provable" strcmp 0 == ||
  557. value "nonempty" strcmp 0 == ||
  558. value "sort" strcmp 0 == || {
  559. theory tok mm0_parse_sort ;
  560. ret ;
  561. }
  562. if value "var" strcmp 0 == {
  563. theory tok mm0_parse_var ;
  564. ret ;
  565. }
  566. if value "term" strcmp 0 == {
  567. theory tok mm0_parse_term ;
  568. ret ;
  569. }
  570. if value "axiom" strcmp 0 ==
  571. value "theorem" strcmp 0 == || {
  572. theory tok mm0_parse_assert ;
  573. ret ;
  574. }
  575. if value "def" strcmp 0 == {
  576. theory tok mm0_parse_def ;
  577. ret ;
  578. }
  579. if value "infixl" strcmp 0 ==
  580. value "infixr" strcmp 0 == ||
  581. value "prefix" strcmp 0 == ||
  582. value "coercion" strcmp 0 == ||
  583. value "notation" strcmp 0 == || {
  584. theory tok mm0_parse_notation ;
  585. ret ;
  586. }
  587. if value "output" strcmp 0 == {
  588. theory tok mm0_parse_output ;
  589. ret ;
  590. }
  591. 0 "mm0_parse_statement: invalid statement" assert_msg ;
  592. }
  593. fun mm0_parse 1 {
  594. $lexer
  595. @lexer 0 param = ;
  596. $theory
  597. @theory mm0th_init = ;
  598. theory MM0TH_LEXER take_addr lexer = ;
  599. while 1 {
  600. $tok
  601. @tok lexer mm0lexer_get_token_or_eof = ;
  602. if tok ! {
  603. theory MM0TH_LEVEL take 0 == "mm0_parse: unmatched braces" assert_msg ;
  604. theory ret ;
  605. }
  606. $type
  607. $value
  608. @type tok MM0TOK_TYPE take = ;
  609. @value tok MM0TOK_VALUE take = ;
  610. if type MM0TOK_TYPE_SYMBOL == {
  611. if value MM0TOK_SYMB_OPENBR == {
  612. theory MM0TH_LEVEL take_addr theory MM0TH_LEVEL take 1 + = ;
  613. } else {
  614. value MM0TOK_SYMB_CLOSEDBR == "mm0_parse: invalid symbol" assert_msg ;
  615. theory MM0TH_LEVEL take 0 > "mm0_parse: invalid block closing" assert_msg ;
  616. theory MM0TH_LEVEL take_addr theory MM0TH_LEVEL take 1 - = ;
  617. }
  618. tok mm0tok_destroy ;
  619. } else {
  620. type MM0TOK_TYPE_IDENT == "mm0_parse: invalid token type" assert_msg ;
  621. theory tok mm0_parse_statement ;
  622. }
  623. }
  624. }
  625. fun mm0_process 1 {
  626. $filename
  627. @filename 0 param = ;
  628. $lexer
  629. @lexer filename mm0lexer_init = ;
  630. lexer "mm0_process: cannot open file" assert_msg ;
  631. $theory
  632. "Parsing MM0 theory: " log ;
  633. @theory lexer mm0_parse = ;
  634. "\n" log ;
  635. # TODO: verify theory
  636. # Free resources
  637. theory mm0th_destroy ;
  638. lexer mm0lexer_destroy ;
  639. }