builtins.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include "tags.h"
  6. #include "builtins.h"
  7. #include "bytecode.h"
  8. #include "symboltable.h"
  9. #include "gc.h"
  10. void scm_display(scm x) {
  11. switch(scm_get_tag(x)) {
  12. case atom_tag_fals:
  13. printf("%s", "#f");
  14. break;
  15. case atom_tag_true:
  16. printf("%s", "#t");
  17. break;
  18. case atom_tag_null:
  19. printf("%s", "()");
  20. break;
  21. case atom_tag_symb:
  22. printf("%s", lookup(get_symb(x)));
  23. break;
  24. case atom_tag_char:
  25. printf("%c", get_char(x));
  26. break;
  27. case tag_numb:
  28. printf("%ld", get_numb(x));
  29. break;
  30. case tag_cons:
  31. printf("<PAIR>");
  32. break;
  33. case tag_clos:
  34. printf("<CLOS>");
  35. break;
  36. case tag_vect:
  37. printf("<VECT>");
  38. break;
  39. case tag_strn:
  40. printf("%s", (char*)get_strn_data(x));
  41. break;
  42. default:
  43. printf("<UNKNOWN>");
  44. }
  45. }
  46. scm builtin_display() {
  47. assert(bytecode_args_num == 1);
  48. scm_display(bytecode_args[0]);
  49. return 0;
  50. }
  51. scm builtin_newline() {
  52. puts("");
  53. return 0;
  54. }
  55. //
  56. scm builtin_cons() {
  57. assert(bytecode_args_num == 2);
  58. return heap_alloc_cons(bytecode_args[0], bytecode_args[1]);
  59. }
  60. scm builtin_car() {
  61. assert(bytecode_args_num == 1);
  62. return get_cons_car(bytecode_args[0]);
  63. }
  64. scm builtin_cdr() {
  65. assert(bytecode_args_num == 1);
  66. return get_cons_cdr(bytecode_args[0]);
  67. }
  68. scm builtin_set_car() {
  69. assert(bytecode_args_num == 2);
  70. set_cons_car(bytecode_args[0], bytecode_args[1]);
  71. return 0;
  72. }
  73. scm builtin_set_cdr() {
  74. assert(bytecode_args_num == 2);
  75. set_cons_cdr(bytecode_args[0], bytecode_args[1]);
  76. return 0;
  77. }
  78. //
  79. scm builtin_nullq() {
  80. assert(bytecode_args_num == 1);
  81. return mk_bool(scm_get_tag(bytecode_args[0])
  82. == atom_tag_null);
  83. }
  84. scm builtin_pairq() {
  85. assert(bytecode_args_num == 1);
  86. return mk_bool(scm_get_tag(bytecode_args[0])
  87. == tag_cons);
  88. }
  89. scm builtin_numberq() {
  90. assert(bytecode_args_num == 1);
  91. return mk_bool(scm_get_tag(bytecode_args[0])
  92. == tag_numb);
  93. }
  94. scm builtin_booleanq() {
  95. assert(bytecode_args_num == 1);
  96. return mk_bool((scm_get_tag(bytecode_args[0])
  97. == atom_tag_fals) ||
  98. (scm_get_tag(bytecode_args[0])
  99. == atom_tag_true));
  100. }
  101. scm builtin_stringq() {
  102. assert(bytecode_args_num == 1);
  103. return mk_bool(scm_get_tag(bytecode_args[0])
  104. == tag_strn);
  105. }
  106. scm builtin_charq() {
  107. assert(bytecode_args_num == 1);
  108. return mk_bool(scm_get_tag(bytecode_args[0])
  109. == atom_tag_char);
  110. }
  111. scm builtin_symbolq() {
  112. assert(bytecode_args_num == 1);
  113. return mk_bool(scm_get_tag(bytecode_args[0])
  114. == atom_tag_symb);
  115. }
  116. scm builtin_vectorq() {
  117. assert(bytecode_args_num == 1);
  118. return mk_bool(scm_get_tag(bytecode_args[0])
  119. == tag_vect);
  120. }
  121. //
  122. scm builtin_add() {
  123. assert(bytecode_args_num == 2);
  124. return mk_numb(get_numb(bytecode_args[0])
  125. + get_numb(bytecode_args[1]));
  126. }
  127. scm builtin_subtract() {
  128. assert(bytecode_args_num == 2);
  129. return mk_numb(get_numb(bytecode_args[0])
  130. - get_numb(bytecode_args[1]));
  131. }
  132. scm builtin_multiply() {
  133. assert(bytecode_args_num == 2);
  134. return mk_numb(get_numb(bytecode_args[0])
  135. * get_numb(bytecode_args[1]));
  136. }
  137. scm builtin_quotient() {
  138. assert(bytecode_args_num == 2);
  139. return mk_numb(get_numb(bytecode_args[0])
  140. / get_numb(bytecode_args[1]));
  141. }
  142. scm builtin_modulo() {
  143. assert(bytecode_args_num == 2);
  144. return mk_numb(get_numb(bytecode_args[0])
  145. % get_numb(bytecode_args[1]));
  146. }
  147. scm builtin_eq() {
  148. assert(bytecode_args_num == 2);
  149. return mk_bool(bytecode_args[0]
  150. == bytecode_args[1]);
  151. }
  152. scm builtin_lt() {
  153. assert(bytecode_args_num == 2);
  154. return mk_bool(get_numb(bytecode_args[0])
  155. < get_numb(bytecode_args[1]));
  156. }
  157. scm builtin_gt() {
  158. assert(bytecode_args_num == 2);
  159. return mk_bool(get_numb(bytecode_args[0])
  160. > get_numb(bytecode_args[1]));
  161. }
  162. scm builtin_le() {
  163. assert(bytecode_args_num == 2);
  164. return mk_bool(get_numb(bytecode_args[0])
  165. <= get_numb(bytecode_args[1]));
  166. }
  167. scm builtin_ge() {
  168. assert(bytecode_args_num == 2);
  169. return mk_bool(get_numb(bytecode_args[0])
  170. >= get_numb(bytecode_args[1]));
  171. }
  172. scm builtin_vector_ref() {
  173. assert(bytecode_args_num == 2);
  174. assert(scm_get_tag(bytecode_args[0]) == tag_vect);
  175. assert(scm_get_tag(bytecode_args[1]) == tag_numb);
  176. scm *p;
  177. p = get_vect(bytecode_args[0]);
  178. assert(get_numb(bytecode_args[1]) < header_scm_size(p[0]));
  179. return p[1 + get_numb(bytecode_args[1])];
  180. }
  181. scm builtin_vector_set_bang() {
  182. assert(bytecode_args_num == 3);
  183. assert(scm_get_tag(bytecode_args[0]) == tag_vect);
  184. assert(scm_get_tag(bytecode_args[1]) == tag_numb);
  185. scm *p;
  186. p = get_vect(bytecode_args[0]);
  187. assert(get_numb(bytecode_args[1]) < header_scm_size(p[0]));
  188. p[1 + get_numb(bytecode_args[1])] = bytecode_args[2];
  189. return 0;
  190. }
  191. scm builtin_make_vector() {
  192. assert(bytecode_args_num == 2);
  193. assert(scm_get_tag(bytecode_args[0]) == tag_numb);
  194. return heap_alloc_vect(get_numb(bytecode_args[0]), bytecode_args[1]);
  195. }
  196. scm builtin_vector_length() {
  197. assert(bytecode_args_num == 1);
  198. assert(scm_get_tag(bytecode_args[0]) == tag_vect);
  199. scm *p;
  200. p = get_vect(bytecode_args[0]);
  201. return mk_numb(header_scm_size(p[0]));
  202. }
  203. //
  204. scm builtin_make_string() {
  205. char string_tmp_buf[512] = { 0 };
  206. int len;
  207. assert(bytecode_args_num == 2);
  208. assert(scm_get_tag(bytecode_args[0]) == tag_numb);
  209. assert(scm_get_tag(bytecode_args[1]) == atom_tag_char);
  210. int i;
  211. char c;
  212. len = get_numb(bytecode_args[0]);
  213. c = get_char(bytecode_args[1]);
  214. for(i = 0; i < len; i++) {
  215. string_tmp_buf[i] = c;
  216. }
  217. string_tmp_buf[i] = '\0';
  218. return heap_alloc_strn(string_tmp_buf, len);
  219. }
  220. scm builtin_string_set_bang() {
  221. assert(bytecode_args_num == 3);
  222. assert(scm_get_tag(bytecode_args[0]) == tag_strn);
  223. assert(scm_get_tag(bytecode_args[1]) == tag_numb);
  224. assert(scm_get_tag(bytecode_args[2]) == atom_tag_char);
  225. int i = get_numb(bytecode_args[1]);
  226. assert(i < get_strn_len(bytecode_args[0]));
  227. get_strn_data(bytecode_args[0])[i] = get_char(bytecode_args[2]);
  228. return 0;
  229. }
  230. scm builtin_string_ref() {
  231. assert(bytecode_args_num == 2);
  232. assert(scm_get_tag(bytecode_args[0]) == tag_strn);
  233. assert(scm_get_tag(bytecode_args[1]) == tag_numb);
  234. int i = get_numb(bytecode_args[1]);
  235. assert(i < get_strn_len(bytecode_args[0]));
  236. return mk_char(get_strn_data(bytecode_args[0])[i]);
  237. }
  238. scm builtin_string_to_symbol() {
  239. assert(bytecode_args_num == 1);
  240. assert(scm_get_tag(bytecode_args[0]) == tag_strn);
  241. return intern((char*)get_strn_data(bytecode_args[0]));
  242. }
  243. scm builtin_string_length() {
  244. assert(bytecode_args_num == 1);
  245. assert(scm_get_tag(bytecode_args[0]) == tag_strn);
  246. return mk_numb(get_strn_len(bytecode_args[0]));
  247. }
  248. scm builtin_string_eql() {
  249. assert(bytecode_args_num == 2);
  250. assert(scm_get_tag(bytecode_args[0]) == tag_strn);
  251. assert(scm_get_tag(bytecode_args[1]) == tag_strn);
  252. if(get_strn_len(bytecode_args[0]) != get_strn_len(bytecode_args[1]))
  253. return mk_fals();
  254. if(strcmp((char*)get_strn_data(bytecode_args[0]), (char*)get_strn_data(bytecode_args[1])))
  255. return mk_fals();
  256. return mk_true();
  257. }
  258. //
  259. scm builtin_eof_objectq() {
  260. assert(bytecode_args_num == 1);
  261. return mk_bool(get_char(bytecode_args[0])
  262. == -1);
  263. }
  264. scm builtin_read_char() {
  265. assert(bytecode_args_num == 0);
  266. return mk_char(fgetc(stdin));
  267. }
  268. int fpeek(FILE *stream)
  269. {
  270. int c;
  271. c = fgetc(stream);
  272. ungetc(c, stream);
  273. return c;
  274. }
  275. scm builtin_peek_char() {
  276. assert(bytecode_args_num == 0);
  277. return mk_char(fpeek(stdin));
  278. }
  279. //
  280. scm builtin_gensym() {
  281. char string_tmp_buf[512] = { 0 };
  282. char *s;
  283. assert(bytecode_args_num == 1);
  284. switch(scm_get_tag(bytecode_args[0])) {
  285. case tag_strn:
  286. s = (char*)get_strn_data(bytecode_args[0]);
  287. break;
  288. case atom_tag_symb:
  289. s = lookup(get_symb(bytecode_args[0]));
  290. break;
  291. default:
  292. fprintf(stderr, "gensym was passed the wrong type of object\n");
  293. exit(-1);
  294. }
  295. snprintf(string_tmp_buf, sizeof(string_tmp_buf), "%s%08x", s, rand()%0xFFFFFFFF);
  296. return intern(string_tmp_buf);
  297. }
  298. //
  299. scm builtin_symbol_to_string() {
  300. assert(bytecode_args_num == 1);
  301. assert(scm_get_tag(bytecode_args[0]) == atom_tag_symb);
  302. char *p = lookup(get_symb(bytecode_args[0]));
  303. return heap_alloc_strn(p, strlen(p));
  304. }
  305. scm builtin_char_to_integer() {
  306. assert(bytecode_args_num == 1);
  307. assert(scm_get_tag(bytecode_args[0]) == atom_tag_char);
  308. return mk_numb(get_char(bytecode_args[0]));
  309. }
  310. //
  311. builtin_handler handler[bltn_max] = {
  312. [bltn_gensym] = builtin_gensym,
  313. [bltn_display] = builtin_display,
  314. [bltn_newline] = builtin_newline,
  315. [bltn_eq] = builtin_eq,
  316. [bltn_cons] = builtin_cons,
  317. [bltn_car] = builtin_car,
  318. [bltn_cdr] = builtin_cdr,
  319. [bltn_set_car] = builtin_set_car,
  320. [bltn_set_cdr] = builtin_set_cdr,
  321. [bltn_nullq] = builtin_nullq,
  322. [bltn_pairq] = builtin_pairq,
  323. [bltn_numberq] = builtin_numberq,
  324. [bltn_booleanq] = builtin_booleanq,
  325. [bltn_stringq] = builtin_stringq,
  326. [bltn_charq] = builtin_charq,
  327. [bltn_symbolq] = builtin_symbolq,
  328. [bltn_vectorq] = builtin_vectorq,
  329. [bltn_add] = builtin_add,
  330. [bltn_subtract] = builtin_subtract,
  331. [bltn_multiply] = builtin_multiply,
  332. [bltn_eql] = builtin_eq,
  333. [bltn_lt] = builtin_lt,
  334. [bltn_gt] = builtin_gt,
  335. [bltn_le] = builtin_le,
  336. [bltn_ge] = builtin_ge,
  337. [bltn_quotient] = builtin_quotient,
  338. [bltn_modulo] = builtin_modulo,
  339. [bltn_vector_ref] = builtin_vector_ref,
  340. [bltn_vector_set_bang] = builtin_vector_set_bang,
  341. [bltn_make_vector] = builtin_make_vector,
  342. [bltn_vector_length] = builtin_vector_length,
  343. [bltn_make_string] = builtin_make_string,
  344. [bltn_string_set_bang] = builtin_string_set_bang,
  345. [bltn_string_ref] = builtin_string_ref,
  346. [bltn_string_to_symbol] = builtin_string_to_symbol,
  347. [bltn_string_length] = builtin_string_length,
  348. [bltn_string_eql] = builtin_string_eql,
  349. [bltn_eof_objectq] = builtin_eof_objectq,
  350. [bltn_read_char] = builtin_read_char,
  351. [bltn_peek_char] = builtin_peek_char,
  352. [bltn_symbol_to_string] = builtin_symbol_to_string,
  353. [bltn_char_to_integer] = builtin_char_to_integer,
  354. //[bltn_] = builtin_,
  355. };