# All files / src/semantics/map-function patch-typecasts.js

100% Statements 19/19
100% Branches 11/11
100% Functions 4/4
100% Lines 19/19

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    23x
    23x

    23x
    1160x

    754x

    42x

    51x

    23x

    290x

    23x

    290x

    580x
    300x

    280x

    290x
    580x
    43x

    537x

    290x

     // @flow
    import Syntax from "../../Syntax";
    import { TYPE_CAST } from "../metadata";
    import type { NodeType } from "../../flow/types";

    export const typeWeight = (typeString: ?string) => {
      switch (typeString) {
        case "i32":
          return 0;
        case "i64":
          return 1;
        case "f32":
          return 2;
        case "f64":
          return 3;
        default:
          return -1;
      }
    };

    export const balanceTypesInMathExpression = (
      expression: NodeType
    ): NodeType => {
      // 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;
      }, null);

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

        return paramNode;
      });

      return {
        ...expression,
        params,
        type,
      };
    };