File size: 1,832 Bytes
119e586
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
var SExprParser = {
  parse: function(input) {
    input = input.trim();
    if (!input) return null;
    return this._readAtom(input, 0).value;
  },

  _readAtom: function(input, pos) {
    while (pos < input.length && input[pos] === ' ') pos++;
    if (pos >= input.length) return { value: null, pos: pos };

    if (input[pos] === '(') {
      return this._readList(input, pos + 1);
    } else if (input[pos] === '"') {
      return this._readString(input, pos + 1);
    } else {
      return this._readSymbol(input, pos);
    }
  },

  _readList: function(input, pos) {
    var items = [];
    while (pos < input.length) {
      while (pos < input.length && input[pos] === ' ') pos++;
      if (pos >= input.length) break;
      if (input[pos] === ')') return { value: items, pos: pos + 1 };
      var result = this._readAtom(input, pos);
      items.push(result.value);
      pos = result.pos;
    }
    return { value: items, pos: pos };
  },

  _readString: function(input, pos) {
    var start = pos;
    while (pos < input.length && input[pos] !== '"') pos++;
    return { value: input.substring(start, pos), pos: pos + 1 };
  },

  _readSymbol: function(input, pos) {
    var start = pos;
    while (pos < input.length && '() '.indexOf(input[pos]) === -1) pos++;
    var raw = input.substring(start, pos);
    var num = Number(raw);
    if (!isNaN(num) && raw !== '') return { value: num, pos: pos };
    return { value: raw, pos: pos };
  },

  toString: function(expr) {
    if (expr === null) return 'nil';
    if (typeof expr === 'string') return '"' + expr + '"';
    if (typeof expr === 'number') return String(expr);
    if (Array.isArray(expr)) {
      return '(' + expr.map(this.toString.bind(this)).join(' ') + ')';
    }
    return String(expr);
  }
};