pyret-npm 0.1.22 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -20
- package/package.json +5 -2
- package/pyret-lang/lib/jglr/cyclicJSON.js +174 -0
- package/pyret-lang/lib/jglr/jglr.js +341 -0
- package/pyret-lang/lib/jglr/rnglr.js +2687 -0
- package/pyret-lang/src/js/base/js-numbers.js +4311 -0
- package/pyret-lang/src/js/base/pyret-tokenizer.js +579 -0
- package/pyret-lang/src/js/base/type-util.js +553 -0
package/README.md
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
NPM package for a command line interface of the Pyret programming language.
|
|
2
2
|
|
|
3
|
-
The package ships a prebuilt compiler. `build.sh` builds `lang/` from this
|
|
4
|
-
repository and stages `build/phaseA` into `pyret-lang/`, which is where
|
|
5
|
-
`pyret.js` loads it from.
|
|
6
|
-
|
|
7
3
|
After installing the package, you can run
|
|
8
4
|
|
|
9
5
|
```
|
|
@@ -12,19 +8,3 @@ $ pyret --help
|
|
|
12
8
|
|
|
13
9
|
to get started.
|
|
14
10
|
|
|
15
|
-
## Compiler backends
|
|
16
|
-
|
|
17
|
-
The CLI can run on either the stock Pyret-hosted compiler (the default) or
|
|
18
|
-
the TypeScript port of the compiler (`pyret-lang/src/ts-compiler`) — the CLI
|
|
19
|
-
analogue of code.pyret.org's `?compiler=ts` flag:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
$ pyret --backend ts my-program.arr # or: PYRET_COMPILER=ts pyret my-program.arr
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Each backend keeps its own Parley compile server (separate sockets), so both
|
|
26
|
-
can be used side by side. An explicit `--compiler <path>` overrides
|
|
27
|
-
`--backend`. The ts backend is available when the package was built with
|
|
28
|
-
`PYRET_NPM_TS=1 npm run build` (which additionally runs `make ts-compiler`
|
|
29
|
-
in `../lang` and packages its build output); the default build ships only
|
|
30
|
-
the stock compiler, and default behavior is unchanged.
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pyret-npm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "The CLI for the Pyret programming language",
|
|
5
5
|
"files": [
|
|
6
6
|
"pyret.js",
|
|
7
7
|
"client-lib.js",
|
|
8
8
|
"pyret-lang/build/phaseA/*",
|
|
9
|
-
"pyret-lang/build/ts-compiler/*"
|
|
9
|
+
"pyret-lang/build/ts-compiler/*",
|
|
10
|
+
"pyret-lang/src/js/base/*",
|
|
11
|
+
"pyret-lang/lib/jglr/*"
|
|
10
12
|
],
|
|
11
13
|
"dependencies": {
|
|
12
14
|
"ascii-table": "^0.0.9",
|
|
@@ -15,6 +17,7 @@
|
|
|
15
17
|
"command-line-usage": "^5.0.5",
|
|
16
18
|
"mkdirp": "^0.5.1",
|
|
17
19
|
"resolve": "^1.22.10",
|
|
20
|
+
"source-map": "^0.5.7",
|
|
18
21
|
"strip-ansi": "^4.0.0",
|
|
19
22
|
"vega": "^6.1.2",
|
|
20
23
|
"ws": "^5.2.1"
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
define("jglr/cyclicJSON", [], function() {
|
|
2
|
+
/*
|
|
3
|
+
cycle.js
|
|
4
|
+
2013-02-19
|
|
5
|
+
|
|
6
|
+
Public Domain.
|
|
7
|
+
|
|
8
|
+
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
|
9
|
+
|
|
10
|
+
This code should be minified before deployment.
|
|
11
|
+
See http://javascript.crockford.com/jsmin.html
|
|
12
|
+
|
|
13
|
+
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
|
14
|
+
NOT CONTROL.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/*jslint evil: true, regexp: true */
|
|
18
|
+
|
|
19
|
+
/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push,
|
|
20
|
+
retrocycle, stringify, test, toString
|
|
21
|
+
*/
|
|
22
|
+
//////////////////////////////////
|
|
23
|
+
if (typeof JSON.decycle !== 'function') {
|
|
24
|
+
JSON.decycle = function decycle(object) {
|
|
25
|
+
'use strict';
|
|
26
|
+
|
|
27
|
+
// Make a deep copy of an object or array, assuring that there is at most
|
|
28
|
+
// one instance of each object or array in the resulting structure. The
|
|
29
|
+
// duplicate references (which might be forming cycles) are replaced with
|
|
30
|
+
// an object of the form
|
|
31
|
+
// {$ref: PATH}
|
|
32
|
+
// where the PATH is a JSONPath string that locates the first occurance.
|
|
33
|
+
// So,
|
|
34
|
+
// var a = [];
|
|
35
|
+
// a[0] = a;
|
|
36
|
+
// return JSON.stringify(JSON.decycle(a));
|
|
37
|
+
// produces the string '[{"$ref":"$"}]'.
|
|
38
|
+
|
|
39
|
+
// JSONPath is used to locate the unique object. $ indicates the top level of
|
|
40
|
+
// the object or array. [NUMBER] or [STRING] indicates a child member or
|
|
41
|
+
// property.
|
|
42
|
+
|
|
43
|
+
var objects = [], // Keep a reference to each unique object or array
|
|
44
|
+
paths = []; // Keep the path to each unique object or array
|
|
45
|
+
|
|
46
|
+
return (function derez(value, path) {
|
|
47
|
+
|
|
48
|
+
// The derez recurses through the object, producing the deep copy.
|
|
49
|
+
|
|
50
|
+
var i, // The loop counter
|
|
51
|
+
name, // Property name
|
|
52
|
+
nu; // The new object or array
|
|
53
|
+
|
|
54
|
+
// typeof null === 'object', so go on if this value is really an object but not
|
|
55
|
+
// one of the weird builtin objects.
|
|
56
|
+
|
|
57
|
+
if (typeof value === 'object' && value !== null &&
|
|
58
|
+
!(value instanceof Boolean) &&
|
|
59
|
+
!(value instanceof Date) &&
|
|
60
|
+
!(value instanceof Number) &&
|
|
61
|
+
!(value instanceof RegExp) &&
|
|
62
|
+
!(value instanceof String)) {
|
|
63
|
+
|
|
64
|
+
// If the value is an object or array, look to see if we have already
|
|
65
|
+
// encountered it. If so, return a $ref/path object. This is a hard way,
|
|
66
|
+
// linear search that will get slower as the number of unique objects grows.
|
|
67
|
+
|
|
68
|
+
for (i = 0; i < objects.length; i += 1) {
|
|
69
|
+
if (objects[i] === value) {
|
|
70
|
+
return {$ref: paths[i]};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Otherwise, accumulate the unique value and its path.
|
|
75
|
+
|
|
76
|
+
objects.push(value);
|
|
77
|
+
paths.push(path);
|
|
78
|
+
|
|
79
|
+
// If it is an array, replicate the array.
|
|
80
|
+
|
|
81
|
+
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
|
82
|
+
nu = [];
|
|
83
|
+
for (i = 0; i < value.length; i += 1) {
|
|
84
|
+
nu[i] = derez(value[i], path + '[' + i + ']');
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
|
|
88
|
+
// If it is an object, replicate the object.
|
|
89
|
+
|
|
90
|
+
nu = {};
|
|
91
|
+
for (name in value) {
|
|
92
|
+
if (Object.prototype.hasOwnProperty.call(value, name)) {
|
|
93
|
+
nu[name] = derez(value[name],
|
|
94
|
+
path + '[' + JSON.stringify(name) + ']');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return nu;
|
|
99
|
+
}
|
|
100
|
+
return value;
|
|
101
|
+
}(object, '$'));
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if (typeof JSON.retrocycle !== 'function') {
|
|
107
|
+
JSON.retrocycle = function retrocycle($) {
|
|
108
|
+
'use strict';
|
|
109
|
+
|
|
110
|
+
// Restore an object that was reduced by decycle. Members whose values are
|
|
111
|
+
// objects of the form
|
|
112
|
+
// {$ref: PATH}
|
|
113
|
+
// are replaced with references to the value found by the PATH. This will
|
|
114
|
+
// restore cycles. The object will be mutated.
|
|
115
|
+
|
|
116
|
+
// The eval function is used to locate the values described by a PATH. The
|
|
117
|
+
// root object is kept in a $ variable. A regular expression is used to
|
|
118
|
+
// assure that the PATH is extremely well formed. The regexp contains nested
|
|
119
|
+
// * quantifiers. That has been known to have extremely bad performance
|
|
120
|
+
// problems on some browsers for very long strings. A PATH is expected to be
|
|
121
|
+
// reasonably short. A PATH is allowed to belong to a very restricted subset of
|
|
122
|
+
// Goessner's JSONPath.
|
|
123
|
+
|
|
124
|
+
// So,
|
|
125
|
+
// var s = '[{"$ref":"$"}]';
|
|
126
|
+
// return JSON.retrocycle(JSON.parse(s));
|
|
127
|
+
// produces an array containing a single element which is the array itself.
|
|
128
|
+
|
|
129
|
+
var px =
|
|
130
|
+
/^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/;
|
|
131
|
+
|
|
132
|
+
(function rez(value) {
|
|
133
|
+
|
|
134
|
+
// The rez function walks recursively through the object looking for $ref
|
|
135
|
+
// properties. When it finds one that has a value that is a path, then it
|
|
136
|
+
// replaces the $ref object with a reference to the value that is found by
|
|
137
|
+
// the path.
|
|
138
|
+
|
|
139
|
+
var i, item, name, path;
|
|
140
|
+
|
|
141
|
+
if (value && typeof value === 'object') {
|
|
142
|
+
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
|
143
|
+
for (i = 0; i < value.length; i += 1) {
|
|
144
|
+
item = value[i];
|
|
145
|
+
if (item && typeof item === 'object') {
|
|
146
|
+
path = item.$ref;
|
|
147
|
+
if (typeof path === 'string' && px.test(path)) {
|
|
148
|
+
value[i] = eval(path);
|
|
149
|
+
} else {
|
|
150
|
+
rez(item);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
for (name in value) {
|
|
156
|
+
if (typeof value[name] === 'object') {
|
|
157
|
+
item = value[name];
|
|
158
|
+
if (item) {
|
|
159
|
+
path = item.$ref;
|
|
160
|
+
if (typeof path === 'string' && px.test(path)) {
|
|
161
|
+
value[name] = eval(path);
|
|
162
|
+
} else {
|
|
163
|
+
rez(item);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}($));
|
|
171
|
+
return $;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
});
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
define("jglr/jglr", ["jglr/rnglr"], function(E) {
|
|
2
|
+
const SrcLoc = E.SrcLoc
|
|
3
|
+
const NS_PER_SEC = 1e9;
|
|
4
|
+
var start;
|
|
5
|
+
function startTimer() {
|
|
6
|
+
if (typeof window !== "undefined" && window.performance) {
|
|
7
|
+
start = window.performance.now();
|
|
8
|
+
} else if (typeof process !== "undefined" && process.hrtime) {
|
|
9
|
+
start = process.hrtime();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function endTimer() {
|
|
13
|
+
if (typeof window !== "undefined" && window.performance) {
|
|
14
|
+
return window.performance.now() - start;
|
|
15
|
+
} else if (typeof process !== "undefined" && process.hrtime) {
|
|
16
|
+
return process.hrtime(start);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/*! https://mths.be/startswith v0.2.0 by @mathias */
|
|
21
|
+
if (!String.prototype.startsWith) {
|
|
22
|
+
(function() {
|
|
23
|
+
'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
|
|
24
|
+
var defineProperty = (function() {
|
|
25
|
+
// IE 8 only supports `Object.defineProperty` on DOM elements
|
|
26
|
+
try {
|
|
27
|
+
var object = {};
|
|
28
|
+
var $defineProperty = Object.defineProperty;
|
|
29
|
+
var result = $defineProperty(object, object, object) && $defineProperty;
|
|
30
|
+
} catch(error) {}
|
|
31
|
+
return result;
|
|
32
|
+
}());
|
|
33
|
+
var toString = {}.toString;
|
|
34
|
+
var startsWith = function(search) {
|
|
35
|
+
if (this == null) {
|
|
36
|
+
throw TypeError();
|
|
37
|
+
}
|
|
38
|
+
var string = String(this);
|
|
39
|
+
if (search && toString.call(search) == '[object RegExp]') {
|
|
40
|
+
throw TypeError();
|
|
41
|
+
}
|
|
42
|
+
var stringLength = string.length;
|
|
43
|
+
var searchString = String(search);
|
|
44
|
+
var searchLength = searchString.length;
|
|
45
|
+
var position = arguments.length > 1 ? arguments[1] : undefined;
|
|
46
|
+
// `ToInteger`
|
|
47
|
+
var pos = position ? Number(position) : 0;
|
|
48
|
+
if (pos != pos) { // better `isNaN`
|
|
49
|
+
pos = 0;
|
|
50
|
+
}
|
|
51
|
+
var start = Math.min(Math.max(pos, 0), stringLength);
|
|
52
|
+
// Avoid the `indexOf` call if no match is possible
|
|
53
|
+
if (searchLength + start > stringLength) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
var index = -1;
|
|
57
|
+
while (++index < searchLength) {
|
|
58
|
+
if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
};
|
|
64
|
+
if (defineProperty) {
|
|
65
|
+
defineProperty(String.prototype, 'startsWith', {
|
|
66
|
+
'value': startsWith,
|
|
67
|
+
'configurable': true,
|
|
68
|
+
'writable': true
|
|
69
|
+
});
|
|
70
|
+
} else {
|
|
71
|
+
String.prototype.startsWith = startsWith;
|
|
72
|
+
}
|
|
73
|
+
}());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
//////////////////////////////////////////////////
|
|
80
|
+
///////////////////////// Old Tokenizer
|
|
81
|
+
//////////////////////////////////////////////////
|
|
82
|
+
|
|
83
|
+
var Tokenizer = (function() {
|
|
84
|
+
function Tokenizer(ignore_ws, Tokens) {
|
|
85
|
+
this.ignore_ws = ignore_ws;
|
|
86
|
+
this.Tokens = Tokens;
|
|
87
|
+
}
|
|
88
|
+
Tokenizer.prototype.isEOF = function(tok) { return tok === E.EOF; }
|
|
89
|
+
Tokenizer.prototype.tokenizeFrom = function(str) {
|
|
90
|
+
this.str = str;
|
|
91
|
+
this.curLine = 1;
|
|
92
|
+
this.curCol = 0;
|
|
93
|
+
this.pos = 0;
|
|
94
|
+
this.len = str.length;
|
|
95
|
+
delete this.curTok;
|
|
96
|
+
delete E.EOF.pos;
|
|
97
|
+
SrcLoc.reset();
|
|
98
|
+
this.times = {};
|
|
99
|
+
}
|
|
100
|
+
const STICKY_REGEXP = ''; //(function() { try { new RegExp("", 'y'); return 'y' } catch(e) { return ''; }})();
|
|
101
|
+
|
|
102
|
+
Tokenizer.prototype.hasNext = function() { return this.pos <= this.len; }
|
|
103
|
+
Tokenizer.prototype.isEmpty = function() { return this.length == 0; }
|
|
104
|
+
if (STICKY_REGEXP === 'y') {
|
|
105
|
+
Tokenizer.prototype.positionTokenRegexp = function(tok) { tok.val.lastIndex = this.pos; };
|
|
106
|
+
Tokenizer.prototype.updateString = function(match) { };
|
|
107
|
+
Tokenizer.prototype.updatePosition = function(tok, match) { this.pos = tok.val.lastIndex; };
|
|
108
|
+
} else {
|
|
109
|
+
Tokenizer.prototype.positionTokenRegexp = function(tok) { };
|
|
110
|
+
Tokenizer.prototype.updateString = function(match) { this.str = this.str.slice(match[0].length); };
|
|
111
|
+
Tokenizer.prototype.updatePosition = function(tok, match) { this.pos += match[0].length; };
|
|
112
|
+
}
|
|
113
|
+
Tokenizer.prototype.makeToken = function (tok_type, s, pos) {
|
|
114
|
+
var t = new E.Token(tok_type, s);
|
|
115
|
+
t.pos = pos;
|
|
116
|
+
return t;
|
|
117
|
+
}
|
|
118
|
+
Tokenizer.prototype.postProcessMatch = function(tok, match, str) { return tok.name; }
|
|
119
|
+
Tokenizer.prototype.unshiftToken = function(prev_tok) { this.curTok = prev_tok; }
|
|
120
|
+
Tokenizer.prototype.next = function() {
|
|
121
|
+
delete this.skippedWhitespace;
|
|
122
|
+
startTimer();
|
|
123
|
+
while (this.hasNext()) { // Surround the tokenizer loop...
|
|
124
|
+
if (this.pos == this.len) {
|
|
125
|
+
this.pos++;
|
|
126
|
+
E.EOF.pos = SrcLoc.make(this.curLine, this.curCol, this.pos, this.curLine, this.curCol, this.pos);
|
|
127
|
+
this.curTok = E.EOF;
|
|
128
|
+
return E.EOF;
|
|
129
|
+
}
|
|
130
|
+
for (var i = 0; i < this.Tokens.length; i++) {
|
|
131
|
+
var tok = this.Tokens[i];
|
|
132
|
+
this.positionTokenRegexp(tok);
|
|
133
|
+
var match = tok.val.exec(this.str);
|
|
134
|
+
if (match !== null) {
|
|
135
|
+
var tok_type = this.postProcessMatch(tok, match, this.str);
|
|
136
|
+
this.updateString(match);
|
|
137
|
+
var p = this.pos;
|
|
138
|
+
var l = this.curLine;
|
|
139
|
+
var c = this.curCol;
|
|
140
|
+
var s = match[0];
|
|
141
|
+
var lines = s.split("\n").length - 1; // From jsPerf, this is UNBELIEVABLY much faster than the prior implementation
|
|
142
|
+
this.updatePosition(tok, match);
|
|
143
|
+
this.curLine += lines;
|
|
144
|
+
if (lines === 0)
|
|
145
|
+
this.curCol += s.length;
|
|
146
|
+
else
|
|
147
|
+
this.curCol = s.length - s.lastIndexOf("\n") - 1;
|
|
148
|
+
if (this.ignore_ws && (tok_type === "WS" || tok_type === "COMMENT")) {
|
|
149
|
+
// ... in case we're ignoring whitespace
|
|
150
|
+
var endT = endTimer();
|
|
151
|
+
if (this.times[tok_type] === undefined) this.times[tok_type] = [];
|
|
152
|
+
this.times[tok_type].push((endT[0] * NS_PER_SEC + endT[1]) / NS_PER_SEC);
|
|
153
|
+
var newWS = SrcLoc.make(l, c, p, this.curLine, this.curCol, this.pos);
|
|
154
|
+
if (this.skippedWhitespace === undefined)
|
|
155
|
+
this.skippedWhitespace = newWS;
|
|
156
|
+
else
|
|
157
|
+
this.skippedWhitespace = this.skippedWhitespace.combine(newWS);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
var t = this.makeToken(tok_type, s, SrcLoc.make(l, c, p, this.curLine, this.curCol, this.pos));
|
|
161
|
+
this.curTok = t;
|
|
162
|
+
var endT = endTimer();
|
|
163
|
+
if (this.times[this.curTok.name] === undefined) this.times[this.curTok.name] = [];
|
|
164
|
+
this.times[this.curTok.name].push((endT[0] * NS_PER_SEC + endT[1]) / NS_PER_SEC);
|
|
165
|
+
return t;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return Tokenizer;
|
|
172
|
+
})();
|
|
173
|
+
|
|
174
|
+
//////////////////////////////////////////////////
|
|
175
|
+
///////////////////////// New Tokenizer
|
|
176
|
+
//////////////////////////////////////////////////
|
|
177
|
+
|
|
178
|
+
var Tokenizer2 = (function() {
|
|
179
|
+
const ws = new RegExp("\\s+", "g");
|
|
180
|
+
|
|
181
|
+
function merge(dest, src) {
|
|
182
|
+
for (var first in src) {
|
|
183
|
+
var cur = dest[first];
|
|
184
|
+
if (cur === undefined)
|
|
185
|
+
cur = dest[first] = [];
|
|
186
|
+
var ext = src[first];
|
|
187
|
+
for (var i = 0; i < ext.length; i++) {
|
|
188
|
+
cur.push(ext[i]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function Tokenizer(spec) {
|
|
194
|
+
this.ignore = spec.ignore;
|
|
195
|
+
|
|
196
|
+
this.whitespace = spec.whitespace;
|
|
197
|
+
this.keywords = Object.create(null);
|
|
198
|
+
merge(this.keywords, spec.symbols);
|
|
199
|
+
merge(this.keywords, spec.comments);
|
|
200
|
+
merge(this.keywords, spec.keywords);
|
|
201
|
+
for (var first in this.keywords) {
|
|
202
|
+
this.keywords[first].sort(function(a, b) {
|
|
203
|
+
// sort in descending length, then by which needs priorWhitespace, then alphabetically
|
|
204
|
+
if (b.val.length === a.val.length) {
|
|
205
|
+
if (a.needsWs && !b.needsWs) return -1;
|
|
206
|
+
if (b.needsWs && !a.needsWs) return 1;
|
|
207
|
+
return (a < b) ? -1 : 0;
|
|
208
|
+
}
|
|
209
|
+
return b.val.length - a.val.length;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
Tokenizer.prototype.tokenizeFrom = function(str) {
|
|
214
|
+
if (typeof str.normalize === "function")
|
|
215
|
+
this.str = str.normalize("NFC");
|
|
216
|
+
else
|
|
217
|
+
this.str = str;
|
|
218
|
+
|
|
219
|
+
this.len = str.length; // XXX Not necessarily unicode-aware
|
|
220
|
+
this.curCol = 0;
|
|
221
|
+
this.curLine = 1;
|
|
222
|
+
this.pos = 0;
|
|
223
|
+
this.priorWhitespace = true;
|
|
224
|
+
delete this.curTok;
|
|
225
|
+
delete E.EOF.pos;
|
|
226
|
+
SrcLoc.reset();
|
|
227
|
+
this.times = {};
|
|
228
|
+
}
|
|
229
|
+
Tokenizer.prototype.isEOF = function(tok) { return tok === E.EOF; }
|
|
230
|
+
Tokenizer.prototype.isEmpty = function() { return this.length == 0; }
|
|
231
|
+
Tokenizer.prototype.hasNext = function() { return this.pos <= this.len; }
|
|
232
|
+
Tokenizer.prototype.unshiftToken = function(prev_tok) { this.curTok = prev_tok; }
|
|
233
|
+
Tokenizer.prototype.addWhitespace = function(ws_loc) {
|
|
234
|
+
if (this.skippedWhitespace === undefined)
|
|
235
|
+
this.skippedWhitespace = ws_loc;
|
|
236
|
+
else
|
|
237
|
+
this.skippedWhitespace = this.skippedWhitespace.combine(ws_loc);
|
|
238
|
+
}
|
|
239
|
+
Tokenizer.prototype.next = function() {
|
|
240
|
+
delete this.skippedWhitespace;
|
|
241
|
+
this.curTok = undefined;
|
|
242
|
+
var startT = startTimer();
|
|
243
|
+
while (this.curTok === undefined && this.hasNext()) {
|
|
244
|
+
if (this.pos == this.len) {
|
|
245
|
+
this.pos++;
|
|
246
|
+
this.curCol++;
|
|
247
|
+
E.EOF.pos = SrcLoc.make(this.curLine, this.curCol, this.pos, this.curLine, this.curCol, this.pos);
|
|
248
|
+
this.curTok = E.EOF;
|
|
249
|
+
return E.EOF;
|
|
250
|
+
}
|
|
251
|
+
var c = this.str[this.pos]; // XXX not unicode aware
|
|
252
|
+
var candidates = this.keywords[c];
|
|
253
|
+
var line = this.curLine, col = this.curCol, pos = this.pos;
|
|
254
|
+
if (candidates) {
|
|
255
|
+
for (var i = 0; i < candidates.length; i++) {
|
|
256
|
+
var candidate = candidates[i];
|
|
257
|
+
if (this.str.startsWith(candidate.val, this.pos)) {
|
|
258
|
+
if (candidate.process) {
|
|
259
|
+
this.curTok = candidate.process.call(this, candidate);
|
|
260
|
+
if (this.curTok) break;
|
|
261
|
+
} else {
|
|
262
|
+
var noFollow = candidate.noFollow;
|
|
263
|
+
var mustFollow = candidate.mustFollow;
|
|
264
|
+
var match = false;
|
|
265
|
+
if (candidate.needsWs && !this.priorWhitespace) {
|
|
266
|
+
match = false;
|
|
267
|
+
} else if (!noFollow && !mustFollow) {
|
|
268
|
+
match = true;
|
|
269
|
+
} else if (noFollow && !noFollow.has(this.str[this.pos + candidate.val.length])) {
|
|
270
|
+
match = true;
|
|
271
|
+
} else if (mustFollow && mustFollow.has(this.str[this.pos + candidate.val.length])) {
|
|
272
|
+
match = true;
|
|
273
|
+
}
|
|
274
|
+
if (match) {
|
|
275
|
+
this.curCol += candidate.val.length;
|
|
276
|
+
this.pos += candidate.val.length;
|
|
277
|
+
var t = this.makeToken(candidate.name, candidate.val,
|
|
278
|
+
SrcLoc.make(line, col, pos, this.curLine, this.curCol, this.pos),
|
|
279
|
+
candidate);
|
|
280
|
+
this.priorWhitespace = false;
|
|
281
|
+
this.curTok = t;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Handle whitespace
|
|
289
|
+
if (this.curTok === undefined && this.whitespace[c]) {
|
|
290
|
+
this.priorWhitespace = true;
|
|
291
|
+
while (this.whitespace[c]) {
|
|
292
|
+
this.pos++;
|
|
293
|
+
this.curCol++;
|
|
294
|
+
if (c === "\n") {
|
|
295
|
+
this.curLine++;
|
|
296
|
+
this.curCol = 0;
|
|
297
|
+
}
|
|
298
|
+
c = this.str[this.pos]; // XXX not unicode aware
|
|
299
|
+
}
|
|
300
|
+
this.curTok = this.makeWSToken(line, col, pos);
|
|
301
|
+
}
|
|
302
|
+
if (this.curTok === undefined) {
|
|
303
|
+
// FAILOVER
|
|
304
|
+
var t = this.makeToken("UNKNOWN", this.str[this.pos],
|
|
305
|
+
SrcLoc.make(line, col, pos, line, col + 1, pos + 1));
|
|
306
|
+
this.curCol++;
|
|
307
|
+
this.pos++;
|
|
308
|
+
this.curTok = t;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (this.ignore.has(this.curTok.name)) {
|
|
312
|
+
var endT = endTimer();
|
|
313
|
+
if (this.times[this.curTok.name] === undefined) this.times[this.curTok.name] = [];
|
|
314
|
+
this.times[this.curTok.name].push((endT[0] * NS_PER_SEC + endT[1]) / NS_PER_SEC);
|
|
315
|
+
this.curTok = undefined;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
var endT = endTimer();
|
|
319
|
+
if (this.times[this.curTok.name] === undefined) this.times[this.curTok.name] = [];
|
|
320
|
+
this.times[this.curTok.name].push((endT[0] * NS_PER_SEC + endT[1]) / NS_PER_SEC);
|
|
321
|
+
return this.curTok;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return Tokenizer;
|
|
325
|
+
})();
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
'Tokenizer': Tokenizer,
|
|
329
|
+
'Tokenizer2': Tokenizer2,
|
|
330
|
+
'STICKY_REGEXP': '',
|
|
331
|
+
'Atom': E.Atom,
|
|
332
|
+
'Nonterm': E.Nonterm,
|
|
333
|
+
'Token': E.Token,
|
|
334
|
+
'Rule': E.Rule,
|
|
335
|
+
'Grammar': E.Grammar,
|
|
336
|
+
'SetOfSets': E.SetOfSets,
|
|
337
|
+
'EOF': E.EOF,
|
|
338
|
+
'EPSILON': E.EPSILON,
|
|
339
|
+
'SrcLoc': E.SrcLoc
|
|
340
|
+
};
|
|
341
|
+
});
|