const block = lazy(_ => seq( LBRACE, S.many().map(cat)
                           , alt( any
                                , block
                                , seq(ATKEYWORD, S.many().map(cat)).map(cat)
                                , seq(SEMI,      S.many().map(cat)).map(cat)
                                ).many().map(cat)
                           , RBRACE, S.many().map(cat) ).map(cat))
Example #2
0
const parser = options => r => Pa
    .seq(
        r.expr.map(data => data.output),
        Pa
            .seq(Pa.optWhitespace, Pa.string(','), Pa.optWhitespace, r.expr.map(data => data.output))
            .map(data => data[3])
            .many()
    )
    .map(data => [data[0]].concat(data[1]));
const parser = options => r => Pa
    .seq(
        r.intervalExpr,
        Pa
            .seq(
                Pa.optWhitespace,
                Pa.alt(Pa.string('*'), Pa.string('/'), Pa.string('%')),
                Pa.optWhitespace,
                r.intervalExpr
            )
            .map(data => ({ operand: data[3], operator: data[1] }))
            .many()
    )
    .map(binaryOpMapper);
const parser = options => r => Pa
    .alt(
        Pa
            .seq(
                r.fieldId.map(data => {
                    const pathItem = new DocumentPathItem();

                    pathItem.setType(DocumentPathItem.Type.MEMBER);
                    pathItem.setValue(data);

                    return pathItem;
                }),
                r.documentPath.atMost(1).map(data => data[0])
            )
            .map(data => [data[0]].concat(data[1])),
        scopedDocumentField(options)(r)
    )
    .map(data => {
        const columnId = new ColumnIdentifier();

        data.forEach(pathItem => {
            columnId.addDocumentPath(pathItem);
        });

        return columnId;
    });
const parser = options => r => Pa
    .seq(
        r.schemaQualifiedIdent,
        Pa.string('('),
        Pa.optWhitespace,
        r.argsList.atMost(1),
        Pa.optWhitespace,
        Pa.string(')')
    )
    .map(data => {
        const functionCall = new FunctionCall();
        functionCall.setName(data[0]);

        const expr = new Expr();
        expr.setType(Expr.Type.FUNC_CALL);

        const argsList = data[3] && data[3][0] ? data[3][0] : [];

        argsList.forEach((additional) => {
            functionCall.addParam(additional);
        });

        expr.setFunctionCall(functionCall);

        return expr;
    });
const parser = options => r => Pa
    .seq(r.optNotPrefix, r.REGEXP.skip(r.blank), r.compExpr)
    .map(data => ({ operator: data[0] + data[1], operand: data[2] }))
    .map(data => {
        const operator = new Operator();
        operator.setName(data.operator);
        operator.addParam(data.operand);

        return operator;
    });
Example #7
0
const parser = options => r => Pa
    .seq(
        r.expr
            .map(data => data.output),
        Pa
            .seq(Pa.whitespace, Pa.alt(r.ASC, r.DESC))
            .map(data => data[1])
            .atMost(1)
            .map(data => data[0])
    )
    .map(data => {
        const order = new Crud.Order();
        order.setExpr(data[0]);

        if (data[1]) {
            order.setDirection(data[1]);
        }

        return { input: options.input, output: order };
    });
const parser = options => r => Pa
    .seq(r.optNotSuffix, r.BETWEEN.skip(r.blank), r.compExpr, r.AND.wrap(r.blank, r.blank), r.compExpr)
    .map(data => ({ operator: data[1] + data[0], operands: [data[2]].concat(data[4]) }))
    .map(data => {
        const operator = new Operator();
        operator.setName(data.operator);

        data.operands.forEach(operand => {
            operator.addParam(operand);
        });

        return operator;
    });
Example #9
0
const parser = options => r => Pa
    .seq(
        r.bitExpr,
        Pa
            .seq(
                Pa.optWhitespace,
                Pa.alt(
                    Pa.string('<>').map(() => '!='),
                    Pa.string('>='),
                    Pa.string('<='),
                    Pa.string('!='),
                    Pa.string('>'),
                    Pa.string('<'),
                    Pa.alt(Pa.string('=='), Pa.string('=')).map(() => '==')
                ),
                Pa.optWhitespace,
                r.bitExpr
            )
            .map(data => ({ operand: data[3], operator: data[1] }))
            .many()
    )
    .map(binaryOpMapper);
const scopedDocumentField = options => r => {
    return Pa
        .seq(
            Pa
                .string('$')
                .map(data => {
                    options.scoped = true;
                    return data;
                }),
            r.documentPath
                .atMost(1)
                .map(data => data[0])
        )
        .map(data => data[1]);
};
Example #11
0
const parser = options => r => Pa
    .seq(
        Pa.alt(
            Pa.string('!'),
            Pa.string('~'),
            Pa.string('+').map(() => 'sign_plus'),
            Pa.string('-').map(() => 'sign_minus')
        ),
        r.atomicExpr
    )
    .map(data => {
        const operator = new Operator();
        operator.setName(data[0]);
        operator.addParam(data[1]);

        const expr = new Expr();
        expr.setType(Expr.Type.OPERATOR);
        expr.setOperator(operator);

        return expr;
    });
Example #12
0
module.exports = function(ps) {
    var DotProp = _.then(word(".")).then(ps.IdentifierAsString);
    var BracketProp = wrap("[", ps.Expr, "]");
    var Property = DotProp.or(BracketProp);
    /// I think so far I'm feeling ok about `foo::bar` as a syntax. I think to
    /// fit in with pattern matching expressions vs literals, the syntax for
    /// getting a bound method based on a computed value could be `foo::(bar)`,
    /// if I end up implementing that.
    var BoundMethod = word("::").then(ps.IdentifierAsString);
    var ArgList = wrap("(", list0(ps.Separator, ps.Expr), ")");
    var CallGetOrBind =
        P.alt(
            ione(almostSpready(ast.Call), ArgList),
            ione(almostSpready(ast.GetProperty), Property),
            ione(almostSpready(ast.GetMethod), BoundMethod)
        );
    return iseq(combine,
        P.seq(
            ps.Literal,
            CallGetOrBind.many()
        ));
};
Example #13
0
(function (parsers) {
    /* tslint:disable:max-line-length:*/
    var id = P.regex(/[a-z]\w*/i);
    var semver = P.regex(/\d+(?:\.\d+)+(?:-[a-z_]\w*(?:\.\d+)*)?/);
    var anyChar = P.regex(/[\S]+/);
    var anyStr = P.regex(/[\S\s]+/);
    var chars = P.regex(/\S+/);
    var space = P.string(' ');
    var colon = P.string(':');
    var optColon = P.regex(/:?/);
    var line = P.regex(/\r?\n/);
    var lineT = P.regex(/ *\r?\n/);

    // https://stackoverflow.com/questions/6927719/url-regex-does-not-work-in-javascript
    var uriLib = P.regex(/((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i);
    var uriBracket = P.string('<').then(uriLib).skip(P.string('>'));

    var bom = P.regex(/\uFEFF/);
    var bomOpt = P.regex(/\uFEFF?/);

    var comment = P.string('//');
    var comment3 = P.string('///');

    // global unity by unicode
    var nameUTF = P.regex(XRegExp('\\p{L}+(?:[ -]\\p{L}+)*'));

    var authorElem = nameUTF.skip(space).then(function (n) {
        return uriBracket.or(P.succeed(null)).map(function (u) {
            var ret = {
                name: n,
                url: u
            };
            return ret;
        });
    });

    var authorSeperator = P.string(', ');

    /* tslint:enable:max-line-length:*/
    parsers.label = comment.then(space).then(P.string('Type definitions for')).then(optColon).then(space).then(id).then(function (n) {
        return space.then(semver).or(P.succeed(null)).map(function (v) {
            var ret = {
                name: n,
                version: v
            };
            return ret;
        });
    });

    parsers.project = comment.then(space).then(P.string('Project')).then(colon).then(space).then(uriLib).map(function (u) {
        var ret = {
            url: u
        };
        return ret;
    });

    parsers.authors = comment.then(space).then(P.string('Definitions by')).then(colon).then(space).then(authorElem).then(function (a) {
        return authorSeperator.then(authorElem).many().or(P.succeed([])).map(function (arr) {
            arr.unshift(a);
            return arr;
        });
    });

    parsers.repo = comment.then(space).then(P.string('Definitions')).then(colon).then(space).then(uriLib).map(function (u) {
        var ret = {
            url: u
        };
        return ret;
    });

    parsers.header = bomOpt.then(P.seq(parsers.label.skip(line), parsers.project.skip(line), parsers.authors.skip(line), parsers.repo.skip(line))).map(function (arr) {
        var ret = {
            label: arr[0],
            project: arr[1],
            authors: arr[2],
            repository: arr[3]
        };
        return ret;
    }).skip(P.all);
})(parsers || (parsers = {}));
Example #14
0
'use strict';

var Parsimmon = require('parsimmon');

var typeDefinition = require('./type-definition.js');
var lexemes = require('./lexemes.js');
var typeLiteral = require('./type-literal.js');
var AST = require('../ast/');
var join = require('./lib/join.js');

var genericExpression = lexemes.openAngularBrace
    .then(join(typeDefinition, lexemes.comma))
    .skip(lexemes.closeAngularBrace);

var genericLiteral = Parsimmon.seq(
    typeLiteral,
    genericExpression.times(0, 1)
).map(function toGeneric(list) {
    if (list[1].length === 0) {
        return list[0];
    }

    return AST.generic(list[0], list[1][0]);
});

module.exports = genericLiteral;
const declaration_list = lazy(_ => alt( seq( declaration
                                           , SEMI.then(S.many()).then(declaration_list).atMost(1) )
                                      , seq(at_rule, declaration_list).map(cat)
                                      , of('') )).map(decls => pipe(flatten, filter(pipe(isEmpty, not)))(decls))
Example #16
0
;(function() {
   var root = this,
       R = {};

   // Dependencies ------------------------------------------------------------
   var _ = require('ramda'),
       P = require('parsimmon'),
       T = require('./types');

   // Helpers -----------------------------------------------------------------
   var _cat = _.join('');

   var _replace_backslash = _.replace(/\\\\/g, '\\');
   var _replace_newline   = _.replace(/\\n/g, '\n');
   var _replace_return    = _.replace(/\\r/g, '\r');
   var _replace_quotes    = _.replace(/\\"/g, '\"');

   var _replace_escaped = _.compose(_replace_newline,
                                    _replace_return,
                                    _replace_backslash,
                                    _replace_quotes);

   // Parsers -----------------------------------------------------------------
   R.Symbol = P.oneOf('!#$%&|*+-/:<=>?@^_~');

   R.Spaces = P.whitespace.atLeast(1);

   R.String = P.oneOf('"')
               .then(
                  P.alt(P.string('\\"'), P.noneOf('"'))
                   .many()
                   .map((value) => { 
                      value = _cat(value);
                      value = _replace_escaped(value);

                      return new T.String(value);
                   }))
               .skip(P.oneOf('"'));

   R.Character = P.string('#\\')
                  .then(
                    P.alt(P.string('space'), P.string('newline'), P.oneOf(' '), P.letter, P.digit)
                     .map((value) => {
                        if (value == 'space') {
                           return new T.Character(' ');
                        } else if (value == 'newline') {
                           return new T.Character('\n');
                        } else {
                           return new T.Character(value);
                        }
                     }));

   R.Atom = P.seqMap(P.alt(P.letter, R.Symbol),
                     P.alt(P.letter, P.digit, R.Symbol).many(),
                     (first, rest) => {
                        var atom = first + _cat(rest);

                        if (atom == '#t') {
                           return new T.Bool(true);
                        } else if (atom == '#f') {
                           return new T.Bool(false);
                        } else {
                           return new T.Atom(atom);
                        }
                     });

   R.Number = P.digit
               .atLeast(1)
               .map((value) => {
                  value = _cat(value);
                  value = parseInt(value);

                  return new T.Number(value);
               });
               
   R.Expr = P.lazy(() => {
      return P.alt(R.Character,
                   R.Atom,
                   R.String,
                   R.Number,
                   R.Quoted,
                   P.oneOf('(')
                    .then(P.alt(R.DottedList, R.List))
                    .skip(P.oneOf(')')));
   });

   R.List = P.sepBy(R.Expr, R.Spaces)
             .map((value) => {
                return new T.List(value);
             });

   R.DottedList = P.seqMap(P.sepBy(R.Expr, R.Spaces).skip(R.Spaces),
                           P.seq(P.oneOf('.'), R.Spaces).then(R.Expr),
                           (initial, last) => {
                              return new T.DottedList(initial, last);
                           });

   R.Quoted = P.oneOf("'")
               .then(
                  R.Expr.map((value) => {
                     return new T.List([new T.Atom('quote')].concat(value)); 
                  }));

   if (typeof exports !== 'undefined') {
      if (typeof module !== 'undefined') {
         exports = module.exports = R;
      }
      exports.R = R;
   } else {
      root.R = R;
   }
}).call(this);
const any = lazy(_ => seq( alt( IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, DELIM, URI
                              , HASH, UNICODE_RANGE, INCLUDES, DASHMATCH, COLON
                              , seq(FUNCTION, S.many().map(cat), alt(any, unused).many().map(cat), RPAREN) .map(cat)
                              , seq(LPAREN,   S.many().map(cat), alt(any, unused).many().map(cat), RPAREN) .map(cat) 
                              , seq(LSBRACE,  S.many().map(cat), alt(any, unused).many().map(cat), RSBRACE).map(cat) )
                         , S.many().map(cat) ).map(cat))
Example #18
0
const parser = options => r => Pa
    .alt(
        Pa
            .seq(
                r.SIGNED,
                Pa
                    .seq(
                        Pa.whitespace,
                        r.INTEGER
                    )
                    .tie()
                    .atMost(1)
                    .map(data => !data.length ? '' : data[0])
            )
            .tie(),
        Pa
            .seq(
                r.UNSIGNED,
                Pa
                    .seq(
                        Pa.whitespace,
                        r.INTEGER
                    )
                    .tie()
                    .atMost(1)
                    .map(data => !data.length ? '' : data[0])
            )
            .tie(),
        Pa
            .seq(
                r.CHAR,
                r.lengthSpec.atMost(1).map(data => !data.length ? '' : data[0])
            )
            .tie(),
        Pa
            .seq(
                r.BINARY,
                r.lengthSpec.atMost(1).map(data => !data.length ? '' : data[0])
            )
            .tie(),
        Pa
            .seq(
                r.DECIMAL,
                Pa
                    .alt(
                        r.lengthSpec,
                        Pa
                            .seq(
                                Pa.string('('),
                                Pa.optWhitespace,
                                r.INT,
                                Pa.optWhitespace,
                                Pa.string(','),
                                Pa.optWhitespace,
                                r.INT,
                                Pa.optWhitespace,
                                Pa.string(')')
                            )
                            .tie()
                    )
                    .atMost(1)
                    .map(data => !data.length ? '' : data[0])
            )
            .tie(),
        r.TIME,
        r.DATETIME,
        r.DATE,
        r.JSON
    )
    .map(data => {
        const str = new Scalar.String();
        /* eslint-disable node/no-deprecated-api */
        str.setValue(new Uint8Array(new Buffer(data)));
        /* eslint-enable node/no-deprecated-api */

        const scalar = new Scalar();
        scalar.setType(Scalar.Type.V_STRING);
        scalar.setVString(str);

        const expr = new Expr();
        expr.setType(Expr.Type.LITERAL);
        expr.setLiteral(scalar);

        return expr;
    });
                         , S.many().map(cat) ).map(cat))

// `any+`
const selector = any.atLeast(1).map(cat)

//  `'{' S* [ any | block | ATKEYWORD S* | ';' S* ]* '}' S*`
const block = lazy(_ => seq( LBRACE, S.many().map(cat)
                           , alt( any
                                , block
                                , seq(ATKEYWORD, S.many().map(cat)).map(cat)
                                , seq(SEMI,      S.many().map(cat)).map(cat)
                                ).many().map(cat)
                           , RBRACE, S.many().map(cat) ).map(cat))

// `ATKEYWORD S* any* [ block | ';' S* ]`
const at_rule = seq( ATKEYWORD, S.many().map(cat), any.many().map(cat)
                   , alt(block, seq(SEMI, S.many().map(cat)).map(cat)) ).map(cat)

// `[ any | block | ATKEYWORD S* ]+`
const value = alt( any
                 , block
                 , seq(ATKEYWORD, S.many().map(cat)).map(cat)
                 ).atLeast(1).map(cat)

// `IDENT`
const property = IDENT

// `property S* ':' S* value`
const declaration = lazy(_ => of().chain(_ => 
  Do(function* () {
    const name = yield property
    yield S.many()
var chainl1 = function(op, p) {
    return P.seq(
        P.seq(p, op).many(),
        p
    ).map(([l, r]) => lassoc(l, r));
};
 before(function() {
   this.paren = seq(LPAREN, S.many().map(cat), alt(any, unused).many().map(cat), RPAREN).map(cat)
 })
Example #22
0
var lexemes = require('./lexemes.js');
var AST = require('../ast.js');
var typeDefinition = require('./type-definition.js');
var typeLiteral = require('./type-literal.js');
var join = require('./lib/join.js');

var genericExpression = lexemes.openAngularBrace
    .then(join(
        typeLiteral,
        lexemes.comma
    ))
    .skip(lexemes.closeAngularBrace);

var typeDeclaration = lexemes.typeWord
    .then(Parsimmon.seq(
        lexemes.identifier,
        genericExpression.times(0, 1)
    ))
    .chain(function captureIdentifiers(list) {
        var identifier = list[0];
        var generics = list[1][0] || [];

        return lexemes.labelSeperator
            .then(typeDefinition)
            .map(function toTypeDeclaration(type) {
                return AST.typeDeclaration(identifier, type,
                    generics);
            });
    });

module.exports = typeDeclaration;
 before(function() {
   this.func = seq(FUNCTION, S.many().map(cat), alt(any, unused).many().map(cat), RPAREN).map(cat)
 })
Example #24
0
function parser (options) {
    options = Object.assign({}, {
        type: Type.EXPR,
        mode: DataModel.DOCUMENT,
        placeholders: [],
        scoped: false
    }, options);

    const parsers = Object.assign({}, keywords(options), partials(options), booleanExpressions(options), collectionOrTableExpressions(options), {

        QUOTED_ID (r) {
            return Pa.alt(
                Pa.seq(Pa.string('`'), r.ID, Pa.string('`')).tie(),
                Pa.seq(
                    Pa.string('`'),
                    Pa.alt(Pa.string('``'), Pa.noneOf('`')).many().tie(),
                    Pa.string('`')
                ).tie()
            );
        },

        ID (r) {
            return Pa.seq(
                Pa.alt(
                    Pa.string('_'),
                    Pa.letter
                ),
                Pa.alt(
                    Pa.string('_'),
                    Pa.letter,
                    r.DIGIT
                ).many().tie()
            ).tie();
        },

        INTERVAL_UNIT () {
            return Pa.alt(
                Pa.string('MICROSECOND'),
                Pa.string('SECOND_MICROSECOND'),
                Pa.string('SECOND'),
                Pa.string('MINUTE_MICROSECOND'),
                Pa.string('MINUTE_SECOND'),
                Pa.string('MINUTE'),
                Pa.string('HOUR_MICROSECOND'),
                Pa.string('HOUR_SECOND'),
                Pa.string('HOUR_MINUTE'),
                Pa.string('HOUR'),
                Pa.string('DAY_MICROSECOND'),
                Pa.string('DAY_SECOND'),
                Pa.string('DAY_MINUTE'),
                Pa.string('DAY_HOUR'),
                Pa.string('DAY'),
                Pa.string('WEEK'),
                Pa.string('MONTH'),
                Pa.string('QUARTER'),
                Pa.string('YEAR_MONTH'),
                Pa.string('YEAR')
            );
        },

        STRING_DQ (r) {
            return Pa
                .seq(
                    Pa.string('"'),
                    Pa.alt(r.SCHAR, Pa.string("'"), r.ESCAPED_DQ, r.ESCAPED_ESCAPE_CHAR).many().tie(),
                    Pa.string('"')
                )
                .tie();
        },

        ESCAPED_DQ (r) {
            return Pa.alt(Pa.string('""'), Pa.string('\u005C"')).map(() => '"');
        },

        ESCAPED_ESCAPE_CHAR (r) {
            return Pa.string('\u005C\u005C').map(() => '\u005C');
        },

        STRING_SQ (r) {
            return Pa
                .seq(
                    Pa.string("'"),
                    Pa.alt(r.SCHAR, Pa.string('"'), r.ESCAPED_SQ, r.ESCAPED_ESCAPE_CHAR).many().tie(),
                    Pa.string("'")
                )
                .tie();
        },

        ESCAPED_SQ (r) {
            return Pa.alt(Pa.string("''"), Pa.string("\u005C'")).map(() => "'");
        },

        DIGIT () {
            return Pa.digit;
        },

        FLOAT (r) {
            return Pa
                .seq(
                    Pa.string('-').atMost(1).tie(),
                    Pa
                        .alt(
                            Pa.seq(
                                r.DIGIT.many().tie(),
                                Pa.string('.'),
                                r.DIGIT.atLeast(1).tie(),
                                Pa.seq(
                                    Pa.string('E'),
                                    Pa.alt(Pa.string('+'), Pa.string('-')).atMost(1),
                                    r.DIGIT.atLeast(1).tie()
                                ).atMost(1).tie()
                            ),
                            Pa.seq(
                                r.DIGIT.atLeast(1).tie(),
                                Pa.string('E'),
                                Pa.alt(Pa.string('+'), Pa.string('-')).atMost(1),
                                r.DIGIT.atLeast(1).tie()
                            )
                        )
                        .tie()
                )
                .tie();
        },

        INT (r) {
            return Pa
                .seq(
                    Pa.string('-').atMost(1).tie(),
                    r.DIGIT.atLeast(1).tie()
                )
                .tie();
        },

        SCHAR () {
            return Pa.alt(
                Pa.range('\u0020', '\u0021'),
                // excludes double quotes (quotation mark)
                Pa.range('\u0023', '\u0026'),
                // excludes single quotes (apostrophe)
                Pa.range('\u0028', '\u005B'),
                // excludes escape character (reverse solidus)
                Pa.range('\u005D', '\u007E'),
                Pa.range('\u0080', '\uFFFF')
            );
        },

        // Additional Expression Types
        projectedSearchExpr: projectedSearchExpr.parser(options),
        sortExpr: sortExpr.parser(options),

        // Shortcuts

        blank (r) {
            return Pa.whitespace;
        },

        optBlank (r) {
            return r.blank.atMost(1);
        },

        optNotPrefix (r) {
            return r.NOT.skip(r.blank).atMost(1).map(data => !data.length ? '' : 'not_');
        },

        optNotSuffix (r) {
            return r.NOT.skip(r.blank).atMost(1).map(data => !data.length ? '' : '_not');
        }
    });

    const language = Pa.createLanguage(parsers);

    return language[options.type];
}
const parser = options => r => Pa
    .seq(r.ESCAPE.wrap(r.blank, r.blank), r.compExpr)
    .map(data => data[1]);
Example #26
0
function patternFactory(type, ps) {
    var Pattern = P.lazy(function() {
        return P.alt(
            PatternArray,
            PatternObject,
            PatternLeaf
        );
    });

    var helpers = {
        Let: function() {
            return PatternSimple;
        },
        Match: function() {
            return P.alt(
                PatternLiteral,
                PatternSimple,
                PatternParenExpr
            );
        }
    };

    if (!helpers.hasOwnProperty(type)) {
        throw new Error("cannot make pattern factory for " + type);
    }

    var PatternLeaf = P.lazy(helpers[type]);

    var PatternSimple =
        ione(ast.PatternSimple, ps.Identifier);

    var PatternParenExpr =
        ione(ast.PatternParenExpr, ps.ParenExpr);

    var PatternLiteral =
        ione(ast.PatternLiteral,
            P.alt(
                ps.Number,
                ps.String,
                ps.NamedLiteral
            ));

    var PatternObjectPairBasic =
        iseq(ast.PatternObjectPair,
            P.seq(
                ps.ObjectPairKey.skip(_),
                word(":").then(Pattern)
            ));

    var PatternObjectPairShorthand =
        ps.Identifier
        .map(function(i) {
            var str = ast.String(i.index, i.data);
            var expr = ast.PatternSimple(i.index, i);
            return ast.PatternObjectPair(i.index, str, expr);
        });

    var PatternObjectPair =
        P.alt(
            PatternObjectPairBasic,
            PatternObjectPairShorthand
        );

    var PatternObject =
        ione(ast.PatternObject,
            wrap("{", list0(ps.Separator, PatternObjectPair), "}"));

    var PatternArrayStrict =
        ione(ast.PatternArray,
            wrap("[", list0(ps.Separator, Pattern), "]"));

    var BareSlurp =
        ione(ast.PatternSimple,
            ione(ast.Identifier, P.of("_")));

    var PatternArraySlurpy =
        iseq(ast.PatternArraySlurpy,
            wrap(
                "[",
                P.seq(
                    Pattern.skip(ps.Separator).many(),
                    word("...").then(Pattern.or(BareSlurp))
                ),
                "]"
            ));

    var PatternArray =
        P.alt(
            PatternArrayStrict,
            PatternArraySlurpy
        );

    return Pattern;
}
const unused = lazy(_ => alt( block
                            , seq(ATKEYWORD, S.many())
                            , seq(SEMI,      S.many())
                            , seq(CDO,       S.many())
                            , seq(CDC,       S.many()) ).map(cat))
Example #28
0
);

const app = form(
  expr,
  expr,
  (fn, arg) => $app(fn, arg)
);

const ifz = form(
  tok("case"),
  expr,
  parens(
    tok("zero").then(expr)
  ),
  parens(
    seq(parens(tok("s").then(ident)), expr)
  ),
  (_, d, d0, [ x, d1 ]) => $ifz(d0, x, d1, d)
);

const fix = form(
  tok("fix"),
  ident,
  expr,
  (_, x, d) => $fix(x, d)
);

const define = form(
  tok("define"),
  ident,
  expr,
function chainr1(op, p) {
    return P.seq(
        p,
        P.seq(op, p).many()
    ).map(([l, r]) => rassoc(l, r));
}