All files / src/shared/lib/rpn helpers.ts

82.35% Statements 42/51
63.15% Branches 24/38
100% Functions 9/9
78.57% Lines 33/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105112x 112x                   112x 369x             112x 68x 1x   67x 1x   66x     112x 224x     112x 301x     112x 134x 134x     112x 26x     112x 44x     44x 34x       10x       9x     15x                                                   10x     112x 39x       6x   33x     112x 26x    
import { assertUnreachable } from "shared/lib/helpers/assert";
import {
  Associativity,
  FunctionSymbol,
  functionSymbols,
  OperatorSymbol,
  operatorSymbols,
  functionArgsLen,
  Token,
} from "./types";
 
export const isNumeric = (str: string) => {
  return (
    str.toLowerCase() === "true" ||
    str.toLowerCase() === "false" ||
    (!isNaN(Number(str)) && isFinite(Number(str)))
  );
};
 
export const toNumber = (str: string) => {
  if (str.toLowerCase() === "true") {
    return 1;
  }
  if (str.toLowerCase() === "false") {
    return 0;
  }
  return Number(str);
};
 
export const isOperatorSymbol = (x: string): x is OperatorSymbol => {
  return (operatorSymbols as unknown as string[]).indexOf(x) > -1;
};
 
export const isFunctionSymbol = (x: string): x is FunctionSymbol => {
  return (functionSymbols as unknown as string[]).indexOf(x) > -1;
};
 
export const isVariable = (token: string): boolean => {
  const variable = String.raw`\$([VLT][0-9]|[a-z0-9-]{36}|[0-9]+)\$`;
  return !!new RegExp(`^${variable}$`, "i").exec(token);
};
 
export const isConstant = (token: string): boolean => {
  return !!/^@([a-z0-9-]{36}|engine::[^@]+)@$/i.exec(token);
};
 
export const getPrecedence = (token: Token): number => {
  Iif (token.type === "FUN") {
    return 4;
  }
  if (token.type === "OP") {
    switch (token.operator) {
      case "~":
      case "!":
      case "neg":
        return 14;
      case "*":
      case "/":
      case "%":
        return 12;
      case "+":
      case "-":
        return 11;
      case "<<":
      case ">>":
        return 10;
      case "<":
      case ">":
      case ">=":
      case "<=":
        return 9;
      case "==":
      case "!=":
        return 8;
      case "&":
        return 7;
      case "^":
        return 6;
      case "|":
        return 5;
      case "&&":
        return 4;
      case "||":
        return 3;
    }
    /* istanbul ignore next */
    assertUnreachable(token.operator);
  }
  return -1;
};
 
export const getAssociativity = (token: Token): Associativity => {
  if (
    token.type === "OP" &&
    (token.operator === "!" || token.operator === "~")
  ) {
    return Associativity.Right;
  }
  return Associativity.Left;
};
 
export const getArgsLen = (symbol: FunctionSymbol) => {
  return functionArgsLen[symbol];
};