compatibilityTable.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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 buildInfixMultiDivSubTable () {
  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 buildInfixEqualityInequalityTable () {
  26. const table = [[], [], [], []];
  27. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
  28. table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
  29. table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
  30. table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
  31. return table;
  32. }
  33. function buildInfixRelationalTable () {
  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.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
  38. return table;
  39. }
  40. function buildInfixAndOrTable () {
  41. const table = [[], [], [], []];
  42. table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
  43. return table;
  44. }
  45. function buildInfixModTable () {
  46. const table = [[], [], [], []];
  47. table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
  48. return table;
  49. }
  50. function buildUnarySumSubList () {
  51. const list = [];
  52. list[Types.INTEGER.ord] = Types.INTEGER;
  53. list[Types.REAL.ord] = Types.REAL;
  54. return list;
  55. }
  56. function buildUnaryNegList () {
  57. const list = [];
  58. list[Types.BOOLEAN.ord] = Types.BOOLEAN;
  59. return list;
  60. }
  61. function buildInfixCompatibilityTable () {
  62. const compatibilityMap = new WeakMap();
  63. compatibilityMap.set(Operators.ADD, buildInfixAddTable());
  64. compatibilityMap.set(Operators.SUB, buildInfixMultiDivSubTable());
  65. compatibilityMap.set(Operators.MULT, buildInfixMultiDivSubTable());
  66. compatibilityMap.set(Operators.DIV, buildInfixMultiDivSubTable());
  67. compatibilityMap.set(Operators.EQ, buildInfixEqualityInequalityTable());
  68. compatibilityMap.set(Operators.NEQ, buildInfixEqualityInequalityTable());
  69. compatibilityMap.set(Operators.GE, buildInfixRelationalTable());
  70. compatibilityMap.set(Operators.GT, buildInfixRelationalTable());
  71. compatibilityMap.set(Operators.LE, buildInfixRelationalTable());
  72. compatibilityMap.set(Operators.LT, buildInfixRelationalTable());
  73. compatibilityMap.set(Operators.OR, buildInfixAndOrTable());
  74. compatibilityMap.set(Operators.AND, buildInfixAndOrTable());
  75. compatibilityMap.set(Operators.MOD, buildInfixModTable());
  76. return compatibilityMap;
  77. }
  78. function buildUnaryCompatibilityTable () {
  79. const compatibilityMap = new WeakMap();
  80. compatibilityMap.set(Operators.ADD, buildUnarySumSubList());
  81. compatibilityMap.set(Operators.SUB, buildUnarySumSubList());
  82. compatibilityMap.set(Operators.NOT, buildUnaryNegList());
  83. return compatibilityMap;
  84. }
  85. const infixMap = buildInfixCompatibilityTable();
  86. const unaryMap = buildUnaryCompatibilityTable();
  87. export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpressionType) {
  88. try {
  89. const resultType = infixMap.get(operator)[leftExpressionType.ord][rightExpressionType.ord];
  90. if (resultType === null || resultType === undefined) {
  91. return Types.UNDEFINED
  92. }
  93. return resultType;
  94. } catch (e) {
  95. if (e instanceof TypeError) {
  96. return Types.UNDEFINED;
  97. } else {
  98. throw e;
  99. }
  100. }
  101. }
  102. export function resultTypeAfterUnaryOp (operator, leftExpressionType) {
  103. try {
  104. return unaryMap.get(operator)[leftExpressionType.ord];
  105. } catch (e) {
  106. if (e instanceof TypeError) {
  107. return Types.UNDEFINED;
  108. } else {
  109. throw e;
  110. }
  111. }
  112. }