erplp.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // parsing:
  2. int skip_whitespace () {
  3. int c;
  4. do {
  5. c = _getchar();
  6. } while (c == ' ' || c == '\n');
  7. lastchar = c;
  8. return c;
  9. }
  10. Atom* parse_list () {
  11. List *list = NULL, *next = NULL;
  12. while (1) {
  13. if (lastchar == -1 || lastchar == ' ' || lastchar == '\n')
  14. skip_whitespace();
  15. if (lastchar == ')') {
  16. lastchar = -1;
  17. break;
  18. }
  19. Atom *at = parse();
  20. List *tail = cons(at, NULL);
  21. if (next) {
  22. next->tail = tail;
  23. } else {
  24. list = next = tail;
  25. }
  26. next = tail;
  27. }
  28. return create_list(list);
  29. }
  30. Atom* parse_symbol (int c) {
  31. int buf[65536], n = 1, stop_at;
  32. if (lastchar != -1) {
  33. buf[n] = lastchar;
  34. lastchar = -1;
  35. n++;
  36. }
  37. switch (c) {
  38. case '"':
  39. case '\'':
  40. stop_at = c;
  41. do {
  42. if (c == '\\') {
  43. c = _getchar();
  44. switch (c) {
  45. case 'b': c = '\b'; break;
  46. case 'n': c = '\n'; break;
  47. case 't': c = '\t';
  48. }
  49. }
  50. buf[n] = c;
  51. c = _getchar();
  52. n ++;
  53. } while (c != stop_at && n < 65536);
  54. lastchar = -1;
  55. default:
  56. while (n < 65536 && c != ' ' && c != '\n' && c != '(' && c != ')') {
  57. buf[n] = c;
  58. c = _getchar();
  59. n ++;
  60. }
  61. lastchar = c;
  62. }
  63. if (n == 1)
  64. return NULL;
  65. buf[0] = n-1;
  66. if (symbols_are_equal(buf, nil_symb))
  67. return NULL;
  68. return create_symbol(duplicate_symbol(buf));
  69. }
  70. // TODO this routine needs rework, very bad quality code
  71. Atom* parse_int (int c) {
  72. char neg = 0;
  73. int value = 0;
  74. int input_processed = 0;
  75. int firstchar = c;
  76. if (c == '+') {
  77. } else if (c == '-') {
  78. neg = 1;
  79. } else if (c >= '0' && c <= '9') {
  80. value += (c - '0');
  81. input_processed = 1;
  82. lastchar = -1;
  83. }
  84. while (1) {
  85. c = _getchar();
  86. if (c >= '0' && c <= '9') {
  87. if (!input_processed)
  88. input_processed = 1;
  89. value *= 10;
  90. value += (c - '0');
  91. } else {
  92. lastchar = c;
  93. break;
  94. }
  95. if (value < 0)
  96. return NULL;
  97. }
  98. if (!input_processed) {
  99. input_processed = firstchar;
  100. firstchar = lastchar;
  101. lastchar = input_processed;
  102. return parse_symbol(firstchar);
  103. }
  104. if (neg)
  105. value = -value;
  106. return create_int(value);
  107. }
  108. Atom* parse () {
  109. if (lastchar == -1 || lastchar == ' ' || lastchar == '\n')
  110. skip_whitespace();
  111. int c = lastchar;
  112. lastchar = -1;
  113. if (c == '(') {
  114. return parse_list();
  115. } else if (c == '-' || c == '+' || (c >= '0' && c <= '9')) {
  116. return parse_int(c);
  117. } else if (c == ';') {
  118. while (c != '\n')
  119. c = _getchar();
  120. return parse();
  121. } else if (c == ')') {
  122. return _warning("PARSE" EXTRA_PARENTHESIS);
  123. } else {
  124. return parse_symbol(c);
  125. }
  126. }