% crochet

// The stream we're parsing (this should support random indexing)
type parser-stream(position is integer, stream is list);


// Parsers
abstract parser;
singleton parser-always is parser;
singleton parser-any is parser;
type parser-lazy(parser is thunk) is parser;
type parser-alt(left is parser, right is parser) is parser;
type parser-backtrack(parser is parser) is parser;
type parser-seq(left is parser, right is parser) is parser;
type parser-many(parser is parser) is parser;
type parser-opt(parser is parser) is parser;
type parser-eq(value) is parser;
type parser-not(parser is parser) is parser;
type parser-lookahead(parser is parser) is parser;
type parser-action(parser is parser, semantic is function-1) is parser;
type parser-predicate(parser is parser, pred is function-1) is parser;

// Reasons for parsing error
abstract parser-error;
singleton parser-error-end-of-stream is parser-error;
type parser-error-alt(left is parser-error, right is parser-error) is parser-error;
type parser-error-expected(expected) is parser-error;
type parser-error-unexpected(parser is parser) is parser-error;
type parser-error-not-satisfied(parser is parser) is parser-error;
type parser-error-arbitrary(failure is text) is parser-error;

// An intermediate parser result
abstract parser-result;
type parser-result-ok(value, position is parser-stream) is parser-result;
type parser-result-error(reason is parser-error, position is parser-stream) is parser-result;

type parser-result-pair(left, right);

