You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
5.6 KiB

5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. const bigInt = require("big-integer");
  2. const BigArray = require("./bigarray.js");
  3. class TableName {
  4. constructor (ctx) {
  5. this.ctx = ctx;
  6. this.o = {};
  7. }
  8. _allocElement(name, _sizes, type) {
  9. const sizes = _sizes || [];
  10. let l = 1;
  11. for (let i=0; i<sizes.length; i++) {
  12. l = l*sizes[i];
  13. }
  14. this.o[name] = {
  15. sizes: sizes,
  16. type: type
  17. };
  18. return l;
  19. }
  20. addSignal(name, sizes) {
  21. const l = this._allocElement(name, sizes, "S");
  22. const o = this.ctx.nSignals;
  23. this.o[name].offset = o;
  24. this.ctx.nSignals += l;
  25. if (l>1) {
  26. return [o, o+l];
  27. } else {
  28. return o;
  29. }
  30. }
  31. addComponent(name, sizes) {
  32. const l = this._allocElement(name, sizes, "C");
  33. const o = this.ctx.nComponents;
  34. this.o[name].offset = o;
  35. this.ctx.nComponents += l;
  36. if (l>1) {
  37. return [o, o+l];
  38. } else {
  39. return o;
  40. }
  41. }
  42. _getElement(name, _sels, type) {
  43. const sels = _sels || [];
  44. const s = this.o[name];
  45. if (!s) return -1;
  46. if (s.type != type) return -1;
  47. if (sels.length > s.sizes.length) return -1;
  48. let l=1;
  49. for (let i = s.sizes.length-1; i>sels.length; i--) {
  50. l = l*s.sizes[i];
  51. }
  52. let o =0;
  53. let p=1;
  54. for (let i=sels.length-1; i>=0; i--) {
  55. if (sels[i] > s.sizes[i]) return -1; // Out of range
  56. if (sels[i] < 0) return -1; // Out of range
  57. o += p*sels[i];
  58. p *= s.sizes[i];
  59. }
  60. if (l>1) {
  61. return [s.offset + o, s.offset + o + l];
  62. } else {
  63. return s.offset + o;
  64. }
  65. }
  66. getSignalIdx(name, sels) {
  67. return this._getElement(name, sels, "S");
  68. }
  69. getComponentIdx(name, sels) {
  70. return this._getElement(name, sels, "C");
  71. }
  72. getSizes(name) {
  73. return this.o[name].sels;
  74. }
  75. }
  76. module.exports = class Ctx {
  77. constructor() {
  78. this.stONE = 1;
  79. this.stOUTPUT = 2;
  80. this.stPUBINPUT = 3;
  81. this.stPRVINPUT = 4;
  82. this.stINTERNAL = 5;
  83. this.stDISCARDED = 6;
  84. this.stCONSTANT = 7;
  85. this.IN = 0x01;
  86. this.OUT = 0x02;
  87. this.PRV = 0x04;
  88. this.ONE = 0x08;
  89. this.MAIN = 0x10;
  90. this.COUNTED = 0x20;
  91. this.scopes = [{}];
  92. this.signals = new BigArray();
  93. this.currentComponent= -1;
  94. this.constraints= new BigArray();
  95. this.components= new BigArray();
  96. this.templates= {};
  97. this.functions= {};
  98. this.functionParams= {};
  99. this.nSignals = 0;
  100. this.nComponents =0;
  101. this.names = new TableName(this);
  102. this.main=false;
  103. this.error = null;
  104. this.warnings = [];
  105. const oneIdx = this.addSignal("one");
  106. this.signals[oneIdx] = {
  107. v: bigInt(1),
  108. o: this.ONE,
  109. e: -1,
  110. };
  111. this.uniqueNames = {};
  112. }
  113. addSignal(name, sizes) {
  114. if (this.currentComponent>=0) {
  115. return this.components[this.currentComponent].names.addSignal(name, sizes);
  116. } else {
  117. return this.names.addSignal(name, sizes);
  118. }
  119. }
  120. addComponent(name, sizes) {
  121. if (this.currentComponent>=0) {
  122. return this.components[this.currentComponent].names.addComponent(name, sizes);
  123. } else {
  124. return this.names.addComponent(name, sizes);
  125. }
  126. }
  127. getSignalIdx(name, sels) {
  128. if (this.currentComponent>=0) {
  129. return this.components[this.currentComponent].names.getSignalIdx(name, sels);
  130. } else {
  131. return this.names.getSignalIdx(name, sels);
  132. }
  133. }
  134. getComponentIdx(name, sels) {
  135. if (this.currentComponent>=0) {
  136. return this.components[this.currentComponent].names.getComponentIdx(name, sels);
  137. } else {
  138. return this.names.getComponentIdx(name, sels);
  139. }
  140. }
  141. getSizes(name) {
  142. if (this.currentComponent>=0) {
  143. return this.components[this.currentComponent].names.getSizes(name);
  144. } else {
  145. return this.names.getSizes(name);
  146. }
  147. }
  148. newTableName() {
  149. return new TableName(this);
  150. }
  151. _buildErr(ast, errStr) {
  152. if (typeof ast == "string") {
  153. ast = null;
  154. errStr = ast;
  155. }
  156. if (ast) {
  157. return {
  158. pos: {
  159. first_line: ast.first_line,
  160. first_column: ast.first_column,
  161. last_line: ast.last_line,
  162. last_column: ast.last_column
  163. },
  164. errStr: errStr,
  165. ast: ast,
  166. message: errStr,
  167. errFile: this.fileName
  168. };
  169. } else {
  170. return {
  171. errStr: errStr,
  172. message: errStr
  173. };
  174. }
  175. }
  176. throwError(ast, errStr) {
  177. const err = this._buildErr(ast, errStr);
  178. this.error = err;
  179. }
  180. logWarning(ast, errStr) {
  181. const w = this._buildErr(ast, errStr);
  182. this.warnings.push(w);
  183. }
  184. getUniqueName(suggestedName) {
  185. if (!suggestedName) {
  186. suggestedName = "_tmp";
  187. }
  188. if (typeof(this.uniqueNames[suggestedName]) == "undefined") {
  189. this.uniqueNames[suggestedName] = 1;
  190. return suggestedName;
  191. } else {
  192. const name = suggestedName + "_" + this.uniqueNames[suggestedName];
  193. this.uniqueNames[suggestedName]++;
  194. return name;
  195. }
  196. }
  197. };