UNPKG

@fink/larix

Version:

A parser for generating fink's AST.

259 lines (218 loc) 5.53 kB
const { _in_ } = require("@fink/js-interop/runtime.js"); const { advance, expression, next_is, has_errors } = require("@fink/prattler/parser.js"); const { curr_loc, next_loc } = require("@fink/prattler/parser.js"); const { add_error } = require("@fink/prattler/errors.js"); const { unfold, filter } = require("@fink/std-lib/iter.js"); const { update_indentation, push_block, pop_block } = require("./indentation.js"); const { next_is_unindented } = require("./indentation.js"); const { next_is_indented } = require("./indentation.js"); const { get_comments } = require("../comments/collect.js"); const empty_expr = ({ loc: { end } }) => ({ type: `empty`, value: ``, loc: { start: end, end } }); exports.empty_expr = empty_expr; const get_end_symb = ({ blocks: [block] }) => block.end_symbol; exports.get_end_symb = get_end_symb; const end_of_block_tokens = [`:`, `}`, `]`, `)`, `str-expr-end`, `jsx-expr-end`, `end`]; exports.end_of_block_tokens = end_of_block_tokens; const next_is_end_of_block = ctx => { const ˆvalue_1 = ctx; /* istanbul ignore else */ if (ˆvalue_1 != null) { const { next_token: ˆp_3 } = ˆvalue_1; /* istanbul ignore else */ if (ˆp_3 != null) { const { type: ˆp_4 } = ˆp_3; /* istanbul ignore else */ if (_in_(ˆp_4, end_of_block_tokens)) { return true; } } } /* istanbul ignore else */ if (next_is_unindented(ˆvalue_1)) { return true; } { return false; } }; exports.next_is_end_of_block = next_is_end_of_block; const next_is_nl = ctx => { const { end: { line: curr_line } } = curr_loc(ctx); const { start: { line: next_line } } = next_loc(ctx); return curr_line < next_line; }; exports.next_is_nl = next_is_nl; const get_all = (ctx, single_expr) => { let _do_result; { let ˆpipe_result_5 = [, [[], ctx, true, false]]; ˆpipe_result_5 = unfold(([, [exprs, ctx, at_start, was_comma]]) => { const ˆvalue_6 = ctx; /* istanbul ignore else */ if (has_errors(ˆvalue_6)) { return [true, [exprs, ctx]]; } /* istanbul ignore else */ if (next_is_indented(ˆvalue_6)) { { const next_ctx = update_indentation(ctx); return [false, [exprs, next_ctx, true, was_comma]]; } } /* istanbul ignore else */ if (next_is_end_of_block(ˆvalue_6)) { { const ˆvalue_8 = was_comma; /* istanbul ignore else */ if (ˆvalue_8 === true) { { const expr = empty_expr(ctx.curr_token); return [true, [[...exprs, expr], ctx]]; } } { return [true, [exprs, ctx]]; } } } /* istanbul ignore else */ if (next_is(ˆvalue_6, `,`)) { { const next_ctx = advance(ctx); { const ˆvalue_10 = at_start; /* istanbul ignore else */ if (ˆvalue_10 === true) { { const expr = empty_expr(ctx.next_token); return [false, [[...exprs, expr], next_ctx, true, false]]; } } { { const ˆvalue_12 = next_ctx; /* istanbul ignore else */ if (next_is(ˆvalue_12, `,`)) { { const expr = empty_expr(ctx.next_token); return [false, [[...exprs, expr], next_ctx, false, false]]; } } { return [false, [exprs, next_ctx, true, true]]; } } } } } } { { const ˆvalue_14 = at_start; /* istanbul ignore else */ if (ˆvalue_14 === false) { { const [, err_ctx] = add_error(ctx, `Expected \`,\` or indented new line or ${get_end_symb(ctx)}.`, ctx.next_token); return [true, [exprs, err_ctx]]; } } { { // TODO: check if next is actually a start of an expr. const [expr, next_ctx] = single_expr(ctx); // new line at end of expr is a separator const next_is_start = next_is_nl(next_ctx); return [false, [[...exprs, expr], next_ctx, next_is_start, false]]; } } } } })(ˆpipe_result_5); _do_result = ˆpipe_result_5 = filter(([done]) => done)(ˆpipe_result_5); } // TODO this is a monster, needs breakdown const [[, [exprs, next_ctx]]] = _do_result; _do_result = undefined; return [exprs, next_ctx]; }; exports.get_all = get_all; const expressions = (ctx, end_symbol, single_expr) => { const { start } = curr_loc(ctx); const block_ctx = push_block(ctx, end_symbol); const [exprs, next_ctx] = get_all(block_ctx, single_expr); const end_ctx = pop_block(next_ctx); const { end } = curr_loc(end_ctx); return [{ type: `exprs`, exprs, loc: { start, end } }, end_ctx]; }; exports.expressions = expressions; const single_expression = (ctx, lbp = 0) => { const [leading, expr_ctx] = get_comments(ctx); const [expr, next_ctx] = expression(expr_ctx, lbp); return [{ ...expr, comments: { leading } }, next_ctx]; }; exports.single_expression = single_expression;