circuitscript 0.0.32 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cjs/BaseVisitor.js +187 -39
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +226 -185
  3. package/dist/cjs/antlr/CircuitScriptParser.js +1439 -902
  4. package/dist/cjs/draw_symbols.js +1 -0
  5. package/dist/cjs/execute.js +14 -12
  6. package/dist/cjs/globals.js +14 -2
  7. package/dist/cjs/helpers.js +62 -19
  8. package/dist/cjs/layout.js +88 -36
  9. package/dist/cjs/objects/ClassComponent.js +3 -0
  10. package/dist/cjs/objects/ExecutionScope.js +1 -0
  11. package/dist/cjs/objects/Frame.js +4 -1
  12. package/dist/cjs/objects/ParamDefinition.js +1 -7
  13. package/dist/cjs/objects/types.js +6 -0
  14. package/dist/cjs/regenerate-tests.js +2 -1
  15. package/dist/cjs/render.js +238 -42
  16. package/dist/cjs/visitor.js +162 -27
  17. package/dist/esm/BaseVisitor.mjs +189 -41
  18. package/dist/esm/antlr/CircuitScriptLexer.mjs +226 -185
  19. package/dist/esm/antlr/CircuitScriptParser.mjs +1428 -899
  20. package/dist/esm/antlr/CircuitScriptVisitor.mjs +9 -2
  21. package/dist/esm/draw_symbols.mjs +1 -0
  22. package/dist/esm/execute.mjs +14 -12
  23. package/dist/esm/globals.mjs +13 -1
  24. package/dist/esm/helpers.mjs +61 -20
  25. package/dist/esm/layout.mjs +88 -37
  26. package/dist/esm/objects/ClassComponent.mjs +3 -0
  27. package/dist/esm/objects/ExecutionScope.mjs +1 -0
  28. package/dist/esm/objects/Frame.mjs +5 -1
  29. package/dist/esm/objects/ParamDefinition.mjs +0 -6
  30. package/dist/esm/objects/types.mjs +6 -0
  31. package/dist/esm/regenerate-tests.mjs +2 -1
  32. package/dist/esm/render.mjs +234 -43
  33. package/dist/esm/visitor.mjs +164 -29
  34. package/dist/types/BaseVisitor.d.ts +8 -2
  35. package/dist/types/antlr/CircuitScriptLexer.d.ts +41 -30
  36. package/dist/types/antlr/CircuitScriptParser.d.ts +169 -81
  37. package/dist/types/antlr/CircuitScriptVisitor.d.ts +18 -4
  38. package/dist/types/draw_symbols.d.ts +2 -1
  39. package/dist/types/execute.d.ts +6 -3
  40. package/dist/types/globals.d.ts +11 -0
  41. package/dist/types/helpers.d.ts +12 -0
  42. package/dist/types/layout.d.ts +17 -9
  43. package/dist/types/objects/ClassComponent.d.ts +2 -1
  44. package/dist/types/objects/ExecutionScope.d.ts +2 -0
  45. package/dist/types/objects/Frame.d.ts +6 -2
  46. package/dist/types/objects/ParamDefinition.d.ts +0 -4
  47. package/dist/types/objects/types.d.ts +4 -2
  48. package/dist/types/render.d.ts +6 -14
  49. package/dist/types/visitor.d.ts +10 -2
  50. package/libs/lib.cst +283 -0
  51. package/package.json +1 -1
@@ -5,10 +5,10 @@ import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor";
5
5
  import { ExecutionContext } from "./execute";
6
6
  import { Logger } from "./logger";
7
7
  import { ClassComponent } from "./objects/ClassComponent";
8
- import { NumericValue, PercentageValue, PinBlankValue } from "./objects/ParamDefinition";
8
+ import { NumericValue, PercentageValue } from "./objects/ParamDefinition";
9
9
  import { PinTypes } from "./objects/PinTypes";
10
10
  import { Direction, UndeclaredReference } from "./objects/types";
11
- import { ReferenceTypes } from './globals';
11
+ import { GlobalDocumentName, ReferenceTypes } from './globals';
12
12
  export class BaseVisitor extends CircuitScriptVisitor {
13
13
  indentLevel = 0;
14
14
  startingContext;
@@ -40,6 +40,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
40
40
  this.logger = new Logger();
41
41
  this.onErrorCallbackHandler = onErrorHandler;
42
42
  this.startingContext = new ExecutionContext('__', '__.', '/', 0, 0, silent, this.logger, null);
43
+ this.startingContext.scope.variables.set(GlobalDocumentName, {});
43
44
  this.setupPrintFunction(this.startingContext);
44
45
  this.executionStack = [this.startingContext];
45
46
  this.startingContext.resolveNet =
@@ -51,10 +52,30 @@ export class BaseVisitor extends CircuitScriptVisitor {
51
52
  getExecutor() {
52
53
  return this.executionStack[this.executionStack.length - 1];
53
54
  }
55
+ toString(obj) {
56
+ if (typeof obj === 'string') {
57
+ return `"${obj}"`;
58
+ }
59
+ else if (typeof obj === 'number') {
60
+ return obj.toString();
61
+ }
62
+ else if (Array.isArray(obj)) {
63
+ const inner = obj.map(item => this.toString(item)).join(", ");
64
+ return "[" + inner + "]";
65
+ }
66
+ else {
67
+ if (obj.toString) {
68
+ return obj.toString();
69
+ }
70
+ else {
71
+ throw "Could not create string from object: " + obj;
72
+ }
73
+ }
74
+ }
54
75
  setupPrintFunction(context) {
55
76
  context.createFunction('print', (params) => {
56
77
  const items = params.map(([, , value]) => {
57
- return value;
78
+ return this.toString(value);
58
79
  });
59
80
  if (this.printToConsole) {
60
81
  console.log('::', ...items);
@@ -62,6 +83,38 @@ export class BaseVisitor extends CircuitScriptVisitor {
62
83
  this.printStream.push(...items);
63
84
  return [this, null];
64
85
  });
86
+ context.createFunction('range', (params) => {
87
+ const items = params.map(([, , value]) => {
88
+ if (isNaN(value)) {
89
+ throw 'Invalid value: ' + value;
90
+ }
91
+ return value;
92
+ });
93
+ let startValue = 0;
94
+ let endValue = 0;
95
+ if (items.length === 1) {
96
+ endValue = items[0];
97
+ }
98
+ else if (items.length === 2) {
99
+ startValue = items[0];
100
+ endValue = items[1];
101
+ }
102
+ const returnArray = [];
103
+ for (let i = startValue; i < endValue; i++) {
104
+ returnArray.push(i);
105
+ }
106
+ return [this, returnArray];
107
+ });
108
+ context.createFunction('enumerate', (params) => {
109
+ const [, , array] = params[0];
110
+ if (!Array.isArray(array)) {
111
+ throw "Invalid parameter for enumerate function!";
112
+ }
113
+ const output = array.map((item, index) => {
114
+ return [index, item];
115
+ });
116
+ return [this, output];
117
+ });
65
118
  }
66
119
  createNetResolver(executionStack) {
67
120
  const resolveNet = (netName, netNamespace) => {
@@ -102,36 +155,103 @@ export class BaseVisitor extends CircuitScriptVisitor {
102
155
  return result;
103
156
  };
104
157
  visitAssignment_expr = (ctx) => {
105
- const atomStr = ctx.atom_expr().getText();
106
- if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
107
- throw "Invalid assignment expression!";
108
- }
109
- const ctxAtomExpr = ctx.atom_expr();
110
- this.visit(ctxAtomExpr);
111
- const reference = this.getResult(ctxAtomExpr);
158
+ const reference = this.getReference(ctx.atom_expr());
112
159
  const ctxDataExpr = ctx.data_expr();
113
160
  this.visit(ctxDataExpr);
114
161
  const value = this.getResult(ctxDataExpr);
115
- if (value instanceof ClassComponent) {
116
- const instances = this.getExecutor().scope.instances;
117
- const tmpComponent = value;
118
- const oldName = tmpComponent.instanceName;
119
- tmpComponent.instanceName = reference.name;
120
- instances.delete(oldName);
121
- instances.set(reference.name, tmpComponent);
122
- this.getExecutor().log(`assigned '${reference.name}' to ClassComponent`);
123
- }
124
- else {
125
- const trailers = reference.trailers ?? [];
126
- if (trailers.length === 0) {
162
+ const trailers = reference.trailers ?? [];
163
+ if (trailers.length === 0) {
164
+ if (value instanceof ClassComponent) {
165
+ const instances = this.getExecutor().scope.instances;
166
+ const tmpComponent = value;
167
+ const oldName = tmpComponent.instanceName;
168
+ tmpComponent.instanceName = reference.name;
169
+ instances.delete(oldName);
170
+ instances.set(reference.name, tmpComponent);
171
+ this.getExecutor().log(`assigned '${reference.name}' to ClassComponent`);
172
+ }
173
+ else {
127
174
  this.getExecutor().scope.variables.set(reference.name, value);
128
175
  }
129
- else if (reference.value instanceof ClassComponent) {
176
+ }
177
+ else {
178
+ if (reference.value instanceof ClassComponent) {
130
179
  this.setInstanceParam(reference.value, trailers, value);
131
180
  }
181
+ else if (reference.value instanceof Object) {
182
+ reference.value[trailers.join('.')] = value;
183
+ }
132
184
  }
133
185
  this.setResult(ctx, value);
134
186
  };
187
+ visitOperator_assignment_expr = (ctx) => {
188
+ const reference = this.getReference(ctx.atom_expr());
189
+ const ctxDataExpr = ctx.data_expr();
190
+ this.visit(ctxDataExpr);
191
+ const value = this.getResult(ctxDataExpr);
192
+ if (!reference.found) {
193
+ throw 'Undefined reference: ' + reference.name;
194
+ }
195
+ const trailers = reference.trailers ?? [];
196
+ let currentValue = null;
197
+ if (trailers.length === 0) {
198
+ currentValue = this.getExecutor().scope.variables.get(reference.name);
199
+ }
200
+ else {
201
+ if (reference.value instanceof ClassComponent) {
202
+ currentValue = this.getInstanceParam(reference.value, trailers);
203
+ }
204
+ else if (reference.value instanceof Object) {
205
+ currentValue = reference.value[trailers.join('.')];
206
+ }
207
+ }
208
+ if (currentValue === null) {
209
+ throw 'Operator assignment failed: could not get value';
210
+ }
211
+ let newValue = 0;
212
+ if (ctx.AdditionAssign()) {
213
+ newValue = currentValue + value;
214
+ }
215
+ else if (ctx.MinusAssign()) {
216
+ newValue = currentValue - value;
217
+ }
218
+ else if (ctx.MultiplyAssign()) {
219
+ newValue = currentValue * value;
220
+ }
221
+ else if (ctx.DivideAssign()) {
222
+ newValue = currentValue / value;
223
+ }
224
+ else if (ctx.ModulusAssign()) {
225
+ newValue = currentValue % value;
226
+ }
227
+ else {
228
+ throw 'Operator assignment failed: could not perform operator';
229
+ }
230
+ if (trailers.length === 0) {
231
+ this.getExecutor().scope.variables.set(reference.name, newValue);
232
+ }
233
+ else {
234
+ if (reference.value instanceof ClassComponent) {
235
+ this.setInstanceParam(reference.value, trailers, newValue);
236
+ }
237
+ else if (reference.value instanceof Object) {
238
+ reference.value[trailers.join('.')] = newValue;
239
+ }
240
+ }
241
+ this.setResult(ctx, newValue);
242
+ };
243
+ getReference(ctx) {
244
+ const atomStr = ctx.getText();
245
+ if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
246
+ throw "Invalid assignment expression!";
247
+ }
248
+ this.visit(ctx);
249
+ const reference = this.getResult(ctx);
250
+ if (!reference.found && reference.trailers && reference.trailers.length > 0) {
251
+ throw 'Undefined reference: ' + reference.name + '.' + reference.trailers.join('.');
252
+ }
253
+ return reference;
254
+ }
135
255
  visitAtom_expr = (ctx) => {
136
256
  const executor = this.getExecutor();
137
257
  const firstId = ctx.ID(0);
@@ -147,20 +267,22 @@ export class BaseVisitor extends CircuitScriptVisitor {
147
267
  else {
148
268
  currentReference = executor.resolveVariable(this.executionStack, atomId);
149
269
  }
270
+ const idTrailers = [];
271
+ if (ctx.ID().length > 1) {
272
+ const idLength = ctx.ID().length;
273
+ for (let i = 1; i < idLength; i++) {
274
+ const tmpCtx = ctx.ID(i);
275
+ idTrailers.push(tmpCtx.getText());
276
+ }
277
+ }
278
+ currentReference.trailers = idTrailers;
150
279
  if (currentReference.found && currentReference.type === 'instance') {
151
280
  const tmpComponent = currentReference.value;
152
281
  for (const [pinId, net] of tmpComponent.pinNets) {
153
282
  executor.scope.setNet(tmpComponent, pinId, net);
154
283
  }
155
- if (ctx.ID().length > 1) {
156
- currentReference.trailers = [];
157
- const idLength = ctx.ID().length;
158
- for (let i = 1; i < idLength; i++) {
159
- const tmpCtx = ctx.ID(i);
160
- currentReference.trailers.push(tmpCtx.getText());
161
- }
162
- }
163
284
  }
285
+ this.getExecutor().log('atomId:', atomId, currentReference);
164
286
  if (ctx.parent instanceof ExpressionContext && !currentReference.found) {
165
287
  throw "Unknown symbol: " + atomId;
166
288
  }
@@ -220,7 +342,6 @@ export class BaseVisitor extends CircuitScriptVisitor {
220
342
  const ctxBooleanValue = ctx.BOOLEAN_VALUE();
221
343
  const ctxStringValue = ctx.STRING_VALUE();
222
344
  const ctxPercentageValue = ctx.PERCENTAGE_VALUE();
223
- const ctxBlankExpr = ctx.blank_expr();
224
345
  let result = null;
225
346
  if (ctxIntegerValue || ctxDecimalValue || ctxNumericValue) {
226
347
  if (ctxIntegerValue) {
@@ -254,15 +375,8 @@ export class BaseVisitor extends CircuitScriptVisitor {
254
375
  else if (ctxPercentageValue) {
255
376
  result = new PercentageValue(ctxPercentageValue.getText());
256
377
  }
257
- else if (ctxBlankExpr) {
258
- this.visit(ctxBlankExpr);
259
- result = this.getResult(ctxBlankExpr);
260
- }
261
378
  this.setResult(ctx, result);
262
379
  };
263
- visitBlank_expr = (ctx) => {
264
- this.setResult(ctx, new PinBlankValue(Number(ctx.INTEGER_VALUE().getText())));
265
- };
266
380
  visitValueAtomExpr = (ctx) => {
267
381
  let value = null;
268
382
  const ctxValueExpr = ctx.value_expr();
@@ -344,8 +458,32 @@ export class BaseVisitor extends CircuitScriptVisitor {
344
458
  this.setResult(ctx, returnValue);
345
459
  };
346
460
  visitBreak_keyword = (ctx) => {
347
- this.getExecutor().breakBranch();
348
- this.setResult(ctx, -1);
461
+ const breakContext = this.getExecutor().getBreakContext();
462
+ const currentResult = this.getResult(breakContext) ?? {};
463
+ this.setResult(breakContext, {
464
+ ...currentResult,
465
+ breakSignal: true
466
+ });
467
+ };
468
+ visitContinue_keyword = (ctx) => {
469
+ const breakContext = this.getExecutor().getBreakContext();
470
+ const currentResult = this.getResult(breakContext) ?? {};
471
+ this.setResult(breakContext, {
472
+ ...currentResult,
473
+ breakSignal: true,
474
+ continueSignal: true,
475
+ });
476
+ };
477
+ visitArray_expr = (ctx) => {
478
+ const array = ctx.data_expr().map(item => {
479
+ this.visit(item);
480
+ return this.getResult(item);
481
+ });
482
+ this.setResult(ctx, array);
483
+ };
484
+ visitArrayExpr = (ctx) => {
485
+ this.visit(ctx.array_expr());
486
+ this.setResult(ctx, this.getResult(ctx.array_expr()));
349
487
  };
350
488
  setResult(ctx, value) {
351
489
  this.resultData.set(ctx, value);
@@ -443,9 +581,15 @@ export class BaseVisitor extends CircuitScriptVisitor {
443
581
  }
444
582
  runExpressions(executor, expressions) {
445
583
  let returnValue = null;
584
+ const breakContext = executor.getBreakContext();
446
585
  for (let i = 0; i < expressions.length; i++) {
447
586
  const expr = expressions[i];
448
587
  this.visit(expr);
588
+ const { breakSignal = false } = this.getResult(breakContext) ?? {};
589
+ if (breakSignal) {
590
+ returnValue = executor.returnValue;
591
+ break;
592
+ }
449
593
  if (executor.stopFurtherExpressions) {
450
594
  returnValue = executor.returnValue;
451
595
  break;
@@ -479,6 +623,10 @@ export class BaseVisitor extends CircuitScriptVisitor {
479
623
  object.setParam(paramName, value);
480
624
  this.getExecutor().log(`set instance ${object.instanceName} param ${paramName} to ${value}`);
481
625
  }
626
+ getInstanceParam(object, trailers) {
627
+ const paramName = trailers[0];
628
+ return object.getParam(paramName);
629
+ }
482
630
  enterNewChildContext(executionStack, parentContext, executionContextName, options, funcDefinedParameters, passedInParameters) {
483
631
  const { netNamespace = "" } = options;
484
632
  const currentExecutionContext = executionStack[executionStack.length - 1];