compatibilityTable.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import { Types } from './../ast/types';
  2. import { Operators } from './../ast/operators';
  3. function buildInfixAddTable () {
  4. const table = [[], [], [], []];
  5. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
  6. table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
  7. table[Types.INTEGER.ord][Types.STRING.ord] = Types.STRING;
  8. table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
  9. table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
  10. table[Types.REAL.ord][Types.STRING.ord] = Types.STRING;
  11. table[Types.STRING.ord][Types.INTEGER.ord] = Types.STRING;
  12. table[Types.STRING.ord][Types.REAL.ord] = Types.STRING;
  13. table[Types.STRING.ord][Types.STRING.ord] = Types.STRING;
  14. table[Types.STRING.ord][Types.BOOLEAN.ord] = Types.STRING;
  15. return table;
  16. }
  17. function buildInfixMultiSubTable () {
  18. const table = [[], [], [], []];
  19. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
  20. table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
  21. table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
  22. table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
  23. return table;
  24. }
  25. function buildInfixDivTable () {
  26. const table = [[], [], [], []];
  27. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
  28. table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
  29. table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
  30. table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
  31. return table;
  32. }
  33. function buildInfixEqualityInequalityTable () {
  34. const table = [[], [], [], []];
  35. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
  36. table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
  37. table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
  38. table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
  39. return table;
  40. }
  41. function buildInfixRelationalTable () {
  42. const table = [[], [], [], []];
  43. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
  44. table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
  45. table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
  46. return table;
  47. }
  48. function buildInfixAndOrTable () {
  49. const table = [[], [], [], []];
  50. table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
  51. return table;
  52. }
  53. function buildInfixModTable () {
  54. const table = [[], [], [], []];
  55. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
  56. return table;
  57. }
  58. function buildUnarySumSubList () {
  59. const list = [];
  60. list[Types.INTEGER.ord] = Types.INTEGER;
  61. list[Types.REAL.ord] = Types.REAL;
  62. return list;
  63. }
  64. function buildUnaryNegList () {
  65. const list = [];
  66. list[Types.BOOLEAN.ord] = Types.BOOLEAN;
  67. return list;
  68. }
  69. function buildInfixCompatibilityTable () {
  70. const compatibilityMap = new WeakMap();
  71. compatibilityMap.set(Operators.ADD, buildInfixAddTable());
  72. compatibilityMap.set(Operators.SUB, buildInfixMultiSubTable());
  73. compatibilityMap.set(Operators.MULT, buildInfixMultiSubTable());
  74. compatibilityMap.set(Operators.DIV, buildInfixDivTable());
  75. compatibilityMap.set(Operators.EQ, buildInfixEqualityInequalityTable());
  76. compatibilityMap.set(Operators.NEQ, buildInfixEqualityInequalityTable());
  77. compatibilityMap.set(Operators.GE, buildInfixRelationalTable());
  78. compatibilityMap.set(Operators.GT, buildInfixRelationalTable());
  79. compatibilityMap.set(Operators.LE, buildInfixRelationalTable());
  80. compatibilityMap.set(Operators.LT, buildInfixRelationalTable());
  81. compatibilityMap.set(Operators.OR, buildInfixAndOrTable());
  82. compatibilityMap.set(Operators.AND, buildInfixAndOrTable());
  83. compatibilityMap.set(Operators.MOD, buildInfixModTable());
  84. return compatibilityMap;
  85. }
  86. function buildUnaryCompatibilityTable () {
  87. const compatibilityMap = new WeakMap();
  88. compatibilityMap.set(Operators.ADD, buildUnarySumSubList());
  89. compatibilityMap.set(Operators.SUB, buildUnarySumSubList());
  90. compatibilityMap.set(Operators.NOT, buildUnaryNegList());
  91. return compatibilityMap;
  92. }
  93. const infixMap = buildInfixCompatibilityTable();
  94. const unaryMap = buildUnaryCompatibilityTable();
  95. export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpressionType) {
  96. try {
  97. return infixMap.get(operator)[leftExpressionType.ord][rightExpressionType.ord];
  98. } catch (e) {
  99. if (e instanceof TypeError) {
  100. return Types.UNDEFINED;
  101. } else {
  102. throw e;
  103. }
  104. }
  105. }
  106. export function resultTypeAfterUnaryOp (operator, leftExpressionType) {
  107. try {
  108. return unaryMap.get(operator)[leftExpressionType.ord];
  109. } catch (e) {
  110. if (e instanceof TypeError) {
  111. return Types.UNDEFINED;
  112. } else {
  113. throw e;
  114. }
  115. }
  116. }