store.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. stoObj.setID(id);
  66. this.store[id] = Object.freeze(stoObj);
  67. return this;
  68. } else {
  69. const oldType = oldObj.type;
  70. const stoType = stoObj.type;
  71. // TODO: better error message
  72. throw new Error(`${oldType} is not compatible with type ${stoType} given`);
  73. }
  74. }
  75. }
  76. //In case of future use of ref, it needs to have a special function to update the storeRefObject
  77. // and no the StoreObject refferenced by it
  78. // updateStoreRef(id, stoObjAddress) {...}
  79. insertStore (id, stoObj) {
  80. if (this.store[id]) {
  81. // TODO: better error message
  82. throw new Error(`${id} is already defined`);
  83. }
  84. stoObj.setID(id);
  85. this.store[id] = Object.freeze(stoObj);
  86. return this;
  87. }
  88. /**
  89. * Helper function similar to applyStore. But it returns the actual object in the store be it ref or not
  90. * applyStore will return the refferenced object if the object in the store is a ref
  91. */
  92. getStoreObject (id) {
  93. if(!this.store[id]) {
  94. if (this.nextStore !== null) {
  95. return this.nextStore.getStoreObject(id);
  96. } else {
  97. throw new Error(`Variable ${id} not found.`);
  98. }
  99. }
  100. return this.store[id];
  101. }
  102. }