// 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);