UNPKG

llparse

Version:

Compile incremental parsers to C code

58 lines 2.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MulAdd = void 0; const assert = require("assert"); const constants_1 = require("../constants"); const field_1 = require("./field"); class MulAdd extends field_1.Field { doBuild(ctx, out) { const options = this.ref.options; const ty = ctx.getFieldType(this.ref.field); let field = this.field(ctx); if (options.signed) { assert(constants_1.SIGNED_TYPES.has(ty), `Unexpected mulAdd type "${ty}"`); const targetTy = constants_1.SIGNED_TYPES.get(ty); out.push(`${targetTy}* field = (${targetTy}*) &${field};`); field = '(*field)'; } const match = ctx.matchVar(); const limits = options.signed ? constants_1.SIGNED_LIMITS : constants_1.UNSIGNED_LIMITS; assert(limits.has(ty), `Unexpected mulAdd type "${ty}"`); const [min, max] = limits.get(ty); const mulMax = `${max} / ${options.base}`; const mulMin = `${min} / ${options.base}`; out.push('/* Multiplication overflow */'); out.push(`if (${field} > ${mulMax}) {`); out.push(' return 1;'); out.push('}'); if (options.signed) { out.push(`if (${field} < ${mulMin}) {`); out.push(' return 1;'); out.push('}'); } out.push(''); out.push(`${field} *= ${options.base};`); out.push(''); out.push('/* Addition overflow */'); out.push(`if (${match} >= 0) {`); out.push(` if (${field} > ${max} - ${match}) {`); out.push(' return 1;'); out.push(' }'); out.push('} else {'); out.push(` if (${field} < ${min} - ${match}) {`); out.push(' return 1;'); out.push(' }'); out.push('}'); out.push(`${field} += ${match};`); if (options.max !== undefined) { out.push(''); out.push('/* Enforce maximum */'); out.push(`if (${field} > ${options.max}) {`); out.push(' return 1;'); out.push('}'); } out.push('return 0;'); } } exports.MulAdd = MulAdd; //# sourceMappingURL=mul-add.js.map