// Generated by LiveScript 1.4.0
|
(function(){
|
var identifierRegex, tokenRegex;
|
identifierRegex = /[\$\w]+/;
|
function peek(tokens){
|
var token;
|
token = tokens[0];
|
if (token == null) {
|
throw new Error('Unexpected end of input.');
|
}
|
return token;
|
}
|
function consumeIdent(tokens){
|
var token;
|
token = peek(tokens);
|
if (!identifierRegex.test(token)) {
|
throw new Error("Expected text, got '" + token + "' instead.");
|
}
|
return tokens.shift();
|
}
|
function consumeOp(tokens, op){
|
var token;
|
token = peek(tokens);
|
if (token !== op) {
|
throw new Error("Expected '" + op + "', got '" + token + "' instead.");
|
}
|
return tokens.shift();
|
}
|
function maybeConsumeOp(tokens, op){
|
var token;
|
token = tokens[0];
|
if (token === op) {
|
return tokens.shift();
|
} else {
|
return null;
|
}
|
}
|
function consumeArray(tokens){
|
var types;
|
consumeOp(tokens, '[');
|
if (peek(tokens) === ']') {
|
throw new Error("Must specify type of Array - eg. [Type], got [] instead.");
|
}
|
types = consumeTypes(tokens);
|
consumeOp(tokens, ']');
|
return {
|
structure: 'array',
|
of: types
|
};
|
}
|
function consumeTuple(tokens){
|
var components;
|
components = [];
|
consumeOp(tokens, '(');
|
if (peek(tokens) === ')') {
|
throw new Error("Tuple must be of at least length 1 - eg. (Type), got () instead.");
|
}
|
for (;;) {
|
components.push(consumeTypes(tokens));
|
maybeConsumeOp(tokens, ',');
|
if (')' === peek(tokens)) {
|
break;
|
}
|
}
|
consumeOp(tokens, ')');
|
return {
|
structure: 'tuple',
|
of: components
|
};
|
}
|
function consumeFields(tokens){
|
var fields, subset, ref$, key, types;
|
fields = {};
|
consumeOp(tokens, '{');
|
subset = false;
|
for (;;) {
|
if (maybeConsumeOp(tokens, '...')) {
|
subset = true;
|
break;
|
}
|
ref$ = consumeField(tokens), key = ref$[0], types = ref$[1];
|
fields[key] = types;
|
maybeConsumeOp(tokens, ',');
|
if ('}' === peek(tokens)) {
|
break;
|
}
|
}
|
consumeOp(tokens, '}');
|
return {
|
structure: 'fields',
|
of: fields,
|
subset: subset
|
};
|
}
|
function consumeField(tokens){
|
var key, types;
|
key = consumeIdent(tokens);
|
consumeOp(tokens, ':');
|
types = consumeTypes(tokens);
|
return [key, types];
|
}
|
function maybeConsumeStructure(tokens){
|
switch (tokens[0]) {
|
case '[':
|
return consumeArray(tokens);
|
case '(':
|
return consumeTuple(tokens);
|
case '{':
|
return consumeFields(tokens);
|
}
|
}
|
function consumeType(tokens){
|
var token, wildcard, type, structure;
|
token = peek(tokens);
|
wildcard = token === '*';
|
if (wildcard || identifierRegex.test(token)) {
|
type = wildcard
|
? consumeOp(tokens, '*')
|
: consumeIdent(tokens);
|
structure = maybeConsumeStructure(tokens);
|
if (structure) {
|
return structure.type = type, structure;
|
} else {
|
return {
|
type: type
|
};
|
}
|
} else {
|
structure = maybeConsumeStructure(tokens);
|
if (!structure) {
|
throw new Error("Unexpected character: " + token);
|
}
|
return structure;
|
}
|
}
|
function consumeTypes(tokens){
|
var lookahead, types, typesSoFar, typeObj, type;
|
if ('::' === peek(tokens)) {
|
throw new Error("No comment before comment separator '::' found.");
|
}
|
lookahead = tokens[1];
|
if (lookahead != null && lookahead === '::') {
|
tokens.shift();
|
tokens.shift();
|
}
|
types = [];
|
typesSoFar = {};
|
if ('Maybe' === peek(tokens)) {
|
tokens.shift();
|
types = [
|
{
|
type: 'Undefined'
|
}, {
|
type: 'Null'
|
}
|
];
|
typesSoFar = {
|
Undefined: true,
|
Null: true
|
};
|
}
|
for (;;) {
|
typeObj = consumeType(tokens), type = typeObj.type;
|
if (!typesSoFar[type]) {
|
types.push(typeObj);
|
}
|
typesSoFar[type] = true;
|
if (!maybeConsumeOp(tokens, '|')) {
|
break;
|
}
|
}
|
return types;
|
}
|
tokenRegex = RegExp('\\.\\.\\.|::|->|' + identifierRegex.source + '|\\S', 'g');
|
module.exports = function(input){
|
var tokens, e;
|
if (!input.length) {
|
throw new Error('No type specified.');
|
}
|
tokens = input.match(tokenRegex) || [];
|
if (in$('->', tokens)) {
|
throw new Error("Function types are not supported.\ To validate that something is a function, you may use 'Function'.");
|
}
|
try {
|
return consumeTypes(tokens);
|
} catch (e$) {
|
e = e$;
|
throw new Error(e.message + " - Remaining tokens: " + JSON.stringify(tokens) + " - Initial input: '" + input + "'");
|
}
|
};
|
function in$(x, xs){
|
var i = -1, l = xs.length >>> 0;
|
while (++i < l) if (x === xs[i]) return true;
|
return false;
|
}
|
}).call(this);
|