store.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { Modes } from './../modes';
  2. import { Types } from "./../../typeSystem/types";
  3. import { StoreObject } from './storeObject';
  4. export class Store {
  5. static canImplicitTypeCast (castType, sourceType) {
  6. if (castType.isCompatible(Types.INTEGER) || castType.isCompatible(Types.REAL)) {
  7. if (sourceType.isCompatible(Types.INTEGER) || sourceType.isCompatible(Types.REAL)) {
  8. return true;
  9. }
  10. }
  11. return false;
  12. }
  13. static doImplicitCasting (castType, stoObj) {
  14. if(!Store.canImplicitTypeCast(castType, stoObj.type)) {
  15. throw new Error("!!!Critical error: attempted to type cast invalid types");
  16. }
  17. if(castType.isCompatible(Types.INTEGER)) {
  18. return new StoreObject(Types.INTEGER, stoObj.value.trunc());
  19. } else {
  20. return new StoreObject(Types.REAL, stoObj.value);
  21. }
  22. }
  23. constructor(name) {
  24. this.name = name;
  25. this.store = {};
  26. this.nextStore = null;
  27. this.mode = Modes.RUN;
  28. }
  29. extendStore (nextStore) {
  30. this.nextStore = nextStore;
  31. }
  32. applyStore (id) {
  33. if(!this.store[id]) {
  34. if (this.nextStore !== null) {
  35. return this.nextStore.applyStore(id);
  36. } else {
  37. throw new Error(`Variable ${id} not found.`);
  38. }
  39. }
  40. const val = this.store[id];
  41. if (val.isRef) {
  42. return val.getRefObj();
  43. }
  44. return this.store[id];
  45. }
  46. updateStore (id, stoObj) {
  47. if(!this.store[id]) {
  48. if(this.nextStore !== null) {
  49. this.nextStore.updateStore(id, stoObj);
  50. return this;
  51. } else {
  52. // TODO: better error message
  53. throw new Error(`Variable ${id} not found.`);
  54. }
  55. } else {
  56. const oldObj = this.store[id];
  57. if(oldObj.readOnly) {
  58. // TODO: better error message
  59. throw new Error("Cannot change value of a read only variable: " + id);
  60. }
  61. if(oldObj.isRef) {
  62. oldObj.updateRef(stoObj);
  63. return this;
  64. } else if(oldObj.isCompatible(stoObj)) {
  65. const newObj = stoObj.copy();
  66. stoObj.destroy();
  67. newObj.setID(id);
  68. this.store[id].destroy();
  69. this.store[id] = newObj;
  70. return this;
  71. } else {
  72. const oldType = oldObj.type;
  73. const stoType = stoObj.type;
  74. // TODO: better error message
  75. throw new Error(`${oldType} is not compatible with type ${stoType} given`);
  76. }
  77. }
  78. }
  79. //In case of future use of ref, it needs to have a special function to update the storeRefObject
  80. // and no the StoreObject refferenced by it
  81. // updateStoreRef(id, stoObjAddress) {...}
  82. insertStore (id, stoObj) {
  83. if (this.store[id]) {
  84. // TODO: better error message
  85. throw new Error(`${id} is already defined`);
  86. }
  87. stoObj.setID(id);
  88. this.store[id] = stoObj;
  89. return this;
  90. }
  91. /**
  92. * Helper function similar to applyStore. But it returns the actual object in the store be it ref or not
  93. * applyStore will return the refferenced object if the object in the store is a ref
  94. */
  95. getStoreObject (id) {
  96. if(!this.store[id]) {
  97. if (this.nextStore !== null) {
  98. return this.nextStore.getStoreObject(id);
  99. } else {
  100. throw new Error(`Variable ${id} not found.`);
  101. }
  102. }
  103. return this.store[id];
  104. }
  105. }