circuitscript 0.1.15 → 0.1.17
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.
- package/dist/cjs/BaseVisitor.js +98 -35
- package/dist/cjs/antlr/CircuitScriptLexer.js +3 -3
- package/dist/cjs/antlr/CircuitScriptParser.js +868 -757
- package/dist/cjs/builtinMethods.js +11 -1
- package/dist/cjs/draw_symbols.js +18 -17
- package/dist/cjs/execute.js +58 -31
- package/dist/cjs/globals.js +4 -1
- package/dist/cjs/graph.js +372 -0
- package/dist/cjs/helpers.js +6 -2
- package/dist/cjs/layout.js +18 -259
- package/dist/cjs/objects/ClassComponent.js +27 -20
- package/dist/cjs/objects/ExecutionScope.js +7 -2
- package/dist/cjs/objects/Net.js +1 -1
- package/dist/cjs/objects/PinDefinition.js +55 -3
- package/dist/cjs/objects/types.js +42 -6
- package/dist/cjs/visitor.js +88 -48
- package/dist/esm/BaseVisitor.js +98 -35
- package/dist/esm/antlr/CircuitScriptLexer.js +3 -3
- package/dist/esm/antlr/CircuitScriptParser.js +864 -755
- package/dist/esm/antlr/CircuitScriptVisitor.js +2 -0
- package/dist/esm/builtinMethods.js +11 -1
- package/dist/esm/draw_symbols.js +18 -17
- package/dist/esm/execute.js +60 -33
- package/dist/esm/globals.js +3 -0
- package/dist/esm/graph.js +344 -0
- package/dist/esm/helpers.js +6 -2
- package/dist/esm/layout.js +14 -235
- package/dist/esm/objects/ClassComponent.js +28 -21
- package/dist/esm/objects/ExecutionScope.js +7 -2
- package/dist/esm/objects/Net.js +1 -1
- package/dist/esm/objects/PinDefinition.js +53 -2
- package/dist/esm/objects/types.js +42 -6
- package/dist/esm/visitor.js +90 -50
- package/dist/libs/std.cst +3 -2
- package/dist/types/BaseVisitor.d.ts +5 -2
- package/dist/types/antlr/CircuitScriptParser.d.ts +42 -26
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +4 -0
- package/dist/types/draw_symbols.d.ts +13 -7
- package/dist/types/execute.d.ts +12 -12
- package/dist/types/globals.d.ts +4 -1
- package/dist/types/graph.d.ts +29 -0
- package/dist/types/layout.d.ts +4 -9
- package/dist/types/objects/ClassComponent.d.ts +8 -8
- package/dist/types/objects/ExecutionScope.d.ts +8 -7
- package/dist/types/objects/Net.d.ts +2 -2
- package/dist/types/objects/PinDefinition.d.ts +17 -2
- package/dist/types/objects/types.d.ts +31 -7
- package/libs/std.cst +3 -2
- package/package.json +2 -1
package/dist/cjs/visitor.js
CHANGED
|
@@ -22,19 +22,23 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
22
22
|
this.setResult(ctx, [id, value]);
|
|
23
23
|
};
|
|
24
24
|
this.visitPin_select_expr = (ctx) => {
|
|
25
|
-
let
|
|
25
|
+
let pinId = null;
|
|
26
26
|
const ctxData = ctx.data_expr();
|
|
27
27
|
const result = this.visitResult(ctxData);
|
|
28
|
+
let pinValue;
|
|
28
29
|
if (result instanceof ParamDefinition_js_1.NumericValue) {
|
|
29
|
-
|
|
30
|
+
pinValue = result.toNumber();
|
|
30
31
|
}
|
|
31
32
|
else if (typeof result === 'string') {
|
|
32
|
-
|
|
33
|
+
pinValue = result;
|
|
33
34
|
}
|
|
34
35
|
else {
|
|
35
|
-
throw new utils_js_2.RuntimeExecutionError("Invalid
|
|
36
|
+
throw new utils_js_2.RuntimeExecutionError("Invalid select pin: " + result, ctx);
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
if (pinValue !== undefined) {
|
|
39
|
+
pinId = new PinDefinition_js_1.PinId(pinValue);
|
|
40
|
+
}
|
|
41
|
+
this.setResult(ctx, pinId);
|
|
38
42
|
};
|
|
39
43
|
this.visitAdd_component_expr = (ctx) => {
|
|
40
44
|
const [component, pinValue] = this.visitResult(ctx.data_expr_with_assignment());
|
|
@@ -221,11 +225,18 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
221
225
|
}
|
|
222
226
|
}
|
|
223
227
|
else {
|
|
224
|
-
if (!(value instanceof ParamDefinition_js_1.NumericValue)) {
|
|
228
|
+
if (!(value instanceof ParamDefinition_js_1.NumericValue) && !(typeof value === 'string')) {
|
|
225
229
|
throw new utils_js_2.RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx);
|
|
226
230
|
}
|
|
227
231
|
else {
|
|
228
|
-
|
|
232
|
+
let useValue;
|
|
233
|
+
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
234
|
+
useValue = value.toNumber();
|
|
235
|
+
}
|
|
236
|
+
else if (typeof value === 'string') {
|
|
237
|
+
useValue = value;
|
|
238
|
+
}
|
|
239
|
+
value && checkPinExistsAndNotDuplicated(useValue, ctx);
|
|
229
240
|
}
|
|
230
241
|
}
|
|
231
242
|
}
|
|
@@ -265,7 +276,6 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
265
276
|
scope.exitContext();
|
|
266
277
|
scope.popOnPropertyHandler();
|
|
267
278
|
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
268
|
-
const pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
269
279
|
let instanceName = this.getExecutor().getUniqueInstanceName();
|
|
270
280
|
const propParams = properties.get('params');
|
|
271
281
|
const params = this.parseCreateComponentParams(propParams);
|
|
@@ -278,11 +288,11 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
278
288
|
}
|
|
279
289
|
instanceName += `${globals_js_1.Delimiter1}${appendValue}`;
|
|
280
290
|
}
|
|
281
|
-
const
|
|
291
|
+
const arrangeProp = properties.has('arrange') ?
|
|
282
292
|
properties.get('arrange') : null;
|
|
283
|
-
const
|
|
293
|
+
const displayProp = properties.has('display') ?
|
|
284
294
|
properties.get('display') : null;
|
|
285
|
-
const
|
|
295
|
+
const typeProp = properties.has('type') ?
|
|
286
296
|
properties.get('type') : null;
|
|
287
297
|
const copy = properties.has('copy') ?
|
|
288
298
|
properties.get('copy') : false;
|
|
@@ -294,8 +304,29 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
294
304
|
properties.get(globals_js_1.ParamKeys.angle) : null;
|
|
295
305
|
const followWireOrientation = properties.has('followWireOrientation') ?
|
|
296
306
|
properties.get('followWireOrientation') : true;
|
|
307
|
+
let pins = [];
|
|
308
|
+
if (displayProp !== null && arrangeProp === null
|
|
309
|
+
&& typeProp !== types_js_1.TypeProps.Graphic) {
|
|
310
|
+
const drawCommands = displayProp.getCommands();
|
|
311
|
+
drawCommands.forEach(command => {
|
|
312
|
+
const [commandValue,] = command;
|
|
313
|
+
if (commandValue === draw_symbols_js_1.PlaceHolderCommands.vpin
|
|
314
|
+
|| commandValue === draw_symbols_js_1.PlaceHolderCommands.hpin
|
|
315
|
+
|| commandValue === draw_symbols_js_1.PlaceHolderCommands.pin) {
|
|
316
|
+
const id = PinDefinition_js_1.PinId.from(command[1][0]);
|
|
317
|
+
const pinType = id.getType();
|
|
318
|
+
const pinName = id.toString();
|
|
319
|
+
pins.push(new PinDefinition_js_1.PinDefinition(id, pinType, pinName, PinTypes_js_1.PinTypes.Any));
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
325
|
+
}
|
|
297
326
|
const props = {
|
|
298
|
-
arrange
|
|
327
|
+
arrange: arrangeProp,
|
|
328
|
+
display: displayProp,
|
|
329
|
+
type: typeProp, width, height, copy,
|
|
299
330
|
angle, followWireOrientation
|
|
300
331
|
};
|
|
301
332
|
try {
|
|
@@ -381,7 +412,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
381
412
|
if (ctxNestedProperties) {
|
|
382
413
|
const nestedKeyValues = this.visitResult(ctxNestedProperties);
|
|
383
414
|
nestedKeyValues.forEach((value, key) => {
|
|
384
|
-
parameters.push(['keyword', key, value]);
|
|
415
|
+
parameters.push(['keyword', key, (0, utils_js_1.unwrapValue)(value)]);
|
|
385
416
|
});
|
|
386
417
|
}
|
|
387
418
|
else {
|
|
@@ -539,36 +570,36 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
539
570
|
this.setResult(ctx, result);
|
|
540
571
|
};
|
|
541
572
|
this.visitData_expr_with_assignment = (ctx) => {
|
|
542
|
-
let
|
|
543
|
-
let componentCtx
|
|
573
|
+
let dataResult = null;
|
|
574
|
+
let componentCtx;
|
|
544
575
|
const ctxDataExpr = ctx.data_expr();
|
|
545
576
|
const ctxAssignmentExpr = ctx.assignment_expr();
|
|
546
577
|
if (ctxDataExpr) {
|
|
547
|
-
|
|
548
|
-
component = (0, utils_js_1.unwrapValue)(component);
|
|
578
|
+
dataResult = this.visitResult(ctxDataExpr);
|
|
549
579
|
componentCtx = ctxDataExpr;
|
|
550
|
-
if (component === null || component === undefined) {
|
|
551
|
-
this.throwWithContext(ctxDataExpr, "Could not find component: " + ctxDataExpr.getText());
|
|
552
|
-
}
|
|
553
580
|
}
|
|
554
581
|
else if (ctxAssignmentExpr) {
|
|
555
|
-
|
|
582
|
+
dataResult = this.visitResult(ctxAssignmentExpr);
|
|
556
583
|
componentCtx = ctxAssignmentExpr;
|
|
557
584
|
}
|
|
558
|
-
if (
|
|
559
|
-
|
|
560
|
-
component = this.getExecutor().copyComponent(component);
|
|
561
|
-
}
|
|
562
|
-
if (component instanceof types_js_1.UndeclaredReference) {
|
|
563
|
-
const { reference: { trailers = [], parentValue = null } } = component;
|
|
585
|
+
if (dataResult instanceof types_js_1.AnyReference) {
|
|
586
|
+
const { trailers = [], parentValue = null } = dataResult;
|
|
564
587
|
if (parentValue instanceof ClassComponent_js_1.ClassComponent
|
|
565
588
|
&& trailers.length > 0
|
|
566
589
|
&& trailers[0] === globals_js_1.ModuleContainsKeyword) {
|
|
567
|
-
|
|
568
|
-
this.placeModuleContains(
|
|
590
|
+
dataResult = parentValue;
|
|
591
|
+
this.placeModuleContains(dataResult);
|
|
569
592
|
}
|
|
570
593
|
}
|
|
571
|
-
|
|
594
|
+
dataResult = (0, utils_js_1.unwrapValue)(dataResult);
|
|
595
|
+
if (dataResult === null || dataResult === undefined) {
|
|
596
|
+
this.throwWithContext(componentCtx, "Could not find component: " + componentCtx.getText());
|
|
597
|
+
}
|
|
598
|
+
if (dataResult instanceof ClassComponent_js_1.ClassComponent
|
|
599
|
+
&& dataResult.copyProp) {
|
|
600
|
+
dataResult = this.getExecutor().copyComponent(dataResult);
|
|
601
|
+
}
|
|
602
|
+
if (dataResult && dataResult instanceof ClassComponent_js_1.ClassComponent) {
|
|
572
603
|
const modifiers = ctx.component_modifier_expr();
|
|
573
604
|
modifiers.forEach(modifier => {
|
|
574
605
|
const modifierText = modifier.ID(0).getText();
|
|
@@ -585,23 +616,23 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
585
616
|
if (modifierText === globals_js_1.ParamKeys.flip) {
|
|
586
617
|
const flipValue = result;
|
|
587
618
|
if (flipValue.indexOf('x') !== -1) {
|
|
588
|
-
|
|
619
|
+
dataResult.setParam(globals_js_1.ParamKeys.flipX, 1);
|
|
589
620
|
shouldIgnoreWireOrientation = true;
|
|
590
621
|
}
|
|
591
622
|
if (flipValue.indexOf('y') !== -1) {
|
|
592
|
-
|
|
623
|
+
dataResult.setParam(globals_js_1.ParamKeys.flipY, 1);
|
|
593
624
|
shouldIgnoreWireOrientation = true;
|
|
594
625
|
}
|
|
595
626
|
}
|
|
596
627
|
else if (modifierText === globals_js_1.ParamKeys.angle) {
|
|
597
|
-
|
|
628
|
+
dataResult.setParam(globals_js_1.ParamKeys.angle, result);
|
|
598
629
|
shouldIgnoreWireOrientation = true;
|
|
599
630
|
}
|
|
600
631
|
else if (modifierText === 'anchor') {
|
|
601
|
-
|
|
632
|
+
dataResult.setParam('anchor', result);
|
|
602
633
|
}
|
|
603
634
|
if (shouldIgnoreWireOrientation) {
|
|
604
|
-
|
|
635
|
+
dataResult.useWireOrientationAngle = false;
|
|
605
636
|
}
|
|
606
637
|
});
|
|
607
638
|
}
|
|
@@ -611,15 +642,15 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
611
642
|
pinValue = this.visitResult(ctxPinSelectExpr);
|
|
612
643
|
}
|
|
613
644
|
else {
|
|
614
|
-
if (
|
|
615
|
-
pinValue =
|
|
645
|
+
if (dataResult instanceof ClassComponent_js_1.ClassComponent) {
|
|
646
|
+
pinValue = dataResult.getDefaultPin();
|
|
616
647
|
}
|
|
617
648
|
else {
|
|
618
|
-
const undeclaredRef =
|
|
649
|
+
const undeclaredRef = dataResult;
|
|
619
650
|
this.throwWithContext(componentCtx, 'Invalid component: ' + undeclaredRef.reference.name);
|
|
620
651
|
}
|
|
621
652
|
}
|
|
622
|
-
this.setResult(ctx, [
|
|
653
|
+
this.setResult(ctx, [dataResult, pinValue]);
|
|
623
654
|
};
|
|
624
655
|
this.visitUnaryOperatorExpr = (ctx) => {
|
|
625
656
|
let value = this.visitResult(ctx.data_expr());
|
|
@@ -749,8 +780,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
749
780
|
this.setResult(ctx, result);
|
|
750
781
|
};
|
|
751
782
|
this.visitAdditionExpr = (ctx) => {
|
|
752
|
-
const value1 = this.resolveDataExpr(ctx.data_expr(0));
|
|
753
|
-
const value2 = this.resolveDataExpr(ctx.data_expr(1));
|
|
783
|
+
const value1 = (0, utils_js_1.unwrapValue)(this.resolveDataExpr(ctx.data_expr(0)));
|
|
784
|
+
const value2 = (0, utils_js_1.unwrapValue)(this.resolveDataExpr(ctx.data_expr(1)));
|
|
754
785
|
if (ctx.Addition() && (typeof value1 === 'string' || typeof value2 === 'string')) {
|
|
755
786
|
let tmpValue1 = value1;
|
|
756
787
|
if (value1 instanceof ParamDefinition_js_1.NumericValue) {
|
|
@@ -779,6 +810,8 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
779
810
|
};
|
|
780
811
|
this.visitFunction_def_expr = (ctx) => {
|
|
781
812
|
const functionName = ctx.ID().getText();
|
|
813
|
+
const uniqueFunctionID = '__._' + ctx.start.line + '_'
|
|
814
|
+
+ ctx.start.column + '_' + functionName + '_' + ctx.getText();
|
|
782
815
|
let funcDefinedParameters = [];
|
|
783
816
|
const ctxFunctionArgsExpr = ctx.function_args_expr();
|
|
784
817
|
if (ctxFunctionArgsExpr) {
|
|
@@ -800,19 +833,26 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
800
833
|
nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
801
834
|
return [lastExecution, returnValue];
|
|
802
835
|
};
|
|
803
|
-
this.getExecutor().createFunction(functionName, __runFunc);
|
|
836
|
+
this.getExecutor().createFunction(functionName, __runFunc, ctx, uniqueFunctionID);
|
|
804
837
|
};
|
|
805
838
|
this.visitPin_select_expr2 = (ctx) => {
|
|
806
839
|
const ctxStringValue = ctx.STRING_VALUE();
|
|
807
840
|
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
808
|
-
let
|
|
841
|
+
let pinIdValue;
|
|
842
|
+
let pinId = null;
|
|
809
843
|
if (ctxStringValue) {
|
|
810
|
-
|
|
844
|
+
pinIdValue = this.prepareStringValue(ctxStringValue.getText());
|
|
811
845
|
}
|
|
812
846
|
else if (ctxIntegerValue) {
|
|
813
|
-
|
|
847
|
+
pinIdValue = Number(ctxIntegerValue.getText());
|
|
814
848
|
}
|
|
815
|
-
|
|
849
|
+
if (pinIdValue !== undefined) {
|
|
850
|
+
pinId = new PinDefinition_js_1.PinId(pinIdValue);
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
throw new utils_js_2.RuntimeExecutionError("Invalid select pin", ctx);
|
|
854
|
+
}
|
|
855
|
+
this.setResult(ctx, pinId);
|
|
816
856
|
};
|
|
817
857
|
this.visitAt_block_pin_expr = (ctx) => {
|
|
818
858
|
const executor = this.getExecutor();
|
|
@@ -1204,7 +1244,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1204
1244
|
return item;
|
|
1205
1245
|
}
|
|
1206
1246
|
else {
|
|
1207
|
-
return
|
|
1247
|
+
return new PinDefinition_js_1.PinId(nameToPinId.get(item));
|
|
1208
1248
|
}
|
|
1209
1249
|
});
|
|
1210
1250
|
if (items.length > 0) {
|
|
@@ -1295,7 +1335,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1295
1335
|
getGraph() {
|
|
1296
1336
|
const executor = this.getExecutor();
|
|
1297
1337
|
const fullSequence = executor.scope.sequence;
|
|
1298
|
-
const tmpNet = executor.scope.getNet(executor.scope.componentRoot, 1);
|
|
1338
|
+
const tmpNet = executor.scope.getNet(executor.scope.componentRoot, new PinDefinition_js_1.PinId(1));
|
|
1299
1339
|
const sequence = (tmpNet === null)
|
|
1300
1340
|
? fullSequence.slice(1) : fullSequence;
|
|
1301
1341
|
const nets = executor.scope.getNets();
|
package/dist/esm/BaseVisitor.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Big } from 'big.js';
|
|
2
|
-
import { ExpressionContext } from "./antlr/CircuitScriptParser.js";
|
|
3
2
|
import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor.js";
|
|
4
3
|
import { ExecutionContext } from "./execute.js";
|
|
5
4
|
import { Logger } from "./logger.js";
|
|
@@ -7,11 +6,12 @@ import { ClassComponent } from "./objects/ClassComponent.js";
|
|
|
7
6
|
import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition.js";
|
|
8
7
|
import { PinTypes } from "./objects/PinTypes.js";
|
|
9
8
|
import { Direction, AnyReference, UndeclaredReference } from "./objects/types.js";
|
|
10
|
-
import { ComponentTypes, DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals.js';
|
|
9
|
+
import { ComponentTypes, DoubleDelimiter1, GlobalDocumentName, ReferenceTypes, TrailerArrayIndex } from './globals.js';
|
|
11
10
|
import { isReference, unwrapValue as unwrapValue } from "./utils.js";
|
|
12
11
|
import { linkBuiltInMethods } from './builtinMethods.js';
|
|
13
12
|
import { resolveToNumericValue, RuntimeExecutionError, throwWithContext } from './utils.js';
|
|
14
13
|
import { SequenceAction } from './objects/ExecutionScope.js';
|
|
14
|
+
import { PinId } from './objects/PinDefinition.js';
|
|
15
15
|
export class BaseVisitor extends CircuitScriptVisitor {
|
|
16
16
|
indentLevel = 0;
|
|
17
17
|
startingContext;
|
|
@@ -134,28 +134,37 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
134
134
|
const ctxAtom = ctx.atom_expr();
|
|
135
135
|
const ctxFuncCallRef = ctx.function_call_expr();
|
|
136
136
|
let leftSideReference;
|
|
137
|
+
let lhsCtx;
|
|
137
138
|
if (ctxAtom) {
|
|
138
139
|
leftSideReference = this.getReference(ctx.atom_expr());
|
|
140
|
+
lhsCtx = ctxAtom;
|
|
139
141
|
}
|
|
140
142
|
else if (ctxFuncCallRef) {
|
|
141
143
|
this.setResult(ctxFuncCallRef, { keepReference: true });
|
|
142
144
|
leftSideReference = this.visitResult(ctxFuncCallRef);
|
|
145
|
+
lhsCtx = ctxFuncCallRef;
|
|
146
|
+
}
|
|
147
|
+
const rhsCtx = ctx.data_expr();
|
|
148
|
+
const rhsCtxResult = this.visitResult(rhsCtx);
|
|
149
|
+
if (isReference(rhsCtxResult) && !rhsCtxResult.found) {
|
|
150
|
+
this.throwWithContext(rhsCtx, rhsCtx.getText() + ' is not defined');
|
|
143
151
|
}
|
|
144
|
-
const rhsCtxResult = this.visitResult(ctx.data_expr());
|
|
145
152
|
const rhsValue = unwrapValue(rhsCtxResult);
|
|
146
153
|
const trailers = leftSideReference.trailers ?? [];
|
|
147
154
|
const sequenceParts = [];
|
|
148
155
|
if (trailers.length === 0) {
|
|
156
|
+
this.getScope().setVariable(leftSideReference.name, rhsValue);
|
|
157
|
+
let itemType = '';
|
|
149
158
|
if (rhsValue instanceof ClassComponent) {
|
|
150
|
-
|
|
151
|
-
sequenceParts.push(...['instance', leftSideReference.name, rhsValue]);
|
|
159
|
+
itemType = ReferenceTypes.instance;
|
|
152
160
|
this.log2(`assigned '${leftSideReference.name}' to ClassComponent`);
|
|
153
161
|
}
|
|
154
162
|
else {
|
|
163
|
+
itemType = ReferenceTypes.variable;
|
|
155
164
|
this.getScope().setVariable(leftSideReference.name, rhsValue);
|
|
156
165
|
this.log2(`assigned variable ${leftSideReference.name} to ${rhsValue}`);
|
|
157
|
-
sequenceParts.push(...['variable', leftSideReference.name, rhsValue]);
|
|
158
166
|
}
|
|
167
|
+
sequenceParts.push(...[itemType, leftSideReference.name, rhsValue]);
|
|
159
168
|
}
|
|
160
169
|
else {
|
|
161
170
|
if (leftSideReference.parentValue instanceof ClassComponent) {
|
|
@@ -163,7 +172,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
163
172
|
this.log2(`assigned component param ${leftSideReference.parentValue} trailers: ${trailers} value: ${rhsValue}`);
|
|
164
173
|
sequenceParts.push(...['instance', [leftSideReference.parentValue, trailers], rhsValue]);
|
|
165
174
|
if (leftSideReference.parentValue.typeProp === ComponentTypes.net) {
|
|
166
|
-
const net = this.getScope().getNet(leftSideReference.parentValue, 1);
|
|
175
|
+
const net = this.getScope().getNet(leftSideReference.parentValue, new PinId(1));
|
|
167
176
|
if (net) {
|
|
168
177
|
const trailerValue = trailers.join(".");
|
|
169
178
|
net.params.set(trailerValue, rhsValue);
|
|
@@ -171,8 +180,20 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
171
180
|
}
|
|
172
181
|
}
|
|
173
182
|
else if (leftSideReference.parentValue instanceof Object) {
|
|
174
|
-
|
|
175
|
-
|
|
183
|
+
if (Array.isArray(trailers[0]) && trailers[0][0] === TrailerArrayIndex) {
|
|
184
|
+
if (Array.isArray(leftSideReference.parentValue)) {
|
|
185
|
+
const arrayIndexValue = trailers[0][1];
|
|
186
|
+
leftSideReference.parentValue[arrayIndexValue] = rhsValue;
|
|
187
|
+
this.log2(`assigned array index ${leftSideReference.parentValue} index: ${arrayIndexValue} value: ${rhsValue}`);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
this.throwWithContext(lhsCtx, "Invalid array");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
leftSideReference.parentValue[trailers.join('.')] = rhsValue;
|
|
195
|
+
this.log2(`assigned object ${leftSideReference.parentValue} trailers: ${trailers} value: ${rhsValue}`);
|
|
196
|
+
}
|
|
176
197
|
sequenceParts.push(...['variable', [leftSideReference.parentValue, trailers], rhsValue]);
|
|
177
198
|
}
|
|
178
199
|
}
|
|
@@ -252,19 +273,39 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
252
273
|
}
|
|
253
274
|
return reference;
|
|
254
275
|
}
|
|
276
|
+
visitTrailer_expr2 = (ctx) => {
|
|
277
|
+
const reference = this.getResult(ctx);
|
|
278
|
+
const ctxID = ctx.ID();
|
|
279
|
+
const ctxDataExpr = ctx.data_expr();
|
|
280
|
+
const useValue = reference.value;
|
|
281
|
+
let nextReference;
|
|
282
|
+
if (ctxID) {
|
|
283
|
+
reference.trailers.push(ctxID.getText());
|
|
284
|
+
nextReference = this.getExecutor().resolveTrailers(reference.type, useValue, reference.trailers);
|
|
285
|
+
}
|
|
286
|
+
else if (ctxDataExpr) {
|
|
287
|
+
const arrayIndex = this.visitResult(ctxDataExpr);
|
|
288
|
+
if (arrayIndex instanceof NumericValue) {
|
|
289
|
+
const arrayIndexValue = arrayIndex.toNumber();
|
|
290
|
+
const foundValue = useValue[arrayIndexValue];
|
|
291
|
+
const refType = foundValue instanceof ClassComponent
|
|
292
|
+
? ReferenceTypes.instance : ReferenceTypes.variable;
|
|
293
|
+
nextReference = new AnyReference({
|
|
294
|
+
found: true,
|
|
295
|
+
type: refType,
|
|
296
|
+
value: foundValue,
|
|
297
|
+
trailers: [[TrailerArrayIndex, arrayIndexValue]],
|
|
298
|
+
parentValue: useValue
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
this.setResult(ctx, nextReference);
|
|
303
|
+
};
|
|
255
304
|
visitAtom_expr = (ctx) => {
|
|
256
305
|
const executor = this.getExecutor();
|
|
257
306
|
const firstId = ctx.ID(0);
|
|
258
307
|
const atomId = firstId.getText();
|
|
259
308
|
let currentReference;
|
|
260
|
-
const idTrailers = [];
|
|
261
|
-
if (ctx.ID().length > 1) {
|
|
262
|
-
const idLength = ctx.ID().length;
|
|
263
|
-
for (let i = 1; i < idLength; i++) {
|
|
264
|
-
const tmpCtx = ctx.ID(i);
|
|
265
|
-
idTrailers.push(tmpCtx.getText());
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
309
|
if (this.pinTypesList.indexOf(atomId) !== -1) {
|
|
269
310
|
currentReference = new AnyReference({
|
|
270
311
|
found: true,
|
|
@@ -273,18 +314,18 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
273
314
|
});
|
|
274
315
|
}
|
|
275
316
|
else {
|
|
276
|
-
currentReference = executor.resolveVariable(this.executionStack, atomId
|
|
317
|
+
currentReference = executor.resolveVariable(this.executionStack, atomId);
|
|
277
318
|
}
|
|
278
|
-
if (currentReference
|
|
279
|
-
const
|
|
280
|
-
for (
|
|
281
|
-
|
|
319
|
+
if (currentReference !== undefined && currentReference.found) {
|
|
320
|
+
const trailersLength = ctx.trailer_expr2().length;
|
|
321
|
+
for (let i = 0; i < trailersLength; i++) {
|
|
322
|
+
const trailerCtx = ctx.trailer_expr2(i);
|
|
323
|
+
this.setResult(trailerCtx, currentReference);
|
|
324
|
+
currentReference = this.visitResult(trailerCtx);
|
|
282
325
|
}
|
|
283
326
|
}
|
|
284
|
-
if (ctx.parent instanceof ExpressionContext && !currentReference.found) {
|
|
285
|
-
this.throwWithContext(ctx, "Unknown symbol: " + atomId);
|
|
286
|
-
}
|
|
287
327
|
this.setResult(ctx, currentReference);
|
|
328
|
+
this.log2('atom resolved: ' + ctx.getText() + ' -> ' + currentReference);
|
|
288
329
|
};
|
|
289
330
|
visitFunctionCallExpr = (ctx) => {
|
|
290
331
|
const result = this.visitResult(ctx.function_call_expr());
|
|
@@ -315,6 +356,11 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
315
356
|
currentReference.trailers = [];
|
|
316
357
|
ctx.trailer_expr().forEach(item => {
|
|
317
358
|
if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
|
|
359
|
+
if (currentReference.type === ReferenceTypes.variable) {
|
|
360
|
+
if (currentReference.value instanceof AnyReference && currentReference.value.type === ReferenceTypes.function) {
|
|
361
|
+
currentReference = currentReference.value;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
318
364
|
let parameters = [];
|
|
319
365
|
const ctxParameters = item.parameters();
|
|
320
366
|
if (ctxParameters) {
|
|
@@ -341,10 +387,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
341
387
|
}
|
|
342
388
|
}
|
|
343
389
|
else {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
: currentReference.value, currentReference.trailers);
|
|
390
|
+
const ctxTrailer = item.trailer_expr2();
|
|
391
|
+
this.setResult(ctxTrailer, currentReference);
|
|
392
|
+
currentReference = this.visitResult(ctxTrailer);
|
|
348
393
|
}
|
|
349
394
|
});
|
|
350
395
|
}
|
|
@@ -410,7 +455,8 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
410
455
|
value = reference;
|
|
411
456
|
}
|
|
412
457
|
else {
|
|
413
|
-
if (reference.trailers && reference.trailers.length > 0)
|
|
458
|
+
if ((reference.trailers && reference.trailers.length > 0)
|
|
459
|
+
|| reference.type === ReferenceTypes.function) {
|
|
414
460
|
value = reference;
|
|
415
461
|
}
|
|
416
462
|
else {
|
|
@@ -445,11 +491,11 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
445
491
|
const returnList = [];
|
|
446
492
|
dataExpressions.forEach((item, index) => {
|
|
447
493
|
const value = this.visitResult(item);
|
|
448
|
-
returnList.push(['position', index, value]);
|
|
494
|
+
returnList.push(['position', index, unwrapValue(value)]);
|
|
449
495
|
});
|
|
450
496
|
keywordAssignmentExpressions.forEach((item) => {
|
|
451
497
|
const [key, value] = this.visitResult(item);
|
|
452
|
-
returnList.push(['keyword', key, value]);
|
|
498
|
+
returnList.push(['keyword', key, unwrapValue(value)]);
|
|
453
499
|
});
|
|
454
500
|
this.setResult(ctx, returnList);
|
|
455
501
|
};
|
|
@@ -459,9 +505,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
459
505
|
visitFunction_return_expr = (ctx) => {
|
|
460
506
|
const executor = this.getExecutor();
|
|
461
507
|
executor.log('return from function');
|
|
462
|
-
const
|
|
463
|
-
this.visit(ctxDataExpr);
|
|
464
|
-
const returnValue = this.getResult(ctxDataExpr);
|
|
508
|
+
const returnValue = this.visitResult(ctx.data_expr());
|
|
465
509
|
executor.stopFurtherExpressions = true;
|
|
466
510
|
executor.returnValue = returnValue;
|
|
467
511
|
this.setResult(ctx, returnValue);
|
|
@@ -495,6 +539,25 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
495
539
|
visitArrayExpr = (ctx) => {
|
|
496
540
|
this.setResult(ctx, this.visitResult(ctx.array_expr()));
|
|
497
541
|
};
|
|
542
|
+
visitArrayIndexExpr = (ctx) => {
|
|
543
|
+
const ctxArray = ctx.data_expr(0);
|
|
544
|
+
const ctxArrayIndex = ctx.data_expr(1);
|
|
545
|
+
const arrayItem = this.visitResult(ctxArray);
|
|
546
|
+
const indexValue = this.visitResult(ctxArrayIndex);
|
|
547
|
+
if (!Array.isArray(arrayItem)) {
|
|
548
|
+
throw new RuntimeExecutionError("Invalid array", ctxArray);
|
|
549
|
+
}
|
|
550
|
+
if (!(indexValue instanceof NumericValue)) {
|
|
551
|
+
throw new RuntimeExecutionError("Invalid index value", ctxArrayIndex);
|
|
552
|
+
}
|
|
553
|
+
const indexValueNumber = indexValue.toNumber();
|
|
554
|
+
if (isNaN(indexValueNumber)) {
|
|
555
|
+
throw new RuntimeExecutionError("Invalid index value", ctxArrayIndex);
|
|
556
|
+
}
|
|
557
|
+
if (Array.isArray(arrayItem)) {
|
|
558
|
+
this.setResult(ctx, arrayItem[indexValueNumber]);
|
|
559
|
+
}
|
|
560
|
+
};
|
|
498
561
|
setResult(ctx, value) {
|
|
499
562
|
this.resultData.set(ctx, value);
|
|
500
563
|
}
|
|
@@ -69,7 +69,7 @@ export class CircuitScriptLexer extends antlr.Lexer {
|
|
|
69
69
|
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
|
70
70
|
];
|
|
71
71
|
static literalNames = [
|
|
72
|
-
null, "':'", "','", "'='", "'..'", "'
|
|
72
|
+
null, "':'", "','", "'='", "'..'", "'['", "']'", "'.'", "'break'",
|
|
73
73
|
"'branch'", "'create'", "'component'", "'graphic'", "'module'",
|
|
74
74
|
"'wire'", "'pin'", "'add'", "'at'", "'to'", "'point'", "'join'",
|
|
75
75
|
"'parallel'", "'return'", "'def'", "'import'", "'for'", "'in'",
|
|
@@ -235,8 +235,8 @@ export class CircuitScriptLexer extends antlr.Lexer {
|
|
|
235
235
|
0, 131, 473, 1, 0, 0, 0, 133, 477, 1, 0, 0, 0, 135, 486, 1, 0, 0, 0, 137, 138, 5, 58, 0,
|
|
236
236
|
0, 138, 2, 1, 0, 0, 0, 139, 140, 5, 44, 0, 0, 140, 4, 1, 0, 0, 0, 141, 142, 5, 61, 0, 0,
|
|
237
237
|
142, 6, 1, 0, 0, 0, 143, 144, 5, 46, 0, 0, 144, 145, 5, 46, 0, 0, 145, 8, 1, 0, 0, 0, 146,
|
|
238
|
-
147, 5,
|
|
239
|
-
151, 5,
|
|
238
|
+
147, 5, 91, 0, 0, 147, 10, 1, 0, 0, 0, 148, 149, 5, 93, 0, 0, 149, 12, 1, 0, 0, 0, 150,
|
|
239
|
+
151, 5, 46, 0, 0, 151, 14, 1, 0, 0, 0, 152, 153, 5, 98, 0, 0, 153, 154, 5, 114, 0, 0, 154,
|
|
240
240
|
155, 5, 101, 0, 0, 155, 156, 5, 97, 0, 0, 156, 157, 5, 107, 0, 0, 157, 16, 1, 0, 0, 0,
|
|
241
241
|
158, 159, 5, 98, 0, 0, 159, 160, 5, 114, 0, 0, 160, 161, 5, 97, 0, 0, 161, 162, 5, 110,
|
|
242
242
|
0, 0, 162, 163, 5, 99, 0, 0, 163, 164, 5, 104, 0, 0, 164, 18, 1, 0, 0, 0, 165, 166, 5,
|