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

82% Statements 41/50
57.58% Branches 19/33
100% Functions 9/9
78.05% Lines 32/41

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 10469x 69x                   69x 251x             69x 49x 1x   48x 1x   47x     69x 147x     69x 202x     69x 74x     69x 21x     69x 34x     34x 25x       9x       7x     9x                                                   9x     69x 31x       6x   25x     69x 16x    
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 => {
  return !!/^[$A-Z_][0-9A-Z_$]*$/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];
};