UNPKG

@fink/larix

Version:

A parser for generating fink's AST.

231 lines (187 loc) 4.55 kB
const { _in_ } = require("@fink/js-interop/runtime.js"); const { next_is, has_errors, advance } = require("@fink/prattler/parser.js"); const { add_error } = require("@fink/prattler/errors.js"); const { add_operator, add_separator } = require("@fink/prattler/expressions.js"); const { keywords } = require("../../lexer/tokens.js"); const { prefix, terminator } = require("../expressions.js"); const { terminated_block, add_named_block } = require("../block/init.js"); const { single_expression } = require("../block/expr.js"); const { identifier } = require("../identifier/init.js"); const value_expr = ctx => { const ˆvalue_1 = ctx; /* istanbul ignore else */ if (next_is(ˆvalue_1, `:`)) { { const next_ctx = advance(ctx); return single_expression(next_ctx, 0); } } { return [false, ctx]; } }; exports.value_expr = value_expr; const key_expr = ctx => { const ˆvalue_3 = ctx.next_token; /* istanbul ignore else */ if (ˆvalue_3 != null) { const { type: ˆp_5 } = ˆvalue_3; /* istanbul ignore else */ if (_in_(ˆp_5, [`ident`, `...`, `(`, `str-start`])) { return single_expression(ctx, 0); } } // TODO should this be {value: ? in keywords} and be the first match? /* istanbul ignore else */ if (ˆvalue_3 != null) { const { type: ˆp_6 } = ˆvalue_3; // TODO should this be {value: ? in keywords} and be the first match? /* istanbul ignore else */ if (_in_(ˆp_6, keywords)) { return identifier(advance(ctx)); } } { return add_error(ctx, `Expected record-key but found '${ctx.next_token.value}'.`, ctx.next_token); } }; exports.key_expr = key_expr; const get_key_val = (ctx, key_or_default) => { const ˆvalue_7 = ctx; /* istanbul ignore else */ if (has_errors(ˆvalue_7)) { { const left = key_or_default; return [left, ctx]; } } { { let _do_result; ˆmatch_10: { const ˆvalue_9 = key_or_default; /* istanbul ignore else */ if (ˆvalue_9 != null) { const { type: ˆp_11 } = ˆvalue_9; /* istanbul ignore else */ if (ˆp_11 === `assign`) { _do_result = [key_or_default.left, key_or_default, ctx]; break ˆmatch_10; } } { { key_or_default; const [value, next_ctx] = value_expr(ctx); _do_result = [key_or_default, value, next_ctx]; } break ˆmatch_10; } } const [key, value, next_ctx] = _do_result; _do_result = undefined; const { start } = key.loc; let _do_result2; ˆmatch_13: { const ˆvalue_12 = value; /* istanbul ignore else */ if (ˆvalue_12 === false) { _do_result2 = key.loc; break ˆmatch_13; } { _do_result2 = value.loc; break ˆmatch_13; } } const { end } = _do_result2; _do_result2 = undefined; return [{ type: `rec:kv`, left: key, right: value, loc: { start, end } }, next_ctx]; } } }; exports.get_key_val = get_key_val; const key_val_expr = ctx => { const [key_or_default, value_ctx] = key_expr(ctx); { const ˆvalue_14 = key_or_default; /* istanbul ignore else */ if (ˆvalue_14 != null) { const { type: ˆp_16 } = ˆvalue_14; /* istanbul ignore else */ if (ˆp_16 === `spread`) { return [key_or_default, value_ctx]; } } { return get_key_val(value_ctx, key_or_default); } } }; exports.key_val_expr = key_val_expr; const record = token_type => ({ ...prefix(token_type), nud: () => ctx => { const [{ exprs, loc }, next_ctx] = terminated_block(ctx, `}`, key_val_expr); return [{ type: `rec`, exprs, loc }, next_ctx]; } }); exports.record = record; const add_record = ctx => { let ˆpipe_result_17 = ctx; ˆpipe_result_17 = add_operator(record(`{`))(ˆpipe_result_17); ˆpipe_result_17 = add_separator(terminator(`,`))(ˆpipe_result_17); ˆpipe_result_17 = add_separator(terminator(`:`))(ˆpipe_result_17); ˆpipe_result_17 = add_separator(terminator(`}`))(ˆpipe_result_17); return ˆpipe_result_17 = add_named_block(`rec`, `rec`, key_val_expr)(ˆpipe_result_17); }; exports.add_record = add_record;