UNPKG

@fink/larix

Version:

A parser for generating fink's AST.

204 lines (186 loc) 3.98 kB
import { curr_loc, next_loc, next_is_end } from "@fink/prattler/parser.js"; import { advance, has_errors } from "@fink/prattler/parser.js"; import { add_error } from "@fink/prattler/errors.js"; // TODO: remove? export const end_of_block_indent = { end_of_block_indent: true }; export const end_of_code = `end`; export const curr_indentation = ({ blocks }) => { const [{ curr_ind }] = blocks; return curr_ind; }; export const min_indentation = ({ blocks }) => { const [{ min_ind }] = blocks; return min_ind; }; export const next_is_new_expr = ctx => { const { start: { column } } = next_loc(ctx); return column <= curr_indentation(ctx); }; export const next_is_unindented = ctx => { const min_ind = min_indentation(ctx); { const ˆvalue_1 = next_loc(ctx); /* istanbul ignore else */ if (ˆvalue_1 != null) { const { start: ˆp_3 } = ˆvalue_1; /* istanbul ignore else */ if (ˆp_3 != null) { const { column: ˆp_4 } = ˆp_3; /* istanbul ignore else */ if (ˆp_4 < min_ind) { return true; } } } { return false; } } }; export const next_is_indented = ctx => { const curr_ind = curr_indentation(ctx); const { end: { line: curr_line } } = curr_loc(ctx); const { start: { line: next_line, column: next_ind } } = next_loc(ctx); return curr_line < next_line && curr_ind < next_ind; }; export const pop_block = ctx => { const { blocks: [{ end_symbol }, ...blocks] } = ctx; const next_ctx = { ...ctx, blocks }; { const ˆvalue_5 = end_symbol; /* istanbul ignore else */ if (ˆvalue_5 === end_of_block_indent || ˆvalue_5 === end_of_code) { { const ˆvalue_7 = next_ctx; /* istanbul ignore else */ if (next_is_end(ˆvalue_7)) { return advance(next_ctx); } { return next_ctx; } } } { { const ˆvalue_9 = ctx; /* istanbul ignore else */ if (ˆvalue_9 != null) { const { next_token: ˆp_11 } = ˆvalue_9; /* istanbul ignore else */ if (ˆp_11 != null) { const { type: ˆp_12 } = ˆp_11; /* istanbul ignore else */ if (ˆp_12 === end_symbol) { return advance(next_ctx); } } } /* istanbul ignore else */ if (has_errors(ˆvalue_9)) { return ctx; } { { const ind = min_indentation(ctx); const [, err_ctx] = add_error(ctx, `Expected \`,\` or indented(>=${ind}) new line or \`${end_symbol}\`.`, ctx.next_token); return err_ctx; } } } } } }; export const push_block = (ctx, end_symbol) => { const { blocks } = ctx; const curr_ind = curr_indentation(ctx); let _do_result; ˆmatch_14: { const ˆvalue_13 = end_symbol; /* istanbul ignore else */ if (ˆvalue_13 === end_of_code) { _do_result = { end_symbol, curr_ind, min_ind: curr_ind }; break ˆmatch_14; } { _do_result = { end_symbol, curr_ind, min_ind: curr_ind + 1 }; break ˆmatch_14; } } const block = _do_result; _do_result = undefined; return { ...ctx, blocks: [block, ...blocks] }; }; export const update_indentation = ctx => { const { start: { column } } = next_loc(ctx); const { blocks: [block, ...blocks] } = ctx; const indented_block = { ...block, curr_ind: column, min_ind: column }; return { ...ctx, blocks: [indented_block, ...blocks] }; }; export const init_indentation = ctx => ({ ...ctx, blocks: [{ end_symbol: end_of_code, min_ind: 0, curr_ind: 0 }] });