writer.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "minilisp.h"
  2. #include "stream.h"
  3. #include <stdio.h>
  4. #define TMP_BUF_SIZE 512
  5. #define INTFORMAT "%ld"
  6. char* tag_to_str(int tag) {
  7. switch (tag) {
  8. case TAG_FREED: return "freed";
  9. case TAG_INT: return "int";
  10. case TAG_CONS: return "cons";
  11. case TAG_SYM: return "symbol";
  12. case TAG_LAMBDA: return "lambda";
  13. case TAG_BUILTIN: return "builtin";
  14. case TAG_BIGNUM: return "bignum";
  15. case TAG_STR: return "string";
  16. case TAG_BYTES: return "bytes";
  17. case TAG_VEC: return "vector";
  18. case TAG_ERROR: return "error";
  19. case TAG_ANY: return "any";
  20. case TAG_VOID: return "void";
  21. case TAG_STREAM: return "stream";
  22. case TAG_STRUCT: return "struct";
  23. //case TAG_FS: return "filesystem";
  24. //case TAG_MARK: return "gc_mark";
  25. default: return "unknown";
  26. }
  27. }
  28. char* write_(Cell* cell, char* buffer, int in_list, int bufsize) {
  29. //printf("writing %p (%d) to %p, size: %d\n",cell,cell->tag,buffer,bufsize);
  30. bufsize--;
  31. buffer[0]=0;
  32. if (cell == NULL) {
  33. snprintf(buffer, bufsize, "null");
  34. } else if (cell->tag == TAG_INT) {
  35. snprintf(buffer, bufsize, INTFORMAT, cell->ar.value);
  36. } else if (cell->tag == TAG_CONS) {
  37. if (cell->ar.addr == 0 && cell->dr.next == 0) {
  38. if (!in_list) {
  39. snprintf(buffer, bufsize, "nil");
  40. }
  41. } else {
  42. char* tmpl=malloc(TMP_BUF_SIZE);
  43. char* tmpr=malloc(TMP_BUF_SIZE);
  44. write_((Cell*)cell->ar.addr, tmpl, 0, TMP_BUF_SIZE);
  45. if (cell->dr.next && ((Cell*)cell->dr.next)->tag==TAG_CONS) {
  46. write_((Cell*)cell->dr.next, tmpr, 1, TMP_BUF_SIZE);
  47. if (in_list) {
  48. if (tmpr[0]) {
  49. snprintf(buffer, bufsize, "%s %s", tmpl, tmpr);
  50. } else {
  51. snprintf(buffer, bufsize, "%s", tmpl); // skip nil at end of list
  52. }
  53. } else {
  54. // we're head of a list
  55. snprintf(buffer, bufsize, "(%s %s)", tmpl, tmpr);
  56. }
  57. } else {
  58. write_((Cell*)cell->dr.next, tmpr, 0, TMP_BUF_SIZE);
  59. // improper list
  60. snprintf(buffer, bufsize, "(%s . %s)", tmpl, tmpr);
  61. }
  62. free(tmpl);
  63. free(tmpr);
  64. }
  65. } else if (cell->tag == TAG_SYM) {
  66. snprintf(buffer, bufsize, "%s", (char*)cell->ar.addr);
  67. } else if (cell->tag == TAG_STR) {
  68. snprintf(buffer, min(bufsize-1,cell->dr.size+3), "\"%s\"", (char*)cell->ar.addr);
  69. } else if (cell->tag == TAG_BIGNUM) {
  70. snprintf(buffer, bufsize, "%s", (char*)cell->ar.addr);
  71. } else if (cell->tag == TAG_LAMBDA) {
  72. char tmp_args[TMP_BUF_SIZE];
  73. char tmp_body[TMP_BUF_SIZE*2];
  74. Cell* args = car(cell->ar.addr);
  75. int ai = 0;
  76. tmp_args[0]=0;
  77. tmp_body[0]=0;
  78. /*char debug[256];
  79. write_(args,debug,0,256);
  80. printf("debug %s\n",debug);*/
  81. while (args && car(car(args))) {
  82. if (car(car(args))->tag == TAG_CONS) {
  83. Cell* arg_cell = car(car(args));
  84. // typed arg
  85. ai += snprintf(tmp_args+ai, TMP_BUF_SIZE-ai, ai ? " (%s %s)" : "(%s %s)", (char*)(car(arg_cell)->ar.addr), (char*)(car(cdr(arg_cell))->ar.addr));
  86. } else {
  87. // untyped arg
  88. ai += snprintf(tmp_args+ai, TMP_BUF_SIZE-ai, ai ? " %s" : "%s" , (char*)(car(car(args)))->ar.addr);
  89. }
  90. args = cdr(args);
  91. }
  92. write_(cdr(cell->ar.addr), tmp_body, 0, TMP_BUF_SIZE);
  93. snprintf(buffer, bufsize, "(fn %s %s)", tmp_args, tmp_body);
  94. } else if (cell->tag == TAG_BUILTIN) {
  95. snprintf(buffer, bufsize, "(op "INTFORMAT")", cell->ar.value);
  96. } else if (cell->tag == TAG_ERROR) {
  97. switch (cell->ar.value) {
  98. case ERR_SYNTAX: snprintf(buffer, bufsize, "<e0:syntax error.>"); break;
  99. case ERR_MAX_EVAL_DEPTH: snprintf(buffer, bufsize, "<e1:deepest level of evaluation reached.>"); break;
  100. case ERR_UNKNOWN_OP: snprintf(buffer, bufsize, "<e2:unknown operation.>"); break;
  101. case ERR_APPLY_NIL: snprintf(buffer, bufsize, "<e3:cannot apply nil.>"); break;
  102. case ERR_INVALID_PARAM_TYPE: snprintf(buffer, bufsize, "<e4:invalid or no parameter given.>"); break;
  103. case ERR_OUT_OF_BOUNDS: snprintf(buffer, bufsize, "<e5:out of bounds.>"); break;
  104. default: snprintf(buffer, bufsize, "<e"INTFORMAT":unknown>", cell->ar.value); break;
  105. }
  106. } else if (cell->tag == TAG_BYTES) {
  107. int strsize = min(cell->dr.size*2+3, bufsize);
  108. int max_bytes = (strsize-3)/2;
  109. if (bufsize>5) {
  110. unsigned int i;
  111. buffer[0]='[';
  112. for (i=0; i<max_bytes; i++) {
  113. sprintf(buffer+1+i*2, "%02x", ((uint8_t*)cell->ar.addr)[i]);
  114. }
  115. buffer[i*2+1]=']';
  116. buffer[i*2+2]=0;
  117. }
  118. } else if (cell->tag == TAG_VEC || cell->tag == TAG_STRUCT || cell->tag == TAG_STRUCT_DEF) {
  119. Cell** vec = cell->ar.addr;
  120. int elements = cell->dr.size;
  121. int pos = 1;
  122. if (bufsize>12) {
  123. int i=0;
  124. buffer[0]='(';
  125. pos = 1;
  126. if (cell->tag == TAG_VEC) {
  127. sprintf(&buffer[1],"vec ");
  128. pos = 5;
  129. }
  130. else if (cell->tag == TAG_STRUCT && vec && vec[0]) {
  131. Cell** struct_def = (Cell**)(vec[0]->ar.addr);
  132. pos = 1+sprintf(&buffer[1],"%s ",(char*)struct_def[0]->ar.addr);
  133. i=1;
  134. }
  135. else if (cell->tag == TAG_STRUCT_DEF) {
  136. sprintf(&buffer[1],"struct ");
  137. pos = 8;
  138. }
  139. for (; i<elements && pos<bufsize-1; i++) {
  140. //printf("i: %d pos: %d vec[i]: %p\n",i,pos,vec[i]);
  141. write_(vec[i], buffer+pos, 0, bufsize-pos);
  142. //printf("-> %s\n",buffer);
  143. pos += strlen(buffer+pos);
  144. buffer[pos]=' ';
  145. pos++;
  146. }
  147. buffer[pos]=')';
  148. buffer[pos+1]=0;
  149. }
  150. } else if (cell->tag == TAG_STREAM) {
  151. Stream* s = (Stream*)cell->ar.addr;
  152. if (s) {
  153. snprintf(buffer, bufsize, "<stream:%d:%s:%s>", s->id, (char*)s->path->ar.addr, (char*)s->fs->mount_point->ar.addr);
  154. } else {
  155. snprintf(buffer, bufsize, "<stream:null>");
  156. }
  157. } else {
  158. snprintf(buffer, bufsize, "<tag:%zd>", cell->tag);
  159. }
  160. return buffer;
  161. }
  162. char* lisp_write(Cell* cell, char* buffer, int bufsize) {
  163. return write_(cell, buffer, 0, bufsize);
  164. }
  165. Cell* lisp_write_to_cell(Cell* cell, Cell* buffer_cell) {
  166. if (buffer_cell->tag == TAG_STR || buffer_cell->tag == TAG_BYTES) {
  167. lisp_write(cell, buffer_cell->ar.addr, buffer_cell->dr.size);
  168. }
  169. return buffer_cell;
  170. }