balanceTypesInMathExpression = expression => {
    // find the heaviest type in the expression
    const type = expression.params.reduce((acc, { type: childType }) => {
      // The way we do that is by scanning the top-level nodes in our expression
      if (typeWeight(acc) < typeWeight(childType)) {
        return childType;
      }

      return acc;
    }, expression.type);

    // iterate again, this time, patching any lighter types
    const params = expression.params.map(paramNode => {
      if (paramNode.type != null && typeWeight(paramNode.type) !== typeWeight(type)) {
        return _extends({}, paramNode, {
          type,
          value: paramNode.value,
          Type: Syntax.TypeCast,
          meta: _extends({}, paramNode.meta, {
            [TYPE_CAST]: { to: type, from: paramNode.type }
          }),
          params: [paramNode]
        });
      }

      return paramNode;
    });

    return _extends({}, expression, {
      params,
      type
    });
  }
Core language plugin

The parsers in here very closly mirror the underlying WebAssembly structure
and are used as the core language for every feature built on top.