proc_macro
Version:
A JavaScript implementation of proc_macros.
209 lines • 7.7 kB
JavaScript
"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var tokens_1 = require("../tokens");
var chalk_1 = __importDefault(require("chalk"));
var TokenStream = /** @class */ (function () {
function TokenStream(tokens) {
if (tokens === void 0) { tokens = []; }
this._stream = tokens;
}
Object.defineProperty(TokenStream.prototype, "empty", {
get: function () {
return this._stream.length === 0;
},
enumerable: false,
configurable: true
});
TokenStream.prototype.clone = function () {
return new TokenStream(__spreadArrays(this._stream));
};
TokenStream.prototype.eq = function (other) {
if (other instanceof TokenStream && other._stream.length === this._stream.length) {
return this._stream.every(function (token, index) { return token.eq(other._stream[index]); });
}
return false;
};
/**
* Adds`other` TokenStream to end of `this` TokenStream.
* @param other Tokens stream to add.
*/
TokenStream.prototype.concat = function (other) {
this._stream.concat(other._stream);
return this;
};
/**
* Checks if TokenStreams are equal until size of smallest.
* @param tokenStream TokenStream to compare.
*/
TokenStream.prototype.zipEq = function (tokenStream) {
var small = (this._stream.length > tokenStream._stream.length) ? tokenStream : this;
var large = (this === small) ? tokenStream : this;
return small._stream.every(function (token, index) { return token.eq(large._stream[index]); });
};
/**
* Parses a string to a proc_macro like token tree.
* @param tokenString String to parse.
*/
TokenStream.tokenize = function (tokenString) {
var tokenStream = new TokenStream();
outer: while (tokenString.trimLeft().length > 0) {
tokenString = tokenString.trimLeft();
for (var _i = 0, TOKENS_1 = tokens_1.TOKENS; _i < TOKENS_1.length; _i++) {
var type = TOKENS_1[_i];
if (type.canTokenize(tokenString)) {
var _a = type.tokenize(tokenString), token = _a[0], ts = _a[1];
tokenStream._stream.push(token);
tokenString = ts;
continue outer;
}
}
throw Error("FATAL ERROR: Could not tokenize input. This is an error on the proc_macro.js library side. Please report bug.");
}
return tokenStream;
};
Object.defineProperty(TokenStream.prototype, "next", {
/**
* Peeks the next raw Token (Should use `peek` instead).
*/
get: function () {
return this._stream[0];
},
enumerable: false,
configurable: true
});
Object.defineProperty(TokenStream.prototype, "stream", {
/**
* Gets the raw Token array (Should use `parse` instead).
*/
get: function () {
return this._stream;
},
enumerable: false,
configurable: true
});
/**
* Gets the next raw Token (Should use `parse` instead).
*/
TokenStream.prototype.shiftNext = function () {
return this.shift(1);
};
TokenStream.prototype.shift = function (count) {
if (count === void 0) { count = 1; }
if (this._stream.length < count)
return undefined;
return new TokenStream(this._stream.splice(0, count));
};
TokenStream.prototype.slice = function (count) {
if (count === void 0) { count = 1; }
if (this._stream.length < count)
return undefined;
return new TokenStream(this._stream.slice(0, count));
};
/**
* Tagged template to determine if passed tokens are expected tokens.
* @param tokens Tokens as string.
* @param types Types to check.
*/
TokenStream.prototype.peek = function (tokens) {
var _a;
var types = [];
for (var _i = 1; _i < arguments.length; _i++) {
types[_i - 1] = arguments[_i];
}
try {
(_a = this.clone()).parse.apply(_a, __spreadArrays([tokens], types));
return true;
}
catch (_b) {
return false;
}
};
/**
* Descriptive error for runtime error. (TODO: Using spans.)
* @param msg Message to display.
*/
TokenStream.prototype.error = function (msg) {
var tokenMap = this._stream.map(function (token, i) {
if (i > 0)
return token.toJavaScript();
else
return chalk_1.default.red(token.toJavaScript());
});
return Error("\n|\n| " + tokenMap.join('') + "\n| " + chalk_1.default.red('^') + "\n| " + chalk_1.default.red('|') + "\n| " + chalk_1.default.red(msg) + "\n|");
};
/**
* Attempts to parse string of tokens.
* @throws If cannot parse tokens.
* @param tokenString String of tokens to parse.
*/
TokenStream.prototype.parseString = function (tokenString) {
var tokenStream = TokenStream.tokenize(tokenString);
if (!this.canParse(tokenStream))
throw this.error("Expected the token \"" + tokenString + "\".");
var next = this.shift(tokenStream._stream.length);
if (!next)
throw this.error("Expected the token \"" + tokenString + "\".");
return next;
};
/**
* Checks if the object can be parsed.
* @param tokenStream The TokenStream trying to parse.
*/
TokenStream.prototype.canParse = function (tokenStream) {
return this.zipEq(tokenStream);
};
/**
* Tagged template to parse tokens and types.
* @param tokens String representation of tokens.
* @param types
*/
TokenStream.prototype.parse = function (tokens) {
var _this = this;
var types = [];
for (var _i = 1; _i < arguments.length; _i++) {
types[_i - 1] = arguments[_i];
}
var typeTokens = [];
tokens.forEach(function (token, i) {
_this.parseString(token);
if (types[i]) {
var type = types[i];
var typeToken = _this.parseType(type);
typeTokens.push(typeToken);
}
});
return typeTokens;
};
/**
* Attempts to parse a Token or Expression type.
* @param type Type to parse.
*/
TokenStream.prototype.parseType = function (type) {
if (type.canParse(this)) {
var t = type.parse(this);
return t;
}
throw this.error("Expected the type " + type.name + ".");
};
TokenStream.prototype.toParenthesisString = function () {
var output = "(TokenStream ";
output += this._stream.map(function (t) { return t.toParenthesisString(); }).join(' ');
return output + ")";
};
TokenStream.prototype.toJavaScript = function () {
return this._stream.map(function (token) { return token.toJavaScript(); }).join('');
};
return TokenStream;
}());
exports.default = TokenStream;
//# sourceMappingURL=token_stream.js.map