asm_preproc.g 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. # This file is part of asmc, a bootstrapping OS with minimal seed
  2. # Copyright (C) 2018 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. const ASMCTX_FDIN 0
  15. const ASMCTX_READ_CHAR 4
  16. const ASMCTX_CHAR_GIVEN_BACK 8
  17. const ASMCTX_SYMBOLS 12
  18. const ASMCTX_STAGE 16
  19. const ASMCTX_CURRENT_LOC 20
  20. const ASMCTX_READ_TOKEN 24
  21. const ASMCTX_TOKEN_GIVEN_BACK 28
  22. const ASMCTX_VERBOSE 32
  23. const ASMCTX_DEBUG 36
  24. const SIZEOF_ASMCTX 40
  25. fun asmctx_init 0 {
  26. $ptr
  27. @ptr SIZEOF_ASMCTX malloc = ;
  28. ptr ASMCTX_SYMBOLS take_addr map_init = ;
  29. ptr ASMCTX_VERBOSE take_addr 1 = ;
  30. ptr ASMCTX_DEBUG take_addr 1 = ;
  31. ptr ret ;
  32. }
  33. fun asmctx_destroy 1 {
  34. $ptr
  35. @ptr 0 param = ;
  36. ptr ASMCTX_SYMBOLS take map_destroy ;
  37. ptr free ;
  38. }
  39. fun asmctx_emit 2 {
  40. $ctx
  41. $byte
  42. @ctx 1 param = ;
  43. @byte 0 param = ;
  44. if ctx ASMCTX_STAGE take 2 == {
  45. ctx ASMCTX_CURRENT_LOC take byte =c ;
  46. }
  47. ctx ASMCTX_CURRENT_LOC take_addr ctx ASMCTX_CURRENT_LOC take 1 + = ;
  48. }
  49. fun asmctx_emit16 2 {
  50. $ctx
  51. $word
  52. @ctx 1 param = ;
  53. @word 0 param = ;
  54. ctx word asmctx_emit ;
  55. ctx word 8 >> asmctx_emit ;
  56. }
  57. fun asmctx_emit32 2 {
  58. $ctx
  59. $dword
  60. @ctx 1 param = ;
  61. @dword 0 param = ;
  62. ctx dword asmctx_emit16 ;
  63. ctx dword 16 >> asmctx_emit16 ;
  64. }
  65. fun emit_size 3 {
  66. $ctx
  67. $data
  68. $size
  69. @ctx 2 param = ;
  70. @data 1 param = ;
  71. @size 0 param = ;
  72. if size 1 == {
  73. ctx data asmctx_emit ;
  74. } else {
  75. if size 2 == {
  76. ctx data asmctx_emit16 ;
  77. } else {
  78. if size 3 == {
  79. ctx data asmctx_emit32 ;
  80. } else {
  81. if size 4 == {
  82. ctx data asmctx_emit32 ;
  83. ctx 0 asmctx_emit32 ;
  84. } else {
  85. 0 "emit_size: invalid size" assert_msg ;
  86. }
  87. }
  88. }
  89. }
  90. }
  91. fun emit_multibyte 2 {
  92. $ctx
  93. $data
  94. @ctx 1 param = ;
  95. @data 0 param = ;
  96. if data 0xff & 1 == {
  97. ctx data 8 >> asmctx_emit ;
  98. ret ;
  99. }
  100. if data 0xff & 2 == {
  101. ctx data 8 >> asmctx_emit16 ;
  102. ret ;
  103. }
  104. if data 0xff & 3 == {
  105. ctx data 8 >> asmctx_emit ;
  106. ctx data 16 >> asmctx_emit16 ;
  107. ret ;
  108. }
  109. 0 "emit_multibyte: error 1" assert_msg ;
  110. }
  111. fun emit_string 2 {
  112. $ctx
  113. $str
  114. @ctx 1 param = ;
  115. @str 0 param = ;
  116. str **c '\'' == "emit_string: argument is not a string" assert_msg ;
  117. @str str 1 + = ;
  118. while str **c '\'' != {
  119. ctx str **c asmctx_emit ;
  120. @str str 1 + = ;
  121. }
  122. }
  123. fun asmctx_add_symbol 3 {
  124. $ctx
  125. $name
  126. $value
  127. @ctx 2 param = ;
  128. @name 1 param = ;
  129. @value 0 param = ;
  130. $syms
  131. @syms ctx ASMCTX_SYMBOLS take = ;
  132. if ctx ASMCTX_STAGE take 1 == {
  133. syms name map_has ! "asmctx_add_symbol: symbol already defined" assert_msg ;
  134. syms name value map_set ;
  135. }
  136. if ctx ASMCTX_STAGE take 2 == {
  137. syms name map_has "asmctx_add_symbol: error 1" assert_msg ;
  138. syms name map_at value == "asmctx_add_symbol: error 2" assert_msg ;
  139. }
  140. }
  141. fun asmctx_get_symbol 2 {
  142. $ctx
  143. $name
  144. @ctx 1 param = ;
  145. @name 0 param = ;
  146. $syms
  147. @syms ctx ASMCTX_SYMBOLS take = ;
  148. if ctx ASMCTX_STAGE take 2 == {
  149. if syms name map_has {
  150. syms name map_at ret ;
  151. } else {
  152. "Undefined symbol: " log ;
  153. name log ;
  154. "\n" log ;
  155. 0 "asmctx_get_symbol: symbol undefined" assert_msg ;
  156. }
  157. } else {
  158. 0 ret ;
  159. }
  160. }
  161. fun asmctx_get_symbol_addr 2 {
  162. $ctx
  163. $name
  164. @ctx 1 param = ;
  165. @name 0 param = ;
  166. $syms
  167. @syms ctx ASMCTX_SYMBOLS take = ;
  168. syms name map_has "asmctx_get_symbol_addr: symbol does not exist" assert_msg ;
  169. syms name map_at ret ;
  170. }
  171. fun asmctx_set_fd 2 {
  172. $ptr
  173. $fd
  174. @ptr 1 param = ;
  175. @fd 0 param = ;
  176. ptr ASMCTX_CHAR_GIVEN_BACK take_addr 0 = ;
  177. ptr ASMCTX_TOKEN_GIVEN_BACK take_addr 0 = ;
  178. ptr ASMCTX_FDIN take_addr fd = ;
  179. }
  180. # fun asmctx_set_starting_loc 2 {
  181. # $ptr
  182. # $loc
  183. # @ptr 1 param = ;
  184. # @loc 0 param = ;
  185. # ptr ASMCTX_CURRENT_LOC take_addr loc = ;
  186. # }
  187. fun asmctx_give_back_char 1 {
  188. $ctx
  189. @ctx 0 param = ;
  190. ctx ASMCTX_CHAR_GIVEN_BACK take ! "Character already given back" assert_msg ;
  191. ctx ASMCTX_CHAR_GIVEN_BACK take_addr 1 = ;
  192. }
  193. fun asmctx_get_char 1 {
  194. $ctx
  195. @ctx 0 param = ;
  196. if ctx ASMCTX_CHAR_GIVEN_BACK take {
  197. ctx ASMCTX_CHAR_GIVEN_BACK take_addr 0 = ;
  198. } else {
  199. ctx ASMCTX_READ_CHAR take_addr ctx ASMCTX_FDIN take vfs_read = ;
  200. }
  201. ctx ASMCTX_READ_CHAR take ret ;
  202. }
  203. fun asmctx_give_back_token 1 {
  204. $ctx
  205. @ctx 0 param = ;
  206. ctx ASMCTX_TOKEN_GIVEN_BACK take ! "Token already given back" assert_msg ;
  207. ctx ASMCTX_TOKEN_GIVEN_BACK take_addr 1 = ;
  208. }
  209. fun asmctx_get_token 1 {
  210. $ctx
  211. @ctx 0 param = ;
  212. if ctx ASMCTX_TOKEN_GIVEN_BACK take {
  213. ctx ASMCTX_TOKEN_GIVEN_BACK take_addr 0 = ;
  214. ctx ASMCTX_READ_TOKEN take ret ;
  215. }
  216. $token_buf
  217. $token_buf_len
  218. @token_buf_len 32 = ;
  219. @token_buf token_buf_len malloc = ;
  220. $state
  221. @state 0 = ;
  222. $token_type
  223. $token_len
  224. @token_len 0 = ;
  225. $cont
  226. @cont 1 = ;
  227. while cont {
  228. $c
  229. @c ctx asmctx_get_char = ;
  230. @cont c 0xffffffff != = ;
  231. if cont {
  232. $save_char
  233. @save_char 0 = ;
  234. $type
  235. @type c get_char_type = ;
  236. $enter_state
  237. @enter_state state = ;
  238. # Normal code
  239. if enter_state 0 == {
  240. @save_char 1 = ;
  241. }
  242. # Comment
  243. if enter_state 1 == {
  244. if c '\n' == {
  245. token_buf '\n' =c ;
  246. @token_len 1 = ;
  247. @state 0 = ;
  248. @cont 0 = ;
  249. }
  250. }
  251. # String
  252. if enter_state 2 == {
  253. @save_char 1 = ;
  254. #if c '\\' == {
  255. # @state 3 = ;
  256. #}
  257. if c '\'' == {
  258. @state 0 = ;
  259. @cont 0 = ;
  260. }
  261. }
  262. # String after backslash
  263. if enter_state 3 == {
  264. @save_char 1 = ;
  265. @state 2 = ;
  266. }
  267. token_buf token_len + c =c ;
  268. if save_char {
  269. if token_len 0 == {
  270. if type 2 != {
  271. @token_len token_len 1 + = ;
  272. @token_type type = ;
  273. if c '\'' == {
  274. @state 2 = ;
  275. @token_type 0 = ;
  276. }
  277. if c ';' == {
  278. @state 1 = ;
  279. @token_type 0 = ;
  280. }
  281. if token_type 1 == {
  282. @cont 0 = ;
  283. }
  284. if token_type 4 == {
  285. @cont 0 = ;
  286. }
  287. }
  288. } else {
  289. if token_type type == token_type 0 == || {
  290. @token_len token_len 1 + = ;
  291. } else {
  292. ctx asmctx_give_back_char ;
  293. @cont 0 = ;
  294. }
  295. }
  296. }
  297. if token_len 1 + token_buf_len >= {
  298. @token_buf_len token_buf_len 2 * = ;
  299. @token_buf token_buf_len token_buf realloc = ;
  300. }
  301. }
  302. }
  303. if token_type 2 == {
  304. token_buf ' ' =c ;
  305. @token_len 1 = ;
  306. }
  307. token_buf token_len + 0 =c ;
  308. ctx ASMCTX_READ_TOKEN take_addr token_buf = ;
  309. token_buf ret ;
  310. }