fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. struct cell {
  5. int c, d;
  6. };
  7. size_t width(const char *s) {
  8. const char *p;
  9. for (p = s; *p && *p == *s; p++) {}
  10. return p - s;
  11. }
  12. size_t nop_width(const char *s) {
  13. const char *p;
  14. for (p = s; *p; p++) {
  15. if (*p == '>' || *p == '<' || *p == '+' || *p == '-') break;
  16. if (*p == '.' || *p == ',' || *p == '[' || *p == ']') break;
  17. }
  18. return p - s;
  19. }
  20. struct cell *find_square_bracket_right(struct cell *p) {
  21. int depth = 0;
  22. for (; p->c; p += p->d) {
  23. if (p->c == '[') depth++;
  24. else if (p->c == ']') {
  25. if (depth == 0) break;
  26. else depth--;
  27. }
  28. }
  29. return p;
  30. }
  31. struct cell *init_square_brackets(struct cell *b) {
  32. struct cell *p, *q;
  33. for (p = b; p->c;) {
  34. switch (p->c) {
  35. case '[':
  36. q = find_square_bracket_right(p + 1);
  37. p->d = q - p + 1;
  38. q->d = - (q - p);
  39. case ']': p++; break;
  40. default: p += p->d; break;
  41. }
  42. }
  43. return b;
  44. }
  45. struct cell *scan(const char *s) {
  46. size_t size = strlen(s), i, j, w;
  47. struct cell *cells = malloc(sizeof (struct cell) * (size + 1));
  48. for (i = 0; i < size; i += cells[i].d) {
  49. switch (s[i]) {
  50. case '>': case '<': case '+': case '-':
  51. for (w = width(s + i), j = 0; j < w; j++) {
  52. cells[i + j].c = s[i + j];
  53. cells[i + j].d = w - j;
  54. }
  55. break;
  56. case '.': case ',': case '[': case ']':
  57. cells[i].c = s[i];
  58. cells[i].d = 1;
  59. break;
  60. default:
  61. for (w = nop_width(s + i), j = 0; j < w; j++) {
  62. cells[i + j].c = s[i + j];
  63. cells[i + j].d = w - j;
  64. }
  65. break;
  66. }
  67. }
  68. cells[i].c = '\0';
  69. cells[i].d = 0;
  70. return init_square_brackets(cells);
  71. }
  72. struct range {
  73. char *begin, *end;
  74. };
  75. struct cell *f(struct cell *ip0, char *dp, struct range *range) {
  76. register struct cell *ip;
  77. for (ip = ip0; ip->c; ip += ip->c == '[' && *dp ? 1 : ip->d) {
  78. switch (ip->c) {
  79. case '>': if (range->end <= (dp += ip->d)) exit(1); break;
  80. case '<': if ((dp -= ip->d) < range->begin) exit(1); break;
  81. case '+': *dp += ip->d; break;
  82. case '-': *dp -= ip->d; break;
  83. case '.': putchar(*dp); break;
  84. case ',': *dp = getchar(); break;
  85. default: break;
  86. }
  87. }
  88. return ip0;
  89. }
  90. void g(const char *s) {
  91. char data[30000] = {0};
  92. struct range range = {data, data + sizeof data};
  93. free(f(scan(s), data, &range));
  94. }
  95. int main() {
  96. g("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.");
  97. g("++++++++[>++++++++<-]>++.<++++++[>++++++++<-]>.<----[>++++<-]>-.++++++++.+++++.--------.+++++++++++++++.<----[>++++<-]>--.++++++++.");
  98. return 0;
  99. }
  100.  
Success #stdin #stdout 0s 9424KB
stdin
Standard input is empty
stdout
Hello World!
Brainfuck