-
Notifications
You must be signed in to change notification settings - Fork 15
/
tokenize.js
65 lines (61 loc) · 1.54 KB
/
tokenize.js
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
60
61
62
63
64
65
var util = require('./util.js');
var delimiters = ["(", ")", "[", "]", "'", ",", "@", "\"", ";"]
var whitespace_re = /^\s/
function get_site_map(s) {
var map = {};
var row = 1;
var col = 1;
for (var i = 0; i < s.length; i++) {
if (s[i] == "\n") {
row++;
col = 1;
} else {
map[i] = row + ":" + col;
col++;
}
}
return map;
}
function tokenize(s) {
var tokens = [];
var begin = 0;
var end = 0;
var site_map = get_site_map(s);
while (begin < s.length) {
if (s[begin].match(whitespace_re)) {
begin++;
} else if (s[begin] == ";") {
for (; begin < s.length && s[begin] != "\n" && s[begin] != "\r"; begin++) {}
} else {
if (s[begin] == "\"") {
for (end = begin + 1; ; end++) {
if (end > s.length) {
throw util.make_church_error("SyntaxError", site_map[begin], site_map[begin], "Unclosed double quote");
} else if (s.slice(end, end + 2) == "\\\"") {
end++;
} else if (s[end] == "\"") {
end++;
break;
}
}
} else if (delimiters.indexOf(s[begin]) != -1) {
end = begin + 1;
} else {
for (end = begin; end < s.length; end++) {
if (delimiters.indexOf(s[end]) != -1 || s[end].match(whitespace_re)) {
break;
}
}
}
var token = s.slice(begin, end);
if (token[0] == '"')
token = '"' + token.substring(1, token.length-1).replace(/\\\"/g, '"') + '"'
tokens.push({text: token, start: site_map[begin], end: site_map[end-1]});
begin = end;
}
}
return tokens;
}
module.exports = {
tokenize: tokenize
}