144 lines
3.1 KiB
JavaScript
144 lines
3.1 KiB
JavaScript
// Generated by LiveScript 1.2.0
|
|
(function(){
|
|
var reject, tokenRegex;
|
|
reject = require('prelude-ls').reject;
|
|
function consumeWord(tokens){
|
|
var token;
|
|
token = tokens[0];
|
|
if (!(token != null && /^[a-zA-Z]+$/.test(token))) {
|
|
throw new Error("Exected textual string.");
|
|
}
|
|
return tokens.shift();
|
|
}
|
|
function consumeOp(tokens, op){
|
|
var token;
|
|
token = tokens[0];
|
|
if (token !== op) {
|
|
throw new Error("Expected " + op);
|
|
}
|
|
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 contentType;
|
|
consumeOp(tokens, '[');
|
|
contentType = consumeTypes(tokens);
|
|
if (!contentType) {
|
|
throw new Error("Must specify content type for Array.");
|
|
}
|
|
consumeOp(tokens, ']');
|
|
return {
|
|
type: 'Array',
|
|
contentType: contentType
|
|
};
|
|
}
|
|
function consumeTuple(tokens){
|
|
var contentTypes, that;
|
|
contentTypes = [];
|
|
consumeOp(tokens, '(');
|
|
while (that = consumeTypes(tokens)) {
|
|
contentTypes.push(that);
|
|
if (!maybeConsumeOp(tokens, ',')) {
|
|
break;
|
|
}
|
|
}
|
|
consumeOp(tokens, ')');
|
|
return {
|
|
type: 'Tuple',
|
|
contentTypes: contentTypes
|
|
};
|
|
}
|
|
function consumeProperty(tokens){
|
|
var key, type;
|
|
key = consumeWord(tokens);
|
|
consumeOp(tokens, ':');
|
|
type = consumeTypes(tokens);
|
|
return {
|
|
key: key,
|
|
type: type
|
|
};
|
|
}
|
|
function consumeObject(tokens){
|
|
var properties, that;
|
|
properties = [];
|
|
consumeOp(tokens, '{');
|
|
while (that = consumeProperty(tokens)) {
|
|
properties.push(that);
|
|
if (!maybeConsumeOp(tokens, ',')) {
|
|
break;
|
|
}
|
|
}
|
|
consumeOp(tokens, '}');
|
|
return {
|
|
type: 'Object',
|
|
properties: properties
|
|
};
|
|
}
|
|
function consumeType(tokens){
|
|
switch (tokens[0]) {
|
|
case '[':
|
|
return consumeArray(tokens);
|
|
case '{':
|
|
return consumeObject(tokens);
|
|
case '(':
|
|
return consumeTuple(tokens);
|
|
default:
|
|
return {
|
|
type: consumeWord(tokens)
|
|
};
|
|
}
|
|
}
|
|
function consumeMaybe(tokens){
|
|
var maybe, type;
|
|
if (tokens[0] === 'Maybe') {
|
|
tokens.shift();
|
|
maybe = true;
|
|
}
|
|
type = consumeType(tokens);
|
|
if (maybe) {
|
|
return {
|
|
type: 'Maybe',
|
|
contentType: type
|
|
};
|
|
} else {
|
|
return type;
|
|
}
|
|
}
|
|
function consumeTypes(tokens){
|
|
var types;
|
|
types = [];
|
|
for (;;) {
|
|
types.push(consumeMaybe(tokens));
|
|
if (!maybeConsumeOp('|')) {
|
|
break;
|
|
}
|
|
}
|
|
if (!types.length) {
|
|
throw new Error("Expected type(s).");
|
|
}
|
|
return types;
|
|
}
|
|
tokenRegex = /[:,\[\]\(\)}{]|[a-zA-Z]+/g;
|
|
module.exports = function(input){
|
|
var tokens, e;
|
|
tokens = reject(function(it){
|
|
return /^\s*$/.test(it);
|
|
})(
|
|
input.match(tokenRegex));
|
|
try {
|
|
return consumeTypes(tokens);
|
|
} catch (e$) {
|
|
e = e$;
|
|
throw new Error(e.message + " - '" + tokens.join('#') + "' - '" + input + "'");
|
|
}
|
|
};
|
|
}).call(this);
|