UNPKG

ti-el

Version:
4,419 lines 104 kB
/*
 * Generated by PEG.js 0.10.0.
 *
 * http://pegjs.org/
 */
"use strict";

function peg$subclass(child, parent) {
  function ctor() {
    this.constructor = child;
  }

  ctor.prototype = parent.prototype;
  child.prototype = new ctor();
}

function peg$SyntaxError(message, expected, found, location) {
  this.message = message;
  this.expected = expected;
  this.found = found;
  this.location = location;
  this.name = "SyntaxError";

  if (typeof Error.captureStackTrace === "function") {
    Error.captureStackTrace(this, peg$SyntaxError);
  }
}

peg$subclass(peg$SyntaxError, Error);

peg$SyntaxError.buildMessage = function (expected, found) {
  var DESCRIBE_EXPECTATION_FNS = {
    literal: function (expectation) {
      return "\"" + literalEscape(expectation.text) + "\"";
    },
    "class": function (expectation) {
      var escapedParts = "",
          i;

      for (i = 0; i < expectation.parts.length; i++) {
        escapedParts += expectation.parts[i] instanceof Array ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) : classEscape(expectation.parts[i]);
      }

      return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
    },
    any: function (expectation) {
      return "any character";
    },
    end: function (expectation) {
      return "end of input";
    },
    other: function (expectation) {
      return expectation.description;
    }
  };

  function hex(ch) {
    return ch.charCodeAt(0).toString(16).toUpperCase();
  }

  function literalEscape(s) {
    return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\0/g, '\\0').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/[\x00-\x0F]/g, function (ch) {
      return '\\x0' + hex(ch);
    }).replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) {
      return '\\x' + hex(ch);
    });
  }

  function classEscape(s) {
    return s.replace(/\\/g, '\\\\').replace(/\]/g, '\\]').replace(/\^/g, '\\^').replace(/-/g, '\\-').replace(/\0/g, '\\0').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/[\x00-\x0F]/g, function (ch) {
      return '\\x0' + hex(ch);
    }).replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) {
      return '\\x' + hex(ch);
    });
  }

  function describeExpectation(expectation) {
    return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
  }

  function describeExpected(expected) {
    var descriptions = new Array(expected.length),
        i,
        j;

    for (i = 0; i < expected.length; i++) {
      descriptions[i] = describeExpectation(expected[i]);
    }

    descriptions.sort();

    if (descriptions.length > 0) {
      for (i = 1, j = 1; i < descriptions.length; i++) {
        if (descriptions[i - 1] !== descriptions[i]) {
          descriptions[j] = descriptions[i];
          j++;
        }
      }

      descriptions.length = j;
    }

    switch (descriptions.length) {
      case 1:
        return descriptions[0];

      case 2:
        return descriptions[0] + " or " + descriptions[1];

      default:
        return descriptions.slice(0, -1).join(", ") + ", or " + descriptions[descriptions.length - 1];
    }
  }

  function describeFound(found) {
    return found ? "\"" + literalEscape(found) + "\"" : "end of input";
  }

  return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
};

function peg$parse(input, options) {
  options = options !== void 0 ? options : {};

  var peg$FAILED = {},
      peg$startRuleFunctions = {
    Start: peg$parseStart
  },
      peg$startRuleFunction = peg$parseStart,
      peg$c0 = function (program) {
    return program;
  },
      peg$c1 = /^[a-z]/,
      peg$c2 = peg$classExpectation([["a", "z"]], false, false),
      peg$c3 = function (letter) {
    return letter;
  },
      peg$c4 = /^[A-Z]/,
      peg$c5 = peg$classExpectation([["A", "Z"]], false, false),
      peg$c6 = /^[0-9]/,
      peg$c7 = peg$classExpectation([["0", "9"]], false, false),
      peg$c8 = function (digit) {
    return Number(digit);
  },
      peg$c9 = /^[0-9a-f]/,
      peg$c10 = peg$classExpectation([["0", "9"], ["a", "f"]], false, false),
      peg$c11 = function (hexDigit) {
    return hexDigit;
  },
      peg$c12 = "_",
      peg$c13 = peg$literalExpectation("_", false),
      peg$c14 = function () {
    return text();
  },
      peg$c15 = ".",
      peg$c16 = peg$literalExpectation(".", false),
      peg$c17 = "#",
      peg$c18 = peg$literalExpectation("#", false),
      peg$c19 = "Final",
      peg$c20 = peg$literalExpectation("Final", false),
      peg$c21 = "New",
      peg$c22 = peg$literalExpectation("New", false),
      peg$c23 = "Empty",
      peg$c24 = peg$literalExpectation("Empty", false),
      peg$c25 = function () {
    return Number(text());
  },
      peg$c26 = "---",
      peg$c27 = peg$literalExpectation("---", false),
      peg$c28 = "functions",
      peg$c29 = peg$literalExpectation("functions", false),
      peg$c30 = "types",
      peg$c31 = peg$literalExpectation("types", false),
      peg$c32 = function (head, tail) {
    const declarations = extractLast(tail);
    const constructors = makeDeclarationsNode('ConstructorDeclarations', declarations, head.declarations);
    const functions = makeDeclarationsNode('FunctionDeclarations', declarations);
    return makeNode('TLProgram', {
      constructors,
      functions
    });
  },
      peg$c33 = function (decls) {
    return makeNode('ConstructorDeclarations', {
      declarations: extractFirst(decls)
    });
  },
      peg$c34 = function (decls) {
    return makeNode('FunctionDeclarations', {
      declarations: extractFirst(decls)
    });
  },
      peg$c35 = function (value) {
    return makeNode('ENat', {
      value
    });
  },
      peg$c36 = function (subexprs) {
    return makeNode('EExpression', {
      subexpressions: extractLast(subexprs)
    });
  },
      peg$c37 = "+",
      peg$c38 = peg$literalExpectation("+", false),
      peg$c39 = function (natexpr, subexpr) {
    return makeNode('EOperator', {
      kind: '+',
      expression: makeNode('EExpression', {
        subexpressions: [natexpr, subexpr]
      })
    });
  },
      peg$c40 = function (id) {
    return makeNode('ETypeIdentifier', {
      id
    });
  },
      peg$c41 = "(",
      peg$c42 = peg$literalExpectation("(", false),
      peg$c43 = ")",
      peg$c44 = peg$literalExpectation(")", false),
      peg$c45 = function (expr) {
    return expr;
  },
      peg$c46 = "<",
      peg$c47 = peg$literalExpectation("<", false),
      peg$c48 = ",",
      peg$c49 = peg$literalExpectation(",", false),
      peg$c50 = ">",
      peg$c51 = peg$literalExpectation(">", false),
      peg$c52 = function (id, head, tail) {
    return makeNode('EExpression', {
      subexpressions: [id, head].concat(extractLast(tail))
    });
  },
      peg$c53 = "%",
      peg$c54 = peg$literalExpectation("%", false),
      peg$c55 = function (terms) {
    const subexpressions = extractLast(terms);
    return makeNode('EOperator', {
      kind: '%',
      expression: subexpressions.length > 1 ? makeNode('EExpression', {
        subexpressions
      }) : subexpressions[0]
    });
  },
      peg$c56 = function (name) {
    return makeNode('SimpleTypeIdentifier', {
      name
    });
  },
      peg$c57 = function (name) {
    return makeNode('HashTypeIdentifier', {
      name
    });
  },
      peg$c58 = function (name) {
    return makeNode('BoxedTypeIdentifier', {
      name
    });
  },
      peg$c59 = function (name) {
    return makeNode('VariableIdentifier', {
      name
    });
  },
      peg$c60 = "!",
      peg$c61 = peg$literalExpectation("!", false),
      peg$c62 = function (bang, expr) {
    const expression = bang === '!' ? makeNode('EOperator', {
      kind: '!',
      expression: expr
    }) : expr;
    return makeNode('TypeExpression', {
      expression
    });
  },
      peg$c63 = function (expression) {
    return makeNode('NatExpression', {
      expression
    });
  },
      peg$c64 = function (ident) {
    const [name, magic] = ident.split('#');
    if (!magic) return makeNode('ShortCombinatorName', {
      name
    });
    return makeNode('FullCombinatorName', {
      name,
      magic
    });
  },
      peg$c65 = function (name) {
    return makeNode('ShortCombinatorName', {
      name
    });
  },
      peg$c66 = function (name) {
    return makeNode('EmptyCombinatorName', {
      name
    });
  },
      peg$c67 = function (name) {
    return makeNode('EmptyVariableIdentifier', {
      name
    });
  },
      peg$c68 = "=",
      peg$c69 = peg$literalExpectation("=", false),
      peg$c70 = ";",
      peg$c71 = peg$literalExpectation(";", false),
      peg$c72 = function (id, optionalArgs, args, excl, resultType) {
    return makeNode('CombinatorDeclaration', {
      id,
      optionalArgs: [].concat(...extractFirst(optionalArgs)),
      args: [].concat(...extractFirst(args)),
      bang: excl === "!",
      resultType
    });
  },
      peg$c73 = "{",
      peg$c74 = peg$literalExpectation("{", false),
      peg$c75 = ":",
      peg$c76 = peg$literalExpectation(":", false),
      peg$c77 = "}",
      peg$c78 = peg$literalExpectation("}", false),
      peg$c79 = function (ids, argType) {
    return extractLast(ids).map(id => makeNode('OptionalArgument', {
      id,
      argType
    }));
  },
      peg$c80 = "*",
      peg$c81 = peg$literalExpectation("*", false),
      peg$c82 = "[",
      peg$c83 = peg$literalExpectation("[", false),
      peg$c84 = "]",
      peg$c85 = peg$literalExpectation("]", false),
      peg$c86 = function (idOrNull, mult, subargs) {
    const id = safeFirst(idOrNull) || makeNode('EmptyVariableIdentifier', {
      name: '_'
    });
    const argType = makeNode('TypeExpression', {
      expression: makeNode('EMultiArg', {
        multiplicity: safeFirst(mult),
        subargs: [].concat(...extractLast(subargs))
      })
    });
    return [makeNode('Argument', {
      id,
      conditionalDef: null,
      argType
    })];
  },
      peg$c87 = function (id, cond, argType) {
    return [makeNode('Argument', {
      id,
      conditionalDef: cond,
      argType
    })];
  },
      peg$c88 = function (ids, argType) {
    return extractLast(ids).map(id => makeNode('Argument', {
      id,
      conditionalDef: null,
      argType
    }));
  },
      peg$c89 = function (argType) {
    return [makeNode('Argument', {
      id: makeNode('EmptyVariableIdentifier', {
        name: '_'
      }),
      conditionalDef: null,
      argType
    })];
  },
      peg$c90 = "?",
      peg$c91 = peg$literalExpectation("?", false),
      peg$c92 = function (id, nat) {
    return makeNode('ConditionalDefinition', {
      id,
      nat: safeLast(nat)
    });
  },
      peg$c93 = function (id, head, tail) {
    return makeNode('ResultType', {
      id,
      expression: makeNode('EExpression', {
        subexpressions: [head].concat(extractLast(tail))
      })
    });
  },
      peg$c94 = function (id, subexprs) {
    return makeNode('ResultType', {
      id,
      expression: makeNode('EExpression', {
        subexpressions: extractLast(subexprs)
      })
    });
  },
      peg$c95 = function (id, result) {
    return makeNode('BuiltinCombinatorDeclaration', {
      id,
      result
    });
  },
      peg$c96 = function (id, head, tail) {
    return makeNode('PartialTypeApplicationDeclaration', {
      id,
      expression: makeNode('EExpression', {
        subexpressions: [head].concat(extractLast(tail))
      })
    });
  },
      peg$c97 = function (id, subexprs) {
    return makeNode('PartialTypeApplicationDeclaration', {
      id,
      expression: makeNode('EExpression', {
        subexpressions: extractLast(subexprs)
      })
    });
  },
      peg$c98 = function (id, subexprs) {
    return makeNode('PartialCombinatorApplicationDeclaration', {
      id,
      expression: makeNode('EExpression', {
        subexpressions: extractLast(subexprs)
      })
    });
  },
      peg$c99 = function (ident) {
    return makeFinalDecl('New', ident);
  },
      peg$c100 = function (ident) {
    return makeFinalDecl('Final', ident);
  },
      peg$c101 = function (ident) {
    return makeFinalDecl('Empty', ident);
  },
      peg$c102 = "//",
      peg$c103 = peg$literalExpectation("//", false),
      peg$c104 = /^[^\r\n]/,
      peg$c105 = peg$classExpectation(["\r", "\n"], true, false),
      peg$c106 = /^[\r\n]/,
      peg$c107 = peg$classExpectation(["\r", "\n"], false, false),
      peg$c108 = peg$otherExpectation("whitespace"),
      peg$c109 = " ",
      peg$c110 = peg$literalExpectation(" ", false),
      peg$c111 = "\t",
      peg$c112 = peg$literalExpectation("\t", false),
      peg$c113 = "\r",
      peg$c114 = peg$literalExpectation("\r", false),
      peg$c115 = "\n",
      peg$c116 = peg$literalExpectation("\n", false),
      peg$c117 = peg$otherExpectation("skip whitespace and comments"),
      peg$c118 = peg$anyExpectation(),
      peg$currPos = 0,
      peg$savedPos = 0,
      peg$posDetailsCache = [{
    line: 1,
    column: 1
  }],
      peg$maxFailPos = 0,
      peg$maxFailExpected = [],
      peg$silentFails = 0,
      peg$result;

  if ("startRule" in options) {
    if (!(options.startRule in peg$startRuleFunctions)) {
      throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
    }

    peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
  }

  function text() {
    return input.substring(peg$savedPos, peg$currPos);
  }

  function location() {
    return peg$computeLocation(peg$savedPos, peg$currPos);
  }

  function expected(description, location) {
    location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos);
    throw peg$buildStructuredError([peg$otherExpectation(description)], input.substring(peg$savedPos, peg$currPos), location);
  }

  function error(message, location) {
    location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos);
    throw peg$buildSimpleError(message, location);
  }

  function peg$literalExpectation(text, ignoreCase) {
    return {
      type: "literal",
      text: text,
      ignoreCase: ignoreCase
    };
  }

  function peg$classExpectation(parts, inverted, ignoreCase) {
    return {
      type: "class",
      parts: parts,
      inverted: inverted,
      ignoreCase: ignoreCase
    };
  }

  function peg$anyExpectation() {
    return {
      type: "any"
    };
  }

  function peg$endExpectation() {
    return {
      type: "end"
    };
  }

  function peg$otherExpectation(description) {
    return {
      type: "other",
      description: description
    };
  }

  function peg$computePosDetails(pos) {
    var details = peg$posDetailsCache[pos],
        p;

    if (details) {
      return details;
    } else {
      p = pos - 1;

      while (!peg$posDetailsCache[p]) {
        p--;
      }

      details = peg$posDetailsCache[p];
      details = {
        line: details.line,
        column: details.column
      };

      while (p < pos) {
        if (input.charCodeAt(p) === 10) {
          details.line++;
          details.column = 1;
        } else {
          details.column++;
        }

        p++;
      }

      peg$posDetailsCache[pos] = details;
      return details;
    }
  }

  function peg$computeLocation(startPos, endPos) {
    var startPosDetails = peg$computePosDetails(startPos),
        endPosDetails = peg$computePosDetails(endPos);
    return {
      start: {
        offset: startPos,
        line: startPosDetails.line,
        column: startPosDetails.column
      },
      end: {
        offset: endPos,
        line: endPosDetails.line,
        column: endPosDetails.column
      }
    };
  }

  function peg$fail(expected) {
    if (peg$currPos < peg$maxFailPos) {
      return;
    }

    if (peg$currPos > peg$maxFailPos) {
      peg$maxFailPos = peg$currPos;
      peg$maxFailExpected = [];
    }

    peg$maxFailExpected.push(expected);
  }

  function peg$buildSimpleError(message, location) {
    return new peg$SyntaxError(message, null, null, location);
  }

  function peg$buildStructuredError(expected, found, location) {
    return new peg$SyntaxError(peg$SyntaxError.buildMessage(expected, found), expected, found, location);
  }

  function peg$parseStart() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;
    s1 = peg$parse__();

    if (s1 !== peg$FAILED) {
      s2 = peg$parseTLProgram();

      if (s2 !== peg$FAILED) {
        s3 = peg$parse__();

        if (s3 !== peg$FAILED) {
          peg$savedPos = s0;
          s1 = peg$c0(s2);
          s0 = s1;
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseLcLetter() {
    var s0, s1;
    s0 = peg$currPos;

    if (peg$c1.test(input.charAt(peg$currPos))) {
      s1 = input.charAt(peg$currPos);
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c2);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c3(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseUcLetter() {
    var s0, s1;
    s0 = peg$currPos;

    if (peg$c4.test(input.charAt(peg$currPos))) {
      s1 = input.charAt(peg$currPos);
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c5);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c3(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseDigit() {
    var s0, s1;
    s0 = peg$currPos;

    if (peg$c6.test(input.charAt(peg$currPos))) {
      s1 = input.charAt(peg$currPos);
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c7);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c8(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseHexDigit() {
    var s0, s1;
    s0 = peg$currPos;

    if (peg$c9.test(input.charAt(peg$currPos))) {
      s1 = input.charAt(peg$currPos);
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c10);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c11(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseLetter() {
    var s0;
    s0 = peg$parseLcLetter();

    if (s0 === peg$FAILED) {
      s0 = peg$parseUcLetter();
    }

    return s0;
  }

  function peg$parseIdentChar() {
    var s0;
    s0 = peg$parseLetter();

    if (s0 === peg$FAILED) {
      s0 = peg$parseDigit();

      if (s0 === peg$FAILED) {
        if (input.charCodeAt(peg$currPos) === 95) {
          s0 = peg$c12;
          peg$currPos++;
        } else {
          s0 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c13);
          }
        }
      }
    }

    return s0;
  }

  function peg$parseLcIdent() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;
    s1 = peg$parseLcLetter();

    if (s1 !== peg$FAILED) {
      s2 = [];
      s3 = peg$parseIdentChar();

      while (s3 !== peg$FAILED) {
        s2.push(s3);
        s3 = peg$parseIdentChar();
      }

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c14();
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseUcIdent() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;
    s1 = peg$parseUcLetter();

    if (s1 !== peg$FAILED) {
      s2 = [];
      s3 = peg$parseIdentChar();

      while (s3 !== peg$FAILED) {
        s2.push(s3);
        s3 = peg$parseIdentChar();
      }

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c14();
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseLcIdentNs() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;
    s1 = peg$currPos;
    s2 = peg$parseLcIdent();

    if (s2 !== peg$FAILED) {
      if (input.charCodeAt(peg$currPos) === 46) {
        s3 = peg$c15;
        peg$currPos++;
      } else {
        s3 = peg$FAILED;

        if (peg$silentFails === 0) {
          peg$fail(peg$c16);
        }
      }

      if (s3 !== peg$FAILED) {
        s2 = [s2, s3];
        s1 = s2;
      } else {
        peg$currPos = s1;
        s1 = peg$FAILED;
      }
    } else {
      peg$currPos = s1;
      s1 = peg$FAILED;
    }

    if (s1 === peg$FAILED) {
      s1 = null;
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$parseLcIdent();

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c14();
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseUcIdentNs() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;
    s1 = peg$currPos;
    s2 = peg$parseLcIdent();

    if (s2 !== peg$FAILED) {
      if (input.charCodeAt(peg$currPos) === 46) {
        s3 = peg$c15;
        peg$currPos++;
      } else {
        s3 = peg$FAILED;

        if (peg$silentFails === 0) {
          peg$fail(peg$c16);
        }
      }

      if (s3 !== peg$FAILED) {
        s2 = [s2, s3];
        s1 = s2;
      } else {
        peg$currPos = s1;
        s1 = peg$FAILED;
      }
    } else {
      peg$currPos = s1;
      s1 = peg$FAILED;
    }

    if (s1 === peg$FAILED) {
      s1 = null;
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$parseUcIdent();

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c14();
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseLcIdentFull() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
    s0 = peg$currPos;
    s1 = peg$parseLcIdentNs();

    if (s1 !== peg$FAILED) {
      s2 = peg$currPos;

      if (input.charCodeAt(peg$currPos) === 35) {
        s3 = peg$c17;
        peg$currPos++;
      } else {
        s3 = peg$FAILED;

        if (peg$silentFails === 0) {
          peg$fail(peg$c18);
        }
      }

      if (s3 !== peg$FAILED) {
        s4 = peg$parseHexDigit();

        if (s4 !== peg$FAILED) {
          s5 = peg$parseHexDigit();

          if (s5 !== peg$FAILED) {
            s6 = peg$parseHexDigit();

            if (s6 !== peg$FAILED) {
              s7 = peg$parseHexDigit();

              if (s7 !== peg$FAILED) {
                s8 = peg$parseHexDigit();

                if (s8 === peg$FAILED) {
                  s8 = null;
                }

                if (s8 !== peg$FAILED) {
                  s9 = peg$parseHexDigit();

                  if (s9 === peg$FAILED) {
                    s9 = null;
                  }

                  if (s9 !== peg$FAILED) {
                    s10 = peg$parseHexDigit();

                    if (s10 === peg$FAILED) {
                      s10 = null;
                    }

                    if (s10 !== peg$FAILED) {
                      s11 = peg$parseHexDigit();

                      if (s11 === peg$FAILED) {
                        s11 = null;
                      }

                      if (s11 !== peg$FAILED) {
                        s3 = [s3, s4, s5, s6, s7, s8, s9, s10, s11];
                        s2 = s3;
                      } else {
                        peg$currPos = s2;
                        s2 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s2;
                      s2 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s2;
                    s2 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s2;
                  s2 = peg$FAILED;
                }
              } else {
                peg$currPos = s2;
                s2 = peg$FAILED;
              }
            } else {
              peg$currPos = s2;
              s2 = peg$FAILED;
            }
          } else {
            peg$currPos = s2;
            s2 = peg$FAILED;
          }
        } else {
          peg$currPos = s2;
          s2 = peg$FAILED;
        }
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }

      if (s2 === peg$FAILED) {
        s2 = null;
      }

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c14();
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseFinalKw() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;

    if (input.substr(peg$currPos, 5) === peg$c19) {
      s1 = peg$c19;
      peg$currPos += 5;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c20);
      }
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$currPos;
      peg$silentFails++;
      s3 = peg$parseIdentChar();
      peg$silentFails--;

      if (s3 === peg$FAILED) {
        s2 = void 0;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }

      if (s2 !== peg$FAILED) {
        s1 = [s1, s2];
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseNewKw() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;

    if (input.substr(peg$currPos, 3) === peg$c21) {
      s1 = peg$c21;
      peg$currPos += 3;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c22);
      }
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$currPos;
      peg$silentFails++;
      s3 = peg$parseIdentChar();
      peg$silentFails--;

      if (s3 === peg$FAILED) {
        s2 = void 0;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }

      if (s2 !== peg$FAILED) {
        s1 = [s1, s2];
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseEmptyKw() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;

    if (input.substr(peg$currPos, 5) === peg$c23) {
      s1 = peg$c23;
      peg$currPos += 5;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c24);
      }
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$currPos;
      peg$silentFails++;
      s3 = peg$parseIdentChar();
      peg$silentFails--;

      if (s3 === peg$FAILED) {
        s2 = void 0;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }

      if (s2 !== peg$FAILED) {
        s1 = [s1, s2];
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseNatConst() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;
    s1 = [];
    s2 = peg$parseDigit();

    if (s2 !== peg$FAILED) {
      while (s2 !== peg$FAILED) {
        s1.push(s2);
        s2 = peg$parseDigit();
      }
    } else {
      s1 = peg$FAILED;
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$currPos;
      peg$silentFails++;
      s3 = peg$parseIdentChar();
      peg$silentFails--;

      if (s3 === peg$FAILED) {
        s2 = void 0;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c25();
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseTLProgram() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
    s0 = peg$currPos;
    s1 = peg$parseConstrDeclarations();

    if (s1 !== peg$FAILED) {
      s2 = [];
      s3 = peg$currPos;
      s4 = peg$parse__();

      if (s4 !== peg$FAILED) {
        if (input.substr(peg$currPos, 3) === peg$c26) {
          s5 = peg$c26;
          peg$currPos += 3;
        } else {
          s5 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c27);
          }
        }

        if (s5 !== peg$FAILED) {
          if (input.substr(peg$currPos, 9) === peg$c28) {
            s6 = peg$c28;
            peg$currPos += 9;
          } else {
            s6 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c29);
            }
          }

          if (s6 !== peg$FAILED) {
            if (input.substr(peg$currPos, 3) === peg$c26) {
              s7 = peg$c26;
              peg$currPos += 3;
            } else {
              s7 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c27);
              }
            }

            if (s7 !== peg$FAILED) {
              s8 = peg$parse__();

              if (s8 !== peg$FAILED) {
                s9 = peg$parseFunDeclarations();

                if (s9 !== peg$FAILED) {
                  s4 = [s4, s5, s6, s7, s8, s9];
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }
      } else {
        peg$currPos = s3;
        s3 = peg$FAILED;
      }

      if (s3 === peg$FAILED) {
        s3 = peg$currPos;
        s4 = peg$parse__();

        if (s4 !== peg$FAILED) {
          if (input.substr(peg$currPos, 3) === peg$c26) {
            s5 = peg$c26;
            peg$currPos += 3;
          } else {
            s5 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c27);
            }
          }

          if (s5 !== peg$FAILED) {
            if (input.substr(peg$currPos, 5) === peg$c30) {
              s6 = peg$c30;
              peg$currPos += 5;
            } else {
              s6 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c31);
              }
            }

            if (s6 !== peg$FAILED) {
              if (input.substr(peg$currPos, 3) === peg$c26) {
                s7 = peg$c26;
                peg$currPos += 3;
              } else {
                s7 = peg$FAILED;

                if (peg$silentFails === 0) {
                  peg$fail(peg$c27);
                }
              }

              if (s7 !== peg$FAILED) {
                s8 = peg$parse__();

                if (s8 !== peg$FAILED) {
                  s9 = peg$parseConstrDeclarations();

                  if (s9 !== peg$FAILED) {
                    s4 = [s4, s5, s6, s7, s8, s9];
                    s3 = s4;
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }
      }

      while (s3 !== peg$FAILED) {
        s2.push(s3);
        s3 = peg$currPos;
        s4 = peg$parse__();

        if (s4 !== peg$FAILED) {
          if (input.substr(peg$currPos, 3) === peg$c26) {
            s5 = peg$c26;
            peg$currPos += 3;
          } else {
            s5 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c27);
            }
          }

          if (s5 !== peg$FAILED) {
            if (input.substr(peg$currPos, 9) === peg$c28) {
              s6 = peg$c28;
              peg$currPos += 9;
            } else {
              s6 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c29);
              }
            }

            if (s6 !== peg$FAILED) {
              if (input.substr(peg$currPos, 3) === peg$c26) {
                s7 = peg$c26;
                peg$currPos += 3;
              } else {
                s7 = peg$FAILED;

                if (peg$silentFails === 0) {
                  peg$fail(peg$c27);
                }
              }

              if (s7 !== peg$FAILED) {
                s8 = peg$parse__();

                if (s8 !== peg$FAILED) {
                  s9 = peg$parseFunDeclarations();

                  if (s9 !== peg$FAILED) {
                    s4 = [s4, s5, s6, s7, s8, s9];
                    s3 = s4;
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }

        if (s3 === peg$FAILED) {
          s3 = peg$currPos;
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            if (input.substr(peg$currPos, 3) === peg$c26) {
              s5 = peg$c26;
              peg$currPos += 3;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c27);
              }
            }

            if (s5 !== peg$FAILED) {
              if (input.substr(peg$currPos, 5) === peg$c30) {
                s6 = peg$c30;
                peg$currPos += 5;
              } else {
                s6 = peg$FAILED;

                if (peg$silentFails === 0) {
                  peg$fail(peg$c31);
                }
              }

              if (s6 !== peg$FAILED) {
                if (input.substr(peg$currPos, 3) === peg$c26) {
                  s7 = peg$c26;
                  peg$currPos += 3;
                } else {
                  s7 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c27);
                  }
                }

                if (s7 !== peg$FAILED) {
                  s8 = peg$parse__();

                  if (s8 !== peg$FAILED) {
                    s9 = peg$parseConstrDeclarations();

                    if (s9 !== peg$FAILED) {
                      s4 = [s4, s5, s6, s7, s8, s9];
                      s3 = s4;
                    } else {
                      peg$currPos = s3;
                      s3 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        }
      }

      if (s2 !== peg$FAILED) {
        peg$savedPos = s0;
        s1 = peg$c32(s1, s2);
        s0 = s1;
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseConstrDeclarations() {
    var s0, s1, s2, s3, s4;
    s0 = peg$currPos;
    s1 = [];
    s2 = peg$currPos;
    s3 = peg$parseDeclaration();

    if (s3 !== peg$FAILED) {
      s4 = peg$parse__();

      if (s4 !== peg$FAILED) {
        s3 = [s3, s4];
        s2 = s3;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }
    } else {
      peg$currPos = s2;
      s2 = peg$FAILED;
    }

    while (s2 !== peg$FAILED) {
      s1.push(s2);
      s2 = peg$currPos;
      s3 = peg$parseDeclaration();

      if (s3 !== peg$FAILED) {
        s4 = peg$parse__();

        if (s4 !== peg$FAILED) {
          s3 = [s3, s4];
          s2 = s3;
        } else {
          peg$currPos = s2;
          s2 = peg$FAILED;
        }
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c33(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseFunDeclarations() {
    var s0, s1, s2, s3, s4;
    s0 = peg$currPos;
    s1 = [];
    s2 = peg$currPos;
    s3 = peg$parseDeclaration();

    if (s3 !== peg$FAILED) {
      s4 = peg$parse__();

      if (s4 !== peg$FAILED) {
        s3 = [s3, s4];
        s2 = s3;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }
    } else {
      peg$currPos = s2;
      s2 = peg$FAILED;
    }

    while (s2 !== peg$FAILED) {
      s1.push(s2);
      s2 = peg$currPos;
      s3 = peg$parseDeclaration();

      if (s3 !== peg$FAILED) {
        s4 = peg$parse__();

        if (s4 !== peg$FAILED) {
          s3 = [s3, s4];
          s2 = s3;
        } else {
          peg$currPos = s2;
          s2 = peg$FAILED;
        }
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c34(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseDeclaration() {
    var s0;
    s0 = peg$parseFinalDecl();

    if (s0 === peg$FAILED) {
      s0 = peg$parseCombinatorDecl();

      if (s0 === peg$FAILED) {
        s0 = peg$parseBuiltinCombinatorDecl();

        if (s0 === peg$FAILED) {
          s0 = peg$parsePartialAppDecl();
        }
      }
    }

    return s0;
  }

  function peg$parseENat() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseNatConst();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c35(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseExpr() {
    var s0, s1, s2, s3, s4;
    s0 = peg$currPos;
    s1 = [];
    s2 = peg$currPos;
    s3 = peg$parse__();

    if (s3 !== peg$FAILED) {
      s4 = peg$parseSubexpr();

      if (s4 !== peg$FAILED) {
        s3 = [s3, s4];
        s2 = s3;
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }
    } else {
      peg$currPos = s2;
      s2 = peg$FAILED;
    }

    while (s2 !== peg$FAILED) {
      s1.push(s2);
      s2 = peg$currPos;
      s3 = peg$parse__();

      if (s3 !== peg$FAILED) {
        s4 = peg$parseSubexpr();

        if (s4 !== peg$FAILED) {
          s3 = [s3, s4];
          s2 = s3;
        } else {
          peg$currPos = s2;
          s2 = peg$FAILED;
        }
      } else {
        peg$currPos = s2;
        s2 = peg$FAILED;
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c36(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseSubexpr() {
    var s0, s1, s2, s3, s4, s5;
    s0 = peg$parseTerm();

    if (s0 === peg$FAILED) {
      s0 = peg$currPos;
      s1 = peg$parseENat();

      if (s1 !== peg$FAILED) {
        s2 = peg$parse__();

        if (s2 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 43) {
            s3 = peg$c37;
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c38);
            }
          }

          if (s3 !== peg$FAILED) {
            s4 = peg$parse__();

            if (s4 !== peg$FAILED) {
              s5 = peg$parseSubexpr();

              if (s5 !== peg$FAILED) {
                peg$savedPos = s0;
                s1 = peg$c39(s1, s5);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    }

    return s0;
  }

  function peg$parseETypeIdent() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseTypeIdent();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c40(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseTerm() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
    s0 = peg$currPos;

    if (input.charCodeAt(peg$currPos) === 40) {
      s1 = peg$c41;
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c42);
      }
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        s3 = peg$parseExpr();

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 41) {
              s5 = peg$c43;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c44);
              }
            }

            if (s5 !== peg$FAILED) {
              peg$savedPos = s0;
              s1 = peg$c45(s3);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    if (s0 === peg$FAILED) {
      s0 = peg$currPos;
      s1 = peg$parseETypeIdent();

      if (s1 !== peg$FAILED) {
        s2 = peg$parse__();

        if (s2 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 60) {
            s3 = peg$c46;
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c47);
            }
          }

          if (s3 !== peg$FAILED) {
            s4 = peg$parse__();

            if (s4 !== peg$FAILED) {
              s5 = peg$parseSubexpr();

              if (s5 !== peg$FAILED) {
                s6 = [];
                s7 = peg$currPos;
                s8 = peg$parse__();

                if (s8 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 44) {
                    s9 = peg$c48;
                    peg$currPos++;
                  } else {
                    s9 = peg$FAILED;

                    if (peg$silentFails === 0) {
                      peg$fail(peg$c49);
                    }
                  }

                  if (s9 !== peg$FAILED) {
                    s10 = peg$parse__();

                    if (s10 !== peg$FAILED) {
                      s11 = peg$parseSubexpr();

                      if (s11 !== peg$FAILED) {
                        s8 = [s8, s9, s10, s11];
                        s7 = s8;
                      } else {
                        peg$currPos = s7;
                        s7 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s7;
                      s7 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s7;
                    s7 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s7;
                  s7 = peg$FAILED;
                }

                while (s7 !== peg$FAILED) {
                  s6.push(s7);
                  s7 = peg$currPos;
                  s8 = peg$parse__();

                  if (s8 !== peg$FAILED) {
                    if (input.charCodeAt(peg$currPos) === 44) {
                      s9 = peg$c48;
                      peg$currPos++;
                    } else {
                      s9 = peg$FAILED;

                      if (peg$silentFails === 0) {
                        peg$fail(peg$c49);
                      }
                    }

                    if (s9 !== peg$FAILED) {
                      s10 = peg$parse__();

                      if (s10 !== peg$FAILED) {
                        s11 = peg$parseSubexpr();

                        if (s11 !== peg$FAILED) {
                          s8 = [s8, s9, s10, s11];
                          s7 = s8;
                        } else {
                          peg$currPos = s7;
                          s7 = peg$FAILED;
                        }
                      } else {
                        peg$currPos = s7;
                        s7 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s7;
                      s7 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s7;
                    s7 = peg$FAILED;
                  }
                }

                if (s6 !== peg$FAILED) {
                  s7 = peg$parse__();

                  if (s7 !== peg$FAILED) {
                    if (input.charCodeAt(peg$currPos) === 62) {
                      s8 = peg$c50;
                      peg$currPos++;
                    } else {
                      s8 = peg$FAILED;

                      if (peg$silentFails === 0) {
                        peg$fail(peg$c51);
                      }
                    }

                    if (s8 !== peg$FAILED) {
                      peg$savedPos = s0;
                      s1 = peg$c52(s1, s5, s6);
                      s0 = s1;
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }

      if (s0 === peg$FAILED) {
        s0 = peg$parseETypeIdent();

        if (s0 === peg$FAILED) {
          s0 = peg$parseENat();

          if (s0 === peg$FAILED) {
            s0 = peg$currPos;

            if (input.charCodeAt(peg$currPos) === 37) {
              s1 = peg$c53;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c54);
              }
            }

            if (s1 !== peg$FAILED) {
              s2 = [];
              s3 = peg$currPos;
              s4 = peg$parse__();

              if (s4 !== peg$FAILED) {
                s5 = peg$parseTerm();

                if (s5 !== peg$FAILED) {
                  s4 = [s4, s5];
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }

              if (s3 !== peg$FAILED) {
                while (s3 !== peg$FAILED) {
                  s2.push(s3);
                  s3 = peg$currPos;
                  s4 = peg$parse__();

                  if (s4 !== peg$FAILED) {
                    s5 = peg$parseTerm();

                    if (s5 !== peg$FAILED) {
                      s4 = [s4, s5];
                      s3 = s4;
                    } else {
                      peg$currPos = s3;
                      s3 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                }
              } else {
                s2 = peg$FAILED;
              }

              if (s2 !== peg$FAILED) {
                peg$savedPos = s0;
                s1 = peg$c55(s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          }
        }
      }
    }

    return s0;
  }

  function peg$parseSimpleTypeIdent() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseLcIdentNs();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c56(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseHashTypeIdent() {
    var s0, s1;
    s0 = peg$currPos;

    if (input.charCodeAt(peg$currPos) === 35) {
      s1 = peg$c17;
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c18);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c57(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseTypeIdent() {
    var s0;
    s0 = peg$parseBoxedTypeIdent();

    if (s0 === peg$FAILED) {
      s0 = peg$parseSimpleTypeIdent();

      if (s0 === peg$FAILED) {
        s0 = peg$parseHashTypeIdent();
      }
    }

    return s0;
  }

  function peg$parseBoxedTypeIdent() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseUcIdentNs();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c58(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseVarIdent() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseLcIdent();

    if (s1 === peg$FAILED) {
      s1 = peg$parseUcIdent();
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c59(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseTypeTerm() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;

    if (input.charCodeAt(peg$currPos) === 33) {
      s1 = peg$c60;
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c61);
      }
    }

    if (s1 === peg$FAILED) {
      s1 = null;
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        s3 = peg$parseTerm();

        if (s3 !== peg$FAILED) {
          peg$savedPos = s0;
          s1 = peg$c62(s1, s3);
          s0 = s1;
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseNatTerm() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseTerm();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c63(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseFullCombName() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseLcIdentFull();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c64(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseShortCombName() {
    var s0, s1;
    s0 = peg$currPos;
    s1 = peg$parseLcIdentNs();

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c65(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseEmptyCombName() {
    var s0, s1;
    s0 = peg$currPos;

    if (input.charCodeAt(peg$currPos) === 95) {
      s1 = peg$c12;
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c13);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c66(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseVarIdentEmpty() {
    var s0, s1;
    s0 = peg$currPos;

    if (input.charCodeAt(peg$currPos) === 95) {
      s1 = peg$c12;
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c13);
      }
    }

    if (s1 !== peg$FAILED) {
      peg$savedPos = s0;
      s1 = peg$c67(s1);
    }

    s0 = s1;
    return s0;
  }

  function peg$parseCombinatorDecl() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
    s0 = peg$currPos;
    s1 = peg$parseFullCombinatorId();

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        s3 = [];
        s4 = peg$currPos;
        s5 = peg$parseOptArgs();

        if (s5 !== peg$FAILED) {
          s6 = peg$parse__();

          if (s6 !== peg$FAILED) {
            s5 = [s5, s6];
            s4 = s5;
          } else {
            peg$currPos = s4;
            s4 = peg$FAILED;
          }
        } else {
          peg$currPos = s4;
          s4 = peg$FAILED;
        }

        while (s4 !== peg$FAILED) {
          s3.push(s4);
          s4 = peg$currPos;
          s5 = peg$parseOptArgs();

          if (s5 !== peg$FAILED) {
            s6 = peg$parse__();

            if (s6 !== peg$FAILED) {
              s5 = [s5, s6];
              s4 = s5;
            } else {
              peg$currPos = s4;
              s4 = peg$FAILED;
            }
          } else {
            peg$currPos = s4;
            s4 = peg$FAILED;
          }
        }

        if (s3 !== peg$FAILED) {
          s4 = [];
          s5 = peg$currPos;
          s6 = peg$parseArgs();

          if (s6 !== peg$FAILED) {
            s7 = peg$parse__();

            if (s7 !== peg$FAILED) {
              s6 = [s6, s7];
              s5 = s6;
            } else {
              peg$currPos = s5;
              s5 = peg$FAILED;
            }
          } else {
            peg$currPos = s5;
            s5 = peg$FAILED;
          }

          while (s5 !== peg$FAILED) {
            s4.push(s5);
            s5 = peg$currPos;
            s6 = peg$parseArgs();

            if (s6 !== peg$FAILED) {
              s7 = peg$parse__();

              if (s7 !== peg$FAILED) {
                s6 = [s6, s7];
                s5 = s6;
              } else {
                peg$currPos = s5;
                s5 = peg$FAILED;
              }
            } else {
              peg$currPos = s5;
              s5 = peg$FAILED;
            }
          }

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 61) {
              s5 = peg$c68;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c69);
              }
            }

            if (s5 !== peg$FAILED) {
              s6 = peg$parse__();

              if (s6 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 33) {
                  s7 = peg$c60;
                  peg$currPos++;
                } else {
                  s7 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c61);
                  }
                }

                if (s7 === peg$FAILED) {
                  s7 = null;
                }

                if (s7 !== peg$FAILED) {
                  s8 = peg$parse__();

                  if (s8 !== peg$FAILED) {
                    s9 = peg$parseResultType();

                    if (s9 !== peg$FAILED) {
                      s10 = peg$parse__();

                      if (s10 !== peg$FAILED) {
                        if (input.charCodeAt(peg$currPos) === 59) {
                          s11 = peg$c70;
                          peg$currPos++;
                        } else {
                          s11 = peg$FAILED;

                          if (peg$silentFails === 0) {
                            peg$fail(peg$c71);
                          }
                        }

                        if (s11 !== peg$FAILED) {
                          peg$savedPos = s0;
                          s1 = peg$c72(s1, s3, s4, s7, s9);
                          s0 = s1;
                        } else {
                          peg$currPos = s0;
                          s0 = peg$FAILED;
                        }
                      } else {
                        peg$currPos = s0;
                        s0 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseFullCombinatorId() {
    var s0;
    s0 = peg$parseFullCombName();

    if (s0 === peg$FAILED) {
      s0 = peg$parseEmptyCombName();
    }

    return s0;
  }

  function peg$parseCombinatorId() {
    var s0;
    s0 = peg$parseShortCombName();

    if (s0 === peg$FAILED) {
      s0 = peg$parseEmptyCombName();
    }

    return s0;
  }

  function peg$parseOptArgs() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8;
    s0 = peg$currPos;

    if (input.charCodeAt(peg$currPos) === 123) {
      s1 = peg$c73;
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c74);
      }
    }

    if (s1 !== peg$FAILED) {
      s2 = [];
      s3 = peg$currPos;
      s4 = peg$parse__();

      if (s4 !== peg$FAILED) {
        s5 = peg$parseVarIdent();

        if (s5 !== peg$FAILED) {
          s4 = [s4, s5];
          s3 = s4;
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }
      } else {
        peg$currPos = s3;
        s3 = peg$FAILED;
      }

      if (s3 !== peg$FAILED) {
        while (s3 !== peg$FAILED) {
          s2.push(s3);
          s3 = peg$currPos;
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            s5 = peg$parseVarIdent();

            if (s5 !== peg$FAILED) {
              s4 = [s4, s5];
              s3 = s4;
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        }
      } else {
        s2 = peg$FAILED;
      }

      if (s2 !== peg$FAILED) {
        s3 = peg$parse__();

        if (s3 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 58) {
            s4 = peg$c75;
            peg$currPos++;
          } else {
            s4 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c76);
            }
          }

          if (s4 !== peg$FAILED) {
            s5 = peg$parse__();

            if (s5 !== peg$FAILED) {
              s6 = peg$parseTypeTerm();

              if (s6 !== peg$FAILED) {
                s7 = peg$parse__();

                if (s7 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 125) {
                    s8 = peg$c77;
                    peg$currPos++;
                  } else {
                    s8 = peg$FAILED;

                    if (peg$silentFails === 0) {
                      peg$fail(peg$c78);
                    }
                  }

                  if (s8 !== peg$FAILED) {
                    peg$savedPos = s0;
                    s1 = peg$c79(s2, s6);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseArgs() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
    s0 = peg$currPos;
    s1 = peg$currPos;
    s2 = peg$parseVarIdentOpt();

    if (s2 !== peg$FAILED) {
      s3 = peg$parse__();

      if (s3 !== peg$FAILED) {
        if (input.charCodeAt(peg$currPos) === 58) {
          s4 = peg$c75;
          peg$currPos++;
        } else {
          s4 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c76);
          }
        }

        if (s4 !== peg$FAILED) {
          s2 = [s2, s3, s4];
          s1 = s2;
        } else {
          peg$currPos = s1;
          s1 = peg$FAILED;
        }
      } else {
        peg$currPos = s1;
        s1 = peg$FAILED;
      }
    } else {
      peg$currPos = s1;
      s1 = peg$FAILED;
    }

    if (s1 === peg$FAILED) {
      s1 = null;
    }

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        s3 = peg$currPos;
        s4 = peg$parseNatTerm();

        if (s4 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 42) {
            s5 = peg$c80;
            peg$currPos++;
          } else {
            s5 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c81);
            }
          }

          if (s5 !== peg$FAILED) {
            s4 = [s4, s5];
            s3 = s4;
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }

        if (s3 === peg$FAILED) {
          s3 = null;
        }

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 91) {
              s5 = peg$c82;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c83);
              }
            }

            if (s5 !== peg$FAILED) {
              s6 = peg$parse__();

              if (s6 !== peg$FAILED) {
                s7 = [];
                s8 = peg$currPos;
                s9 = peg$parse__();

                if (s9 !== peg$FAILED) {
                  s10 = peg$parseArgs();

                  if (s10 !== peg$FAILED) {
                    s9 = [s9, s10];
                    s8 = s9;
                  } else {
                    peg$currPos = s8;
                    s8 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s8;
                  s8 = peg$FAILED;
                }

                while (s8 !== peg$FAILED) {
                  s7.push(s8);
                  s8 = peg$currPos;
                  s9 = peg$parse__();

                  if (s9 !== peg$FAILED) {
                    s10 = peg$parseArgs();

                    if (s10 !== peg$FAILED) {
                      s9 = [s9, s10];
                      s8 = s9;
                    } else {
                      peg$currPos = s8;
                      s8 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s8;
                    s8 = peg$FAILED;
                  }
                }

                if (s7 !== peg$FAILED) {
                  s8 = peg$parse__();

                  if (s8 !== peg$FAILED) {
                    if (input.charCodeAt(peg$currPos) === 93) {
                      s9 = peg$c84;
                      peg$currPos++;
                    } else {
                      s9 = peg$FAILED;

                      if (peg$silentFails === 0) {
                        peg$fail(peg$c85);
                      }
                    }

                    if (s9 !== peg$FAILED) {
                      peg$savedPos = s0;
                      s1 = peg$c86(s1, s3, s7);
                      s0 = s1;
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    if (s0 === peg$FAILED) {
      s0 = peg$currPos;
      s1 = peg$parseVarIdentOpt();

      if (s1 !== peg$FAILED) {
        s2 = peg$parse__();

        if (s2 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 58) {
            s3 = peg$c75;
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c76);
            }
          }

          if (s3 !== peg$FAILED) {
            s4 = peg$parse__();

            if (s4 !== peg$FAILED) {
              s5 = peg$parseConditionalDef();

              if (s5 === peg$FAILED) {
                s5 = null;
              }

              if (s5 !== peg$FAILED) {
                s6 = peg$parse__();

                if (s6 !== peg$FAILED) {
                  s7 = peg$parseTypeTerm();

                  if (s7 !== peg$FAILED) {
                    peg$savedPos = s0;
                    s1 = peg$c87(s1, s5, s7);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }

      if (s0 === peg$FAILED) {
        s0 = peg$currPos;
        s1 = peg$parseVarIdentOpt();

        if (s1 !== peg$FAILED) {
          s2 = peg$parse__();

          if (s2 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 58) {
              s3 = peg$c75;
              peg$currPos++;
            } else {
              s3 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c76);
              }
            }

            if (s3 !== peg$FAILED) {
              s4 = peg$parse__();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 40) {
                  s5 = peg$c41;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c42);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s6 = peg$parse__();

                  if (s6 !== peg$FAILED) {
                    s7 = peg$parseConditionalDef();

                    if (s7 === peg$FAILED) {
                      s7 = null;
                    }

                    if (s7 !== peg$FAILED) {
                      s8 = peg$parse__();

                      if (s8 !== peg$FAILED) {
                        s9 = peg$parseTypeTerm();

                        if (s9 !== peg$FAILED) {
                          s10 = peg$parse__();

                          if (s10 !== peg$FAILED) {
                            if (input.charCodeAt(peg$currPos) === 41) {
                              s11 = peg$c43;
                              peg$currPos++;
                            } else {
                              s11 = peg$FAILED;

                              if (peg$silentFails === 0) {
                                peg$fail(peg$c44);
                              }
                            }

                            if (s11 !== peg$FAILED) {
                              peg$savedPos = s0;
                              s1 = peg$c87(s1, s7, s9);
                              s0 = s1;
                            } else {
                              peg$currPos = s0;
                              s0 = peg$FAILED;
                            }
                          } else {
                            peg$currPos = s0;
                            s0 = peg$FAILED;
                          }
                        } else {
                          peg$currPos = s0;
                          s0 = peg$FAILED;
                        }
                      } else {
                        peg$currPos = s0;
                        s0 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        if (s0 === peg$FAILED) {
          s0 = peg$currPos;

          if (input.charCodeAt(peg$currPos) === 40) {
            s1 = peg$c41;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c42);
            }
          }

          if (s1 !== peg$FAILED) {
            s2 = [];
            s3 = peg$currPos;
            s4 = peg$parse__();

            if (s4 !== peg$FAILED) {
              s5 = peg$parseVarIdentOpt();

              if (s5 !== peg$FAILED) {
                s4 = [s4, s5];
                s3 = s4;
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }

            if (s3 !== peg$FAILED) {
              while (s3 !== peg$FAILED) {
                s2.push(s3);
                s3 = peg$currPos;
                s4 = peg$parse__();

                if (s4 !== peg$FAILED) {
                  s5 = peg$parseVarIdentOpt();

                  if (s5 !== peg$FAILED) {
                    s4 = [s4, s5];
                    s3 = s4;
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              }
            } else {
              s2 = peg$FAILED;
            }

            if (s2 !== peg$FAILED) {
              s3 = peg$parse__();

              if (s3 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 58) {
                  s4 = peg$c75;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c76);
                  }
                }

                if (s4 !== peg$FAILED) {
                  s5 = peg$parse__();

                  if (s5 !== peg$FAILED) {
                    s6 = peg$parseTypeTerm();

                    if (s6 !== peg$FAILED) {
                      s7 = peg$parse__();

                      if (s7 !== peg$FAILED) {
                        if (input.charCodeAt(peg$currPos) === 41) {
                          s8 = peg$c43;
                          peg$currPos++;
                        } else {
                          s8 = peg$FAILED;

                          if (peg$silentFails === 0) {
                            peg$fail(peg$c44);
                          }
                        }

                        if (s8 !== peg$FAILED) {
                          peg$savedPos = s0;
                          s1 = peg$c88(s2, s6);
                          s0 = s1;
                        } else {
                          peg$currPos = s0;
                          s0 = peg$FAILED;
                        }
                      } else {
                        peg$currPos = s0;
                        s0 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }

          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = peg$parseTypeTerm();

            if (s1 !== peg$FAILED) {
              peg$savedPos = s0;
              s1 = peg$c89(s1);
            }

            s0 = s1;
          }
        }
      }
    }

    return s0;
  }

  function peg$parseVarIdentOpt() {
    var s0;
    s0 = peg$parseVarIdent();

    if (s0 === peg$FAILED) {
      s0 = peg$parseVarIdentEmpty();
    }

    return s0;
  }

  function peg$parseConditionalDef() {
    var s0, s1, s2, s3, s4, s5;
    s0 = peg$currPos;
    s1 = peg$parseVarIdent();

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        s3 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 46) {
          s4 = peg$c15;
          peg$currPos++;
        } else {
          s4 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c16);
          }
        }

        if (s4 !== peg$FAILED) {
          s5 = peg$parseNatConst();

          if (s5 !== peg$FAILED) {
            s4 = [s4, s5];
            s3 = s4;
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }

        if (s3 === peg$FAILED) {
          s3 = null;
        }

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 63) {
              s5 = peg$c90;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c91);
              }
            }

            if (s5 !== peg$FAILED) {
              peg$savedPos = s0;
              s1 = peg$c92(s1, s3);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseResultType() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
    s0 = peg$currPos;
    s1 = peg$parseBoxedTypeIdent();

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        if (input.charCodeAt(peg$currPos) === 60) {
          s3 = peg$c46;
          peg$currPos++;
        } else {
          s3 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c47);
          }
        }

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            s5 = peg$parseSubexpr();

            if (s5 !== peg$FAILED) {
              s6 = [];
              s7 = peg$currPos;
              s8 = peg$parse__();

              if (s8 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 44) {
                  s9 = peg$c48;
                  peg$currPos++;
                } else {
                  s9 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c49);
                  }
                }

                if (s9 !== peg$FAILED) {
                  s10 = peg$parse__();

                  if (s10 !== peg$FAILED) {
                    s11 = peg$parseSubexpr();

                    if (s11 !== peg$FAILED) {
                      s8 = [s8, s9, s10, s11];
                      s7 = s8;
                    } else {
                      peg$currPos = s7;
                      s7 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s7;
                    s7 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s7;
                  s7 = peg$FAILED;
                }
              } else {
                peg$currPos = s7;
                s7 = peg$FAILED;
              }

              while (s7 !== peg$FAILED) {
                s6.push(s7);
                s7 = peg$currPos;
                s8 = peg$parse__();

                if (s8 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 44) {
                    s9 = peg$c48;
                    peg$currPos++;
                  } else {
                    s9 = peg$FAILED;

                    if (peg$silentFails === 0) {
                      peg$fail(peg$c49);
                    }
                  }

                  if (s9 !== peg$FAILED) {
                    s10 = peg$parse__();

                    if (s10 !== peg$FAILED) {
                      s11 = peg$parseSubexpr();

                      if (s11 !== peg$FAILED) {
                        s8 = [s8, s9, s10, s11];
                        s7 = s8;
                      } else {
                        peg$currPos = s7;
                        s7 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s7;
                      s7 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s7;
                    s7 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s7;
                  s7 = peg$FAILED;
                }
              }

              if (s6 !== peg$FAILED) {
                s7 = peg$parse__();

                if (s7 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 62) {
                    s8 = peg$c50;
                    peg$currPos++;
                  } else {
                    s8 = peg$FAILED;

                    if (peg$silentFails === 0) {
                      peg$fail(peg$c51);
                    }
                  }

                  if (s8 !== peg$FAILED) {
                    peg$savedPos = s0;
                    s1 = peg$c93(s1, s5, s6);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    if (s0 === peg$FAILED) {
      s0 = peg$currPos;
      s1 = peg$parseBoxedTypeIdent();

      if (s1 !== peg$FAILED) {
        s2 = [];
        s3 = peg$currPos;
        s4 = peg$parse__();

        if (s4 !== peg$FAILED) {
          s5 = peg$parseSubexpr();

          if (s5 !== peg$FAILED) {
            s4 = [s4, s5];
            s3 = s4;
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }

        while (s3 !== peg$FAILED) {
          s2.push(s3);
          s3 = peg$currPos;
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            s5 = peg$parseSubexpr();

            if (s5 !== peg$FAILED) {
              s4 = [s4, s5];
              s3 = s4;
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        }

        if (s2 !== peg$FAILED) {
          peg$savedPos = s0;
          s1 = peg$c94(s1, s2);
          s0 = s1;
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    }

    return s0;
  }

  function peg$parseBuiltinCombinatorDecl() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
    s0 = peg$currPos;
    s1 = peg$parseFullCombinatorId();

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        if (input.charCodeAt(peg$currPos) === 63) {
          s3 = peg$c90;
          peg$currPos++;
        } else {
          s3 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c91);
          }
        }

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 61) {
              s5 = peg$c68;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c69);
              }
            }

            if (s5 !== peg$FAILED) {
              s6 = peg$parse__();

              if (s6 !== peg$FAILED) {
                s7 = peg$parseBoxedTypeIdent();

                if (s7 !== peg$FAILED) {
                  s8 = peg$parse__();

                  if (s8 !== peg$FAILED) {
                    if (input.charCodeAt(peg$currPos) === 59) {
                      s9 = peg$c70;
                      peg$currPos++;
                    } else {
                      s9 = peg$FAILED;

                      if (peg$silentFails === 0) {
                        peg$fail(peg$c71);
                      }
                    }

                    if (s9 !== peg$FAILED) {
                      peg$savedPos = s0;
                      s1 = peg$c95(s1, s7);
                      s0 = s1;
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parsePartialAppDecl() {
    var s0;
    s0 = peg$parsePartialTypeAppDecl();

    if (s0 === peg$FAILED) {
      s0 = peg$parsePartialCombAppDecl();
    }

    return s0;
  }

  function peg$parsePartialTypeAppDecl() {
    var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
    s0 = peg$currPos;
    s1 = peg$parseBoxedTypeIdent();

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        if (input.charCodeAt(peg$currPos) === 60) {
          s3 = peg$c46;
          peg$currPos++;
        } else {
          s3 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c47);
          }
        }

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            s5 = peg$parseSubexpr();

            if (s5 !== peg$FAILED) {
              s6 = [];
              s7 = peg$currPos;
              s8 = peg$parse__();

              if (s8 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 44) {
                  s9 = peg$c48;
                  peg$currPos++;
                } else {
                  s9 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c49);
                  }
                }

                if (s9 !== peg$FAILED) {
                  s10 = peg$parse__();

                  if (s10 !== peg$FAILED) {
                    s11 = peg$parseSubexpr();

                    if (s11 !== peg$FAILED) {
                      s8 = [s8, s9, s10, s11];
                      s7 = s8;
                    } else {
                      peg$currPos = s7;
                      s7 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s7;
                    s7 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s7;
                  s7 = peg$FAILED;
                }
              } else {
                peg$currPos = s7;
                s7 = peg$FAILED;
              }

              while (s7 !== peg$FAILED) {
                s6.push(s7);
                s7 = peg$currPos;
                s8 = peg$parse__();

                if (s8 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 44) {
                    s9 = peg$c48;
                    peg$currPos++;
                  } else {
                    s9 = peg$FAILED;

                    if (peg$silentFails === 0) {
                      peg$fail(peg$c49);
                    }
                  }

                  if (s9 !== peg$FAILED) {
                    s10 = peg$parse__();

                    if (s10 !== peg$FAILED) {
                      s11 = peg$parseSubexpr();

                      if (s11 !== peg$FAILED) {
                        s8 = [s8, s9, s10, s11];
                        s7 = s8;
                      } else {
                        peg$currPos = s7;
                        s7 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s7;
                      s7 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s7;
                    s7 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s7;
                  s7 = peg$FAILED;
                }
              }

              if (s6 !== peg$FAILED) {
                s7 = peg$parse__();

                if (s7 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 62) {
                    s8 = peg$c50;
                    peg$currPos++;
                  } else {
                    s8 = peg$FAILED;

                    if (peg$silentFails === 0) {
                      peg$fail(peg$c51);
                    }
                  }

                  if (s8 !== peg$FAILED) {
                    s9 = peg$parse__();

                    if (s9 !== peg$FAILED) {
                      if (input.charCodeAt(peg$currPos) === 59) {
                        s10 = peg$c70;
                        peg$currPos++;
                      } else {
                        s10 = peg$FAILED;

                        if (peg$silentFails === 0) {
                          peg$fail(peg$c71);
                        }
                      }

                      if (s10 !== peg$FAILED) {
                        peg$savedPos = s0;
                        s1 = peg$c96(s1, s5, s6);
                        s0 = s1;
                      } else {
                        peg$currPos = s0;
                        s0 = peg$FAILED;
                      }
                    } else {
                      peg$currPos = s0;
                      s0 = peg$FAILED;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    if (s0 === peg$FAILED) {
      s0 = peg$currPos;
      s1 = peg$parseBoxedTypeIdent();

      if (s1 !== peg$FAILED) {
        s2 = [];
        s3 = peg$currPos;
        s4 = peg$parse__();

        if (s4 !== peg$FAILED) {
          s5 = peg$parseSubexpr();

          if (s5 !== peg$FAILED) {
            s4 = [s4, s5];
            s3 = s4;
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }

        if (s3 !== peg$FAILED) {
          while (s3 !== peg$FAILED) {
            s2.push(s3);
            s3 = peg$currPos;
            s4 = peg$parse__();

            if (s4 !== peg$FAILED) {
              s5 = peg$parseSubexpr();

              if (s5 !== peg$FAILED) {
                s4 = [s4, s5];
                s3 = s4;
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          }
        } else {
          s2 = peg$FAILED;
        }

        if (s2 !== peg$FAILED) {
          s3 = peg$parse__();

          if (s3 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 59) {
              s4 = peg$c70;
              peg$currPos++;
            } else {
              s4 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c71);
              }
            }

            if (s4 !== peg$FAILED) {
              peg$savedPos = s0;
              s1 = peg$c97(s1, s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    }

    return s0;
  }

  function peg$parsePartialCombAppDecl() {
    var s0, s1, s2, s3, s4, s5;
    s0 = peg$currPos;
    s1 = peg$parseCombinatorId();

    if (s1 !== peg$FAILED) {
      s2 = [];
      s3 = peg$currPos;
      s4 = peg$parse__();

      if (s4 !== peg$FAILED) {
        s5 = peg$parseSubexpr();

        if (s5 !== peg$FAILED) {
          s4 = [s4, s5];
          s3 = s4;
        } else {
          peg$currPos = s3;
          s3 = peg$FAILED;
        }
      } else {
        peg$currPos = s3;
        s3 = peg$FAILED;
      }

      if (s3 !== peg$FAILED) {
        while (s3 !== peg$FAILED) {
          s2.push(s3);
          s3 = peg$currPos;
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            s5 = peg$parseSubexpr();

            if (s5 !== peg$FAILED) {
              s4 = [s4, s5];
              s3 = s4;
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }
        }
      } else {
        s2 = peg$FAILED;
      }

      if (s2 !== peg$FAILED) {
        s3 = peg$parse__();

        if (s3 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 59) {
            s4 = peg$c70;
            peg$currPos++;
          } else {
            s4 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c71);
            }
          }

          if (s4 !== peg$FAILED) {
            peg$savedPos = s0;
            s1 = peg$c98(s1, s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseFinalDecl() {
    var s0, s1, s2, s3, s4, s5;
    s0 = peg$currPos;
    s1 = peg$parseNewKw();

    if (s1 !== peg$FAILED) {
      s2 = peg$parse__();

      if (s2 !== peg$FAILED) {
        s3 = peg$parseBoxedTypeIdent();

        if (s3 !== peg$FAILED) {
          s4 = peg$parse__();

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 59) {
              s5 = peg$c70;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              if (peg$silentFails === 0) {
                peg$fail(peg$c71);
              }
            }

            if (s5 !== peg$FAILED) {
              peg$savedPos = s0;
              s1 = peg$c99(s3);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    if (s0 === peg$FAILED) {
      s0 = peg$currPos;
      s1 = peg$parseFinalKw();

      if (s1 !== peg$FAILED) {
        s2 = peg$parse__();

        if (s2 !== peg$FAILED) {
          s3 = peg$parseBoxedTypeIdent();

          if (s3 !== peg$FAILED) {
            s4 = peg$parse__();

            if (s4 !== peg$FAILED) {
              if (input.charCodeAt(peg$currPos) === 59) {
                s5 = peg$c70;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;

                if (peg$silentFails === 0) {
                  peg$fail(peg$c71);
                }
              }

              if (s5 !== peg$FAILED) {
                peg$savedPos = s0;
                s1 = peg$c100(s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }

      if (s0 === peg$FAILED) {
        s0 = peg$currPos;
        s1 = peg$parseEmptyKw();

        if (s1 !== peg$FAILED) {
          s2 = peg$parse__();

          if (s2 !== peg$FAILED) {
            s3 = peg$parseBoxedTypeIdent();

            if (s3 !== peg$FAILED) {
              s4 = peg$parse__();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 59) {
                  s5 = peg$c70;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  if (peg$silentFails === 0) {
                    peg$fail(peg$c71);
                  }
                }

                if (s5 !== peg$FAILED) {
                  peg$savedPos = s0;
                  s1 = peg$c101(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      }
    }

    return s0;
  }

  function peg$parseComment() {
    var s0, s1, s2, s3;
    s0 = peg$currPos;

    if (input.substr(peg$currPos, 2) === peg$c102) {
      s1 = peg$c102;
      peg$currPos += 2;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c103);
      }
    }

    if (s1 !== peg$FAILED) {
      s2 = [];

      if (peg$c104.test(input.charAt(peg$currPos))) {
        s3 = input.charAt(peg$currPos);
        peg$currPos++;
      } else {
        s3 = peg$FAILED;

        if (peg$silentFails === 0) {
          peg$fail(peg$c105);
        }
      }

      while (s3 !== peg$FAILED) {
        s2.push(s3);

        if (peg$c104.test(input.charAt(peg$currPos))) {
          s3 = input.charAt(peg$currPos);
          peg$currPos++;
        } else {
          s3 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c105);
          }
        }
      }

      if (s2 !== peg$FAILED) {
        if (peg$c106.test(input.charAt(peg$currPos))) {
          s3 = input.charAt(peg$currPos);
          peg$currPos++;
        } else {
          s3 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c107);
          }
        }

        if (s3 === peg$FAILED) {
          s3 = peg$parseEOF();
        }

        if (s3 !== peg$FAILED) {
          s1 = [s1, s2, s3];
          s0 = s1;
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }
      } else {
        peg$currPos = s0;
        s0 = peg$FAILED;
      }
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  function peg$parseWs() {
    var s0, s1;
    peg$silentFails++;

    if (input.charCodeAt(peg$currPos) === 32) {
      s0 = peg$c109;
      peg$currPos++;
    } else {
      s0 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c110);
      }
    }

    if (s0 === peg$FAILED) {
      if (input.charCodeAt(peg$currPos) === 9) {
        s0 = peg$c111;
        peg$currPos++;
      } else {
        s0 = peg$FAILED;

        if (peg$silentFails === 0) {
          peg$fail(peg$c112);
        }
      }

      if (s0 === peg$FAILED) {
        if (input.charCodeAt(peg$currPos) === 13) {
          s0 = peg$c113;
          peg$currPos++;
        } else {
          s0 = peg$FAILED;

          if (peg$silentFails === 0) {
            peg$fail(peg$c114);
          }
        }

        if (s0 === peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 10) {
            s0 = peg$c115;
            peg$currPos++;
          } else {
            s0 = peg$FAILED;

            if (peg$silentFails === 0) {
              peg$fail(peg$c116);
            }
          }
        }
      }
    }

    peg$silentFails--;

    if (s0 === peg$FAILED) {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c108);
      }
    }

    return s0;
  }

  function peg$parse__() {
    var s0, s1;
    peg$silentFails++;
    s0 = [];
    s1 = peg$parseWs();

    if (s1 === peg$FAILED) {
      s1 = peg$parseComment();
    }

    while (s1 !== peg$FAILED) {
      s0.push(s1);
      s1 = peg$parseWs();

      if (s1 === peg$FAILED) {
        s1 = peg$parseComment();
      }
    }

    peg$silentFails--;

    if (s0 === peg$FAILED) {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c117);
      }
    }

    return s0;
  }

  function peg$parseEOF() {
    var s0, s1;
    s0 = peg$currPos;
    peg$silentFails++;

    if (input.length > peg$currPos) {
      s1 = input.charAt(peg$currPos);
      peg$currPos++;
    } else {
      s1 = peg$FAILED;

      if (peg$silentFails === 0) {
        peg$fail(peg$c118);
      }
    }

    peg$silentFails--;

    if (s1 === peg$FAILED) {
      s0 = void 0;
    } else {
      peg$currPos = s0;
      s0 = peg$FAILED;
    }

    return s0;
  }

  const makeNode = (type, body = {}) => ({
    type,
    ...location(),
    ...body
  });

  const makeFinalDecl = (finalization, id) => makeNode('FinalDeclaration', {
    finalization,
    id
  });

  const makeDeclarationsNode = (type, declarations, initial = []) => makeNode(type, {
    declarations: declarations.filter(e => e.type === type).reduce((acc, {
      declarations
    }) => {
      acc.push(...declarations);
      return acc;
    }, initial)
  }); // [[a,b],[c,d]] -> [a,c]


  const extractFirst = list => list.map(list2 => list2 && list2[0]); // [[a,b],[c,d]] -> [b,d]


  const extractLast = list => list.map(list2 => list2 && list2[list2.length - 1]);

  const safeFirst = list => list ? list[0] : null;

  const safeLast = list => list ? list[list.length - 1] : null;

  peg$result = peg$startRuleFunction();

  if (peg$result !== peg$FAILED && peg$currPos === input.length) {
    return peg$result;
  } else {
    if (peg$result !== peg$FAILED && peg$currPos < input.length) {
      peg$fail(peg$endExpectation());
    }

    throw peg$buildStructuredError(peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) : peg$computeLocation(peg$maxFailPos, peg$maxFailPos));
  }
}

module.exports = {
  SyntaxError: peg$SyntaxError,
  parse: peg$parse
};