"use strict"; function parseCodepoint(input, nullValue) { if (input === null) { return nullValue; } else if (typeof input === "number") { return input; } else if (typeof input === "string") { return input.codePointAt(0); } else { // FIXME: Better validation here throw new Error(`Invalid codepoint input`); } } module.exports = { zeroOrMore: (rule) => { return { __protocolKitInstruction: true, type: "zeroOrMore", rule: rule }; }, oneOrMore: (rule) => { return { __protocolKitInstruction: true, type: "oneOrMore", rule: rule }; }, either: (options) => { return { __protocolKitInstruction: true, type: "either", options: options }; }, until: (rule, allowEnd = true) => { return { __protocolKitInstruction: true, type: "until", rule: rule, // FIXME: Should allowEnd have a different default? allowEnd: allowEnd }; }, optional: (rule) => { return { __protocolKitInstruction: true, type: "optional", rule: rule }; }, peek: (rule) => { return { __protocolKitInstruction: true, type: "peek", rule: rule }; }, test: (rule) => { return { __protocolKitInstruction: true, type: "test", rule: rule }; }, wholeMatch: (rule) => { return { __protocolKitInstruction: true, type: "wholeMatch", rule: rule }; }, trackPosition: (rule) => { return { __protocolKitInstruction: true, type: "trackPosition", rule: rule }; }, EndOfInput: { __protocolKitInstruction: true, type: "endOfInput" }, characterRange: (start, end) => { // NOTE: Both inclusive! let startCodepoint = parseCodepoint(start, 0); let endCodepoint = parseCodepoint(end, Infinity); return { __protocolKitInstruction: true, type: "characterRange", start: startCodepoint, end: endCodepoint }; } };