circuitscript 0.1.4 → 0.1.7
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 +149 -80
- package/dist/cjs/SemanticTokenVisitor.js +19 -13
- package/dist/cjs/antlr/CircuitScriptParser.js +711 -671
- package/dist/cjs/builtinMethods.js +48 -22
- package/dist/cjs/draw_symbols.js +4 -1
- package/dist/cjs/environment.js +118 -0
- package/dist/cjs/execute.js +98 -46
- package/dist/cjs/geometry.js +1 -0
- package/dist/cjs/globals.js +14 -7
- package/dist/cjs/helpers.js +142 -150
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/layout.js +39 -14
- package/dist/cjs/main.js +34 -21
- package/dist/cjs/objects/ClassComponent.js +4 -1
- package/dist/cjs/objects/ExecutionScope.js +40 -2
- package/dist/cjs/objects/ParamDefinition.js +15 -15
- package/dist/cjs/parser.js +27 -21
- package/dist/cjs/regenerate-tests.js +9 -6
- package/dist/cjs/render.js +3 -1
- package/dist/cjs/sizing.js +10 -60
- package/dist/cjs/utils.js +148 -17
- package/dist/cjs/validate/SymbolTable.js +96 -0
- package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +14 -0
- package/dist/cjs/validate/SymbolValidatorVisitor.js +170 -0
- package/dist/cjs/validate.js +52 -44
- package/dist/cjs/visitor.js +149 -31
- package/dist/esm/{BaseVisitor.mjs → BaseVisitor.js} +124 -56
- package/dist/esm/{SemanticTokenVisitor.mjs → SemanticTokenVisitor.js} +17 -11
- package/dist/esm/antlr/{CircuitScriptParser.mjs → CircuitScriptParser.js} +711 -671
- package/dist/esm/{builtinMethods.mjs → builtinMethods.js} +40 -14
- package/dist/esm/{draw_symbols.mjs → draw_symbols.js} +11 -8
- package/dist/esm/environment.js +110 -0
- package/dist/esm/{execute.mjs → execute.js} +111 -58
- package/dist/esm/{export.mjs → export.js} +2 -2
- package/dist/esm/{geometry.mjs → geometry.js} +6 -5
- package/dist/esm/{globals.mjs → globals.js} +9 -2
- package/dist/esm/helpers.js +377 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/{layout.mjs → layout.js} +44 -22
- package/dist/esm/{lexer.mjs → lexer.js} +2 -2
- package/dist/esm/{main.mjs → main.js} +36 -23
- package/dist/esm/objects/{ClassComponent.mjs → ClassComponent.js} +9 -5
- package/dist/esm/objects/{ExecutionScope.mjs → ExecutionScope.js} +40 -2
- package/dist/esm/objects/{Frame.mjs → Frame.js} +1 -1
- package/dist/esm/objects/{ParamDefinition.mjs → ParamDefinition.js} +1 -1
- package/dist/esm/objects/{PinDefinition.mjs → PinDefinition.js} +1 -1
- package/dist/esm/parser.js +71 -0
- package/dist/esm/{regenerate-tests.mjs → regenerate-tests.js} +10 -7
- package/dist/esm/{render.mjs → render.js} +11 -9
- package/dist/esm/{sizing.mjs → sizing.js} +11 -36
- package/dist/esm/utils.js +286 -0
- package/dist/esm/validate/SymbolTable.js +90 -0
- package/dist/esm/validate/SymbolValidatorResolveVisitor.js +10 -0
- package/dist/esm/validate/SymbolValidatorVisitor.js +163 -0
- package/dist/esm/validate.js +86 -0
- package/dist/esm/{visitor.mjs → visitor.js} +160 -42
- package/dist/fonts/Arial.ttf +0 -0
- package/dist/fonts/Inter-Bold.ttf +0 -0
- package/dist/fonts/Inter-Regular.ttf +0 -0
- package/dist/fonts/OpenSans-Regular.ttf +0 -0
- package/dist/fonts/Roboto-Regular.ttf +0 -0
- package/dist/libs/lib.cst +423 -0
- package/dist/types/BaseVisitor.d.ts +36 -22
- package/dist/types/SemanticTokenVisitor.d.ts +6 -5
- package/dist/types/antlr/CircuitScriptParser.d.ts +4 -2
- package/dist/types/builtinMethods.d.ts +3 -2
- package/dist/types/draw_symbols.d.ts +2 -6
- package/dist/types/environment.d.ts +31 -0
- package/dist/types/execute.d.ts +2 -3
- package/dist/types/globals.d.ts +7 -2
- package/dist/types/helpers.d.ts +12 -14
- package/dist/types/index.d.ts +5 -0
- package/dist/types/objects/ClassComponent.d.ts +2 -3
- package/dist/types/objects/ExecutionScope.d.ts +20 -6
- package/dist/types/objects/types.d.ts +6 -1
- package/dist/types/parser.d.ts +7 -11
- package/dist/types/sizing.d.ts +0 -3
- package/dist/types/utils.d.ts +33 -4
- package/dist/types/validate/SymbolTable.d.ts +40 -0
- package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +7 -0
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +32 -0
- package/dist/types/validate.d.ts +1 -1
- package/libs/lib.cst +12 -22
- package/package.json +14 -13
- package/dist/cjs/SymbolValidatorVisitor.js +0 -233
- package/dist/esm/SymbolValidatorVisitor.mjs +0 -222
- package/dist/esm/helpers.mjs +0 -380
- package/dist/esm/index.mjs +0 -15
- package/dist/esm/parser.mjs +0 -64
- package/dist/esm/utils.mjs +0 -169
- package/dist/esm/validate.mjs +0 -74
- package/dist/types/SymbolValidatorVisitor.d.ts +0 -61
- package/dist/types/layout.d.ts +0 -148
- /package/dist/esm/antlr/{CircuitScriptLexer.mjs → CircuitScriptLexer.js} +0 -0
- /package/dist/esm/antlr/{CircuitScriptVisitor.mjs → CircuitScriptVisitor.js} +0 -0
- /package/dist/esm/{fonts.mjs → fonts.js} +0 -0
- /package/dist/esm/{logger.mjs → logger.js} +0 -0
- /package/dist/esm/objects/{Net.mjs → Net.js} +0 -0
- /package/dist/esm/objects/{PinTypes.mjs → PinTypes.js} +0 -0
- /package/dist/esm/objects/{Wire.mjs → Wire.js} +0 -0
- /package/dist/esm/objects/{types.mjs → types.js} +0 -0
- /package/dist/esm/{server.mjs → server.js} +0 -0
package/dist/cjs/visitor.js
CHANGED
|
@@ -46,9 +46,14 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
46
46
|
this.visitTo_component_expr = (ctx) => {
|
|
47
47
|
ctx.component_select_expr().forEach(item => {
|
|
48
48
|
const [component, pin] = this.visitResult(item);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
try {
|
|
50
|
+
this.getExecutor().toComponent(component, pin, {
|
|
51
|
+
addSequence: true
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw new utils_js_1.RuntimeExecutionError(err.message, ctx.start, ctx.stop);
|
|
56
|
+
}
|
|
52
57
|
});
|
|
53
58
|
return this.getExecutor().getCurrentPoint();
|
|
54
59
|
};
|
|
@@ -63,7 +68,10 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
63
68
|
componentPin = this.visitResult(ctxDataExprWithAssigment);
|
|
64
69
|
}
|
|
65
70
|
else {
|
|
66
|
-
|
|
71
|
+
let component = this.getScope().currentComponent;
|
|
72
|
+
if (component._pointLinkComponent) {
|
|
73
|
+
component = component._pointLinkComponent;
|
|
74
|
+
}
|
|
67
75
|
let pinId = null;
|
|
68
76
|
const ctxPinSelectExpr = ctx.pin_select_expr();
|
|
69
77
|
if (ctxPinSelectExpr) {
|
|
@@ -111,6 +119,92 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
111
119
|
return this.getExecutor().getCurrentPoint();
|
|
112
120
|
};
|
|
113
121
|
this.visitCreate_component_expr = (ctx) => {
|
|
122
|
+
const scope = this.getScope();
|
|
123
|
+
scope.setOnPropertyHandler((path, value, ctx) => {
|
|
124
|
+
if (path.length === 1) {
|
|
125
|
+
const [, keyName] = path[0];
|
|
126
|
+
switch (keyName) {
|
|
127
|
+
case 'type':
|
|
128
|
+
this.validateString(value, ctx);
|
|
129
|
+
break;
|
|
130
|
+
case 'angle':
|
|
131
|
+
case 'width':
|
|
132
|
+
case 'height':
|
|
133
|
+
this.validateNumeric(value, ctx);
|
|
134
|
+
break;
|
|
135
|
+
case 'pins':
|
|
136
|
+
if (!(value instanceof Map)) {
|
|
137
|
+
this.validateNumeric(value, ctx);
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case 'copy':
|
|
141
|
+
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
142
|
+
this.validateNumeric(value, ctx);
|
|
143
|
+
}
|
|
144
|
+
else if (typeof value === 'boolean') {
|
|
145
|
+
this.validateBoolean(value, ctx);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
throw new utils_js_1.RuntimeExecutionError("Invalid value for 'copy' property", ctx.start, ctx.end);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const [, keyName] = path[0];
|
|
155
|
+
if (keyName === 'arrange') {
|
|
156
|
+
const [sideKeyCtx, sideKeyName] = path[1];
|
|
157
|
+
if (globals_js_1.ValidPinSides.indexOf(sideKeyName) === -1) {
|
|
158
|
+
throw new utils_js_1.RuntimeExecutionError(`Invalid side ${sideKeyName} in arrange`, sideKeyCtx.start, sideKeyCtx.stop);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
if (path.length > 2 && path[2][0] === 'index') {
|
|
162
|
+
if (Array.isArray(value)) {
|
|
163
|
+
const goodBlank = value.length === 1 &&
|
|
164
|
+
value[0] instanceof ParamDefinition_js_1.NumericValue;
|
|
165
|
+
if (!goodBlank) {
|
|
166
|
+
throw new utils_js_1.RuntimeExecutionError(`Invalid blank specifier`, ctx.start, ctx.stop);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
if (!(value instanceof ParamDefinition_js_1.NumericValue)) {
|
|
171
|
+
throw new utils_js_1.RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx.start, ctx.stop);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else if (keyName === 'params') {
|
|
178
|
+
const [, subKeyName] = path[1];
|
|
179
|
+
switch (subKeyName) {
|
|
180
|
+
case 'mpn':
|
|
181
|
+
case 'refdes':
|
|
182
|
+
case 'footprint':
|
|
183
|
+
this.validateString(value, ctx);
|
|
184
|
+
break;
|
|
185
|
+
case 'place':
|
|
186
|
+
this.validateBoolean(value, ctx);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (keyName === 'pins') {
|
|
191
|
+
if (path.length === 2) {
|
|
192
|
+
if (value.length === 2) {
|
|
193
|
+
const [pinType,] = value;
|
|
194
|
+
if (pinType instanceof types_js_1.UndeclaredReference) {
|
|
195
|
+
throw new utils_js_1.RuntimeExecutionError(`Invalid pin type: ${pinType.reference.name}`, ctx.start, ctx.end);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
scope.enterContext(ctx);
|
|
203
|
+
ctx.property_expr().forEach(item => {
|
|
204
|
+
this.visitResult(item);
|
|
205
|
+
});
|
|
206
|
+
scope.exitContext();
|
|
207
|
+
scope.popOnPropertyHandler();
|
|
114
208
|
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
115
209
|
const pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
116
210
|
let instanceName = this.getExecutor().getUniqueInstanceName();
|
|
@@ -123,7 +217,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
123
217
|
if (paramValue instanceof ParamDefinition_js_1.NumericValue) {
|
|
124
218
|
appendValue = paramValue.value;
|
|
125
219
|
}
|
|
126
|
-
instanceName +=
|
|
220
|
+
instanceName += `${globals_js_1.Delimiter1}${appendValue}`;
|
|
127
221
|
}
|
|
128
222
|
const arrange = properties.has('arrange') ?
|
|
129
223
|
properties.get('arrange') : null;
|
|
@@ -145,8 +239,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
145
239
|
arrange, display, type, width, height, copy,
|
|
146
240
|
angle, followWireOrientation
|
|
147
241
|
};
|
|
148
|
-
|
|
149
|
-
|
|
242
|
+
try {
|
|
243
|
+
const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
|
|
244
|
+
this.setResult(ctx, createdComponent);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
this.throwWithContext(ctx, error.message);
|
|
248
|
+
}
|
|
150
249
|
};
|
|
151
250
|
this.visitCreate_graphic_expr = (ctx) => {
|
|
152
251
|
const ctxId = ctx.ID();
|
|
@@ -154,7 +253,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
154
253
|
if (ctxId !== null) {
|
|
155
254
|
const varName = ctxId.getText();
|
|
156
255
|
paramIds.push(varName);
|
|
157
|
-
this.
|
|
256
|
+
this.getScope().variables.set(varName, {});
|
|
158
257
|
}
|
|
159
258
|
const executor = this.getExecutor();
|
|
160
259
|
const stack = [...this.executionStack];
|
|
@@ -256,7 +355,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
256
355
|
useValueArray = [useValueArray];
|
|
257
356
|
}
|
|
258
357
|
useValueArray.forEach((value, index) => {
|
|
259
|
-
this.
|
|
358
|
+
this.getScope().variables.set(forVariableNames[index], value);
|
|
260
359
|
});
|
|
261
360
|
const commands = this.visitResult(ctx.graphic_expressions_block());
|
|
262
361
|
allCommands = allCommands.concat(commands);
|
|
@@ -315,8 +414,16 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
315
414
|
this.setResult(ctx, [keyName, expressionsBlock]);
|
|
316
415
|
};
|
|
317
416
|
this.visitProperty_expr = (ctx) => {
|
|
318
|
-
const
|
|
319
|
-
const
|
|
417
|
+
const ctxKey = ctx.property_key_expr();
|
|
418
|
+
const ctxValue = ctx.property_value_expr();
|
|
419
|
+
const scope = this.getScope();
|
|
420
|
+
this.getScope().enterContext(ctxKey);
|
|
421
|
+
this.getScope().enterContext(ctxValue);
|
|
422
|
+
const keyName = this.visitResult(ctxKey);
|
|
423
|
+
const value = this.visitResult(ctxValue);
|
|
424
|
+
scope.triggerPropertyHandler(value, ctxValue);
|
|
425
|
+
this.getScope().exitContext();
|
|
426
|
+
this.getScope().exitContext();
|
|
320
427
|
if (value instanceof types_js_1.UndeclaredReference && (value.reference.parentValue === undefined
|
|
321
428
|
&& value.reference.value === undefined)) {
|
|
322
429
|
throw value.throwMessage();
|
|
@@ -326,15 +433,21 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
326
433
|
this.setResult(ctx, map);
|
|
327
434
|
};
|
|
328
435
|
this.visitSingle_line_property = (ctx) => {
|
|
436
|
+
this.getScope().enterContext(ctx);
|
|
329
437
|
let value;
|
|
330
438
|
if (ctx.data_expr().length === 1) {
|
|
331
439
|
value = this.visitResult(ctx.data_expr(0));
|
|
332
440
|
}
|
|
333
441
|
else {
|
|
334
|
-
value = ctx.data_expr().map(item => {
|
|
335
|
-
|
|
442
|
+
value = ctx.data_expr().map((item, index) => {
|
|
443
|
+
this.getScope().enterContext(index);
|
|
444
|
+
const result = this.visitResult(item);
|
|
445
|
+
this.getScope().triggerPropertyHandler(result, item);
|
|
446
|
+
this.getScope().exitContext();
|
|
447
|
+
return result;
|
|
336
448
|
});
|
|
337
449
|
}
|
|
450
|
+
this.getScope().exitContext();
|
|
338
451
|
this.setResult(ctx, value);
|
|
339
452
|
};
|
|
340
453
|
this.visitNested_properties_inner = (ctx) => {
|
|
@@ -614,11 +727,13 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
614
727
|
const executionStack = this.executionStack;
|
|
615
728
|
const functionCounter = { counter: 0 };
|
|
616
729
|
const resolveNet = this.createNetResolver(this.executionStack);
|
|
730
|
+
const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
|
|
617
731
|
const __runFunc = (passedInParameters, options) => {
|
|
618
|
-
const executionContextName = functionName
|
|
732
|
+
const executionContextName = `${functionName}-${functionCounter['counter']}`;
|
|
619
733
|
const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
|
|
620
734
|
functionCounter['counter'] += 1;
|
|
621
735
|
newExecutor.resolveNet = resolveNet;
|
|
736
|
+
newExecutor.resolveComponentPinNet = resolveComponentPinNet;
|
|
622
737
|
const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
|
|
623
738
|
const lastExecution = executionStack.pop();
|
|
624
739
|
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
@@ -705,6 +820,9 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
705
820
|
}
|
|
706
821
|
else if (ctxDataExpr) {
|
|
707
822
|
useValue = this.visitResult(ctxDataExpr);
|
|
823
|
+
if (useValue instanceof ParamDefinition_js_1.NumericValue) {
|
|
824
|
+
useValue = useValue.toNumber();
|
|
825
|
+
}
|
|
708
826
|
}
|
|
709
827
|
if (useValue !== null) {
|
|
710
828
|
this.setResult(ctx, [direction, new helpers_js_1.UnitDimension(useValue)]);
|
|
@@ -846,7 +964,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
846
964
|
useValueArray = [useValueArray];
|
|
847
965
|
}
|
|
848
966
|
useValueArray.forEach((value, index) => {
|
|
849
|
-
this.
|
|
967
|
+
this.getScope().variables.set(forVariableNames[index], value);
|
|
850
968
|
});
|
|
851
969
|
this.visit(ctx.expressions_block());
|
|
852
970
|
keepLooping = true;
|
|
@@ -882,15 +1000,15 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
882
1000
|
expandModuleContains(component, netNamespace) {
|
|
883
1001
|
this.getExecutor().log('expanding module `contains`');
|
|
884
1002
|
const executionStack = this.executionStack;
|
|
885
|
-
const resolveNet = this.createNetResolver(executionStack);
|
|
886
1003
|
const executor = this.getExecutor();
|
|
887
|
-
const executionContextName = executor.namespace +
|
|
1004
|
+
const executionContextName = executor.namespace + globals_js_1.Delimiter1
|
|
888
1005
|
+ component.instanceName
|
|
889
|
-
+
|
|
890
|
-
const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName +
|
|
1006
|
+
+ globals_js_1.Delimiter1 + component.moduleCounter;
|
|
1007
|
+
const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + globals_js_1.Delimiter1 + component.moduleCounter);
|
|
891
1008
|
const newExecutor = this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
|
|
892
1009
|
component.moduleCounter += 1;
|
|
893
|
-
newExecutor.resolveNet =
|
|
1010
|
+
newExecutor.resolveNet = this.createNetResolver(executionStack);
|
|
1011
|
+
newExecutor.resolveComponentPinNet = this.createComponentPinNetResolver(executionStack);
|
|
894
1012
|
this.visit(component.moduleContainsExpressions);
|
|
895
1013
|
const executionContext = executionStack.pop();
|
|
896
1014
|
component.moduleExecutionContext = executionContext;
|
|
@@ -1041,32 +1159,32 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1041
1159
|
return result;
|
|
1042
1160
|
}
|
|
1043
1161
|
printNets() {
|
|
1044
|
-
this.
|
|
1162
|
+
this.getScope().printNets();
|
|
1045
1163
|
}
|
|
1046
1164
|
dumpNets() {
|
|
1047
|
-
return this.
|
|
1165
|
+
return this.getScope().dumpNets();
|
|
1048
1166
|
}
|
|
1049
1167
|
dumpUniqueNets() {
|
|
1050
|
-
const nets = this.
|
|
1168
|
+
const nets = this.getScope().getNets();
|
|
1051
1169
|
return nets.reduce((accum, [, , net]) => {
|
|
1052
1170
|
accum.push(net);
|
|
1053
1171
|
return accum;
|
|
1054
1172
|
}, []);
|
|
1055
1173
|
}
|
|
1056
1174
|
dumpVariables() {
|
|
1057
|
-
return this.
|
|
1175
|
+
return this.getScope().variables;
|
|
1058
1176
|
}
|
|
1059
1177
|
dumpInstances() {
|
|
1060
|
-
return this.
|
|
1178
|
+
return this.getScope().instances;
|
|
1061
1179
|
}
|
|
1062
1180
|
dump2() {
|
|
1063
|
-
const instances = this.
|
|
1181
|
+
const instances = this.getScope().instances;
|
|
1064
1182
|
const items = [];
|
|
1065
1183
|
for (const [instanceName, instance] of instances) {
|
|
1066
1184
|
if (instance.assignedRefDes === null) {
|
|
1067
1185
|
continue;
|
|
1068
1186
|
}
|
|
1069
|
-
const pinNets = this.resolveNets(this.
|
|
1187
|
+
const pinNets = this.resolveNets(this.getScope(), instance);
|
|
1070
1188
|
const componentItem = {
|
|
1071
1189
|
name: instanceName,
|
|
1072
1190
|
refdes: instance.assignedRefDes,
|
|
@@ -1081,9 +1199,9 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1081
1199
|
}
|
|
1082
1200
|
getNetList() {
|
|
1083
1201
|
const netlist = [];
|
|
1084
|
-
const instances = this.
|
|
1202
|
+
const instances = this.getScope().instances;
|
|
1085
1203
|
for (const [instanceName, instance] of instances) {
|
|
1086
|
-
const pinNets = this.resolveNets(this.
|
|
1204
|
+
const pinNets = this.resolveNets(this.getScope(), instance);
|
|
1087
1205
|
const componentItem = {
|
|
1088
1206
|
instanceName,
|
|
1089
1207
|
instance,
|
|
@@ -1114,7 +1232,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1114
1232
|
annotateComponents() {
|
|
1115
1233
|
this.log('===== annotate components =====');
|
|
1116
1234
|
const annotater = new ComponentAnnotater();
|
|
1117
|
-
const instances = this.
|
|
1235
|
+
const instances = this.getScope().instances;
|
|
1118
1236
|
const toAnnotate = [];
|
|
1119
1237
|
for (const [, instance] of instances) {
|
|
1120
1238
|
if (instance.typeProp === globals_js_1.ComponentTypes.net
|
|
@@ -1151,7 +1269,7 @@ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
|
|
|
1151
1269
|
this.log('');
|
|
1152
1270
|
}
|
|
1153
1271
|
applySheetFrameComponent() {
|
|
1154
|
-
const baseScope = this.
|
|
1272
|
+
const baseScope = this.getScope();
|
|
1155
1273
|
const document = baseScope.variables.get(globals_js_1.GlobalDocumentName);
|
|
1156
1274
|
let frameComponent = null;
|
|
1157
1275
|
if (document && document[Frame_js_1.FrameParamKeys.SheetType]) {
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import { readFileSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
1
|
import { Big } from 'big.js';
|
|
4
|
-
import { ExpressionContext } from "./antlr/CircuitScriptParser";
|
|
5
|
-
import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor";
|
|
6
|
-
import { ExecutionContext } from "./execute";
|
|
7
|
-
import { Logger } from "./logger";
|
|
8
|
-
import { ClassComponent } from "./objects/ClassComponent";
|
|
9
|
-
import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition";
|
|
10
|
-
import { PinTypes } from "./objects/PinTypes";
|
|
11
|
-
import { Direction, UndeclaredReference } from "./objects/types";
|
|
12
|
-
import { GlobalDocumentName, ReferenceTypes } from './globals';
|
|
13
|
-
import { linkBuiltInMethods } from './builtinMethods';
|
|
14
|
-
import { resolveToNumericValue, throwWithContext } from './utils';
|
|
2
|
+
import { ExpressionContext } from "./antlr/CircuitScriptParser.js";
|
|
3
|
+
import { CircuitScriptVisitor } from "./antlr/CircuitScriptVisitor.js";
|
|
4
|
+
import { ExecutionContext } from "./execute.js";
|
|
5
|
+
import { Logger } from "./logger.js";
|
|
6
|
+
import { ClassComponent } from "./objects/ClassComponent.js";
|
|
7
|
+
import { NumberOperator, NumericValue, PercentageValue } from "./objects/ParamDefinition.js";
|
|
8
|
+
import { PinTypes } from "./objects/PinTypes.js";
|
|
9
|
+
import { Direction, UndeclaredReference } from "./objects/types.js";
|
|
10
|
+
import { DoubleDelimiter1, GlobalDocumentName, ReferenceTypes } from './globals.js';
|
|
11
|
+
import { linkBuiltInMethods } from './builtinMethods.js';
|
|
12
|
+
import { resolveToNumericValue, RuntimeExecutionError, throwWithContext } from './utils.js';
|
|
13
|
+
import { SequenceAction } from './objects/ExecutionScope.js';
|
|
15
14
|
export class BaseVisitor extends CircuitScriptVisitor {
|
|
16
15
|
indentLevel = 0;
|
|
17
16
|
startingContext;
|
|
18
17
|
executionStack;
|
|
19
18
|
silent = false;
|
|
20
19
|
logger;
|
|
21
|
-
currentDirectory;
|
|
22
|
-
defaultLibsPath;
|
|
23
20
|
printStream = [];
|
|
24
21
|
printToConsole = true;
|
|
25
22
|
acceptedDirections = [Direction.Up, Direction.Down,
|
|
@@ -33,28 +30,41 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
33
30
|
PinTypes.IO,
|
|
34
31
|
PinTypes.Power,
|
|
35
32
|
];
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
onErrorHandler = null;
|
|
34
|
+
environment;
|
|
35
|
+
importedFiles = [];
|
|
36
|
+
onImportFile = async (visitor, filePath, fileData, onErrorHandler) => {
|
|
38
37
|
throw "Import file not implemented";
|
|
39
38
|
};
|
|
40
|
-
constructor(silent = false, onErrorHandler = null,
|
|
39
|
+
constructor(silent = false, onErrorHandler = null, environment) {
|
|
41
40
|
super();
|
|
42
41
|
this.logger = new Logger();
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
45
|
-
this.startingContext
|
|
46
|
-
this.
|
|
42
|
+
this.onErrorHandler = onErrorHandler;
|
|
43
|
+
this.environment = environment;
|
|
44
|
+
this.startingContext = new ExecutionContext(DoubleDelimiter1, `${DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, null);
|
|
45
|
+
const scope = this.startingContext.scope;
|
|
46
|
+
scope.sequence.push([
|
|
47
|
+
SequenceAction.At, scope.componentRoot, scope.currentPin
|
|
48
|
+
]);
|
|
49
|
+
scope.variables.set(GlobalDocumentName, {});
|
|
50
|
+
this.setupBuiltInFunctions(this.startingContext);
|
|
47
51
|
this.executionStack = [this.startingContext];
|
|
48
52
|
this.startingContext.resolveNet =
|
|
49
53
|
this.createNetResolver(this.executionStack);
|
|
54
|
+
this.startingContext.resolveComponentPinNet =
|
|
55
|
+
this.createComponentPinNetResolver(this.executionStack);
|
|
50
56
|
this.silent = silent;
|
|
51
|
-
this.currentDirectory = currentDirectory;
|
|
52
|
-
this.defaultLibsPath = defaultLibsPath;
|
|
53
57
|
}
|
|
54
58
|
getExecutor() {
|
|
55
59
|
return this.executionStack[this.executionStack.length - 1];
|
|
56
60
|
}
|
|
57
|
-
|
|
61
|
+
getScope() {
|
|
62
|
+
return this.getExecutor().scope;
|
|
63
|
+
}
|
|
64
|
+
getRootExecutor() {
|
|
65
|
+
return this.executionStack[0];
|
|
66
|
+
}
|
|
67
|
+
setupBuiltInFunctions(context) {
|
|
58
68
|
linkBuiltInMethods(context, this);
|
|
59
69
|
}
|
|
60
70
|
createNetResolver(executionStack) {
|
|
@@ -77,6 +87,19 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
77
87
|
};
|
|
78
88
|
return resolveNet;
|
|
79
89
|
}
|
|
90
|
+
createComponentPinNetResolver(executionStack) {
|
|
91
|
+
return (component, pin) => {
|
|
92
|
+
const reversed = [...executionStack].reverse();
|
|
93
|
+
for (let i = 0; i < reversed.length; i++) {
|
|
94
|
+
const context = reversed[i];
|
|
95
|
+
const net = context.scope.getNet(component, pin);
|
|
96
|
+
if (net !== null) {
|
|
97
|
+
return net;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
80
103
|
log(...params) {
|
|
81
104
|
const indentOutput = ''.padStart(this.indentLevel * 4, ' ');
|
|
82
105
|
const indentLevelText = this.indentLevel.toString().padStart(3, ' ');
|
|
@@ -89,11 +112,21 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
89
112
|
log2(message) {
|
|
90
113
|
this.getExecutor().log(message);
|
|
91
114
|
}
|
|
92
|
-
|
|
115
|
+
async visitAsync(ctx) {
|
|
116
|
+
const result = await ctx.accept(this);
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
visitScript = async (ctx) => {
|
|
93
120
|
this.log('===', 'start', '===');
|
|
94
|
-
const
|
|
121
|
+
const imports = ctx.import_expr();
|
|
122
|
+
for (let i = 0; i < imports.length; i++) {
|
|
123
|
+
const ctxImport = imports[i];
|
|
124
|
+
const ID = ctxImport.ID().toString();
|
|
125
|
+
await this.handleImportFile(ID, true, ctxImport);
|
|
126
|
+
}
|
|
127
|
+
const result = this.runExpressions(this.getExecutor(), ctx.expression());
|
|
128
|
+
this.setResult(ctx, result);
|
|
95
129
|
this.log('===', 'end', '===');
|
|
96
|
-
return result;
|
|
97
130
|
};
|
|
98
131
|
visitAssignment_expr = (ctx) => {
|
|
99
132
|
const reference = this.getReference(ctx.atom_expr());
|
|
@@ -103,12 +136,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
103
136
|
const trailers = reference.trailers ?? [];
|
|
104
137
|
if (trailers.length === 0) {
|
|
105
138
|
if (value instanceof ClassComponent) {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
tmpComponent.instanceName = reference.name;
|
|
110
|
-
instances.delete(oldName);
|
|
111
|
-
instances.set(reference.name, tmpComponent);
|
|
139
|
+
const variables = this.getExecutor().scope.variables;
|
|
140
|
+
variables.set(reference.name, value);
|
|
141
|
+
this.getExecutor().scope.sequence.push([SequenceAction.Assign, reference.name, value]);
|
|
112
142
|
this.log2(`assigned '${reference.name}' to ClassComponent`);
|
|
113
143
|
}
|
|
114
144
|
else {
|
|
@@ -229,7 +259,6 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
229
259
|
executor.scope.setNet(tmpComponent, pinId, net);
|
|
230
260
|
}
|
|
231
261
|
}
|
|
232
|
-
this.log2(`atomId: ${atomId} ${currentReference}`);
|
|
233
262
|
if (ctx.parent instanceof ExpressionContext && !currentReference.found) {
|
|
234
263
|
this.throwWithContext(ctx, "Unknown symbol: " + atomId);
|
|
235
264
|
}
|
|
@@ -369,10 +398,10 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
369
398
|
const tmpCtx = defaultValuesProvided[index - boundary];
|
|
370
399
|
this.visit(tmpCtx);
|
|
371
400
|
const defaultValue = this.getResult(tmpCtx);
|
|
372
|
-
return [idText, defaultValue];
|
|
401
|
+
return [idText, tmpCtx.start, defaultValue];
|
|
373
402
|
}
|
|
374
403
|
else {
|
|
375
|
-
return [idText];
|
|
404
|
+
return [idText, id.getSymbol()];
|
|
376
405
|
}
|
|
377
406
|
});
|
|
378
407
|
this.setResult(ctx, result);
|
|
@@ -394,10 +423,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
394
423
|
this.setResult(ctx, returnList);
|
|
395
424
|
};
|
|
396
425
|
visitImport_expr = (ctx) => {
|
|
397
|
-
|
|
398
|
-
this.log('import', ID);
|
|
399
|
-
this.handleImportFile(ID, true, ctx);
|
|
400
|
-
this.log('done import', ID);
|
|
426
|
+
throw new RuntimeExecutionError("Cannot parse imports here", ctx.start, ctx.stop);
|
|
401
427
|
};
|
|
402
428
|
visitFunction_return_expr = (ctx) => {
|
|
403
429
|
const executor = this.getExecutor();
|
|
@@ -447,15 +473,24 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
447
473
|
this.visit(ctx);
|
|
448
474
|
return this.getResult(ctx);
|
|
449
475
|
}
|
|
450
|
-
handleImportFile(name, throwErrors = true, ctx = null) {
|
|
476
|
+
async handleImportFile(name, throwErrors = true, ctx = null) {
|
|
477
|
+
name = name.trim();
|
|
478
|
+
const importAlready = this.importedFiles.find(item => {
|
|
479
|
+
return item.id === name;
|
|
480
|
+
});
|
|
481
|
+
if (importAlready) {
|
|
482
|
+
return importAlready;
|
|
483
|
+
}
|
|
451
484
|
let hasError = false;
|
|
452
485
|
let hasParseError = false;
|
|
453
486
|
let pathExists = false;
|
|
454
|
-
const tmpFilePath =
|
|
487
|
+
const tmpFilePath = this.environment.getRelativeToModule(name + ".cst");
|
|
455
488
|
this.log('importing path:', tmpFilePath);
|
|
456
489
|
let fileData = null;
|
|
490
|
+
let filePathUsed = null;
|
|
457
491
|
try {
|
|
458
|
-
|
|
492
|
+
filePathUsed = tmpFilePath;
|
|
493
|
+
fileData = await this.environment.readFile(tmpFilePath, { encoding: 'utf8' });
|
|
459
494
|
pathExists = true;
|
|
460
495
|
}
|
|
461
496
|
catch (err) {
|
|
@@ -463,8 +498,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
463
498
|
}
|
|
464
499
|
if (!pathExists) {
|
|
465
500
|
try {
|
|
466
|
-
const tmpFilePath2 =
|
|
467
|
-
|
|
501
|
+
const tmpFilePath2 = this.environment.getRelativeToDefaultLibs(name + ".cst");
|
|
502
|
+
filePathUsed = tmpFilePath2;
|
|
503
|
+
fileData = await this.environment.readFile(tmpFilePath2, { encoding: 'utf8' });
|
|
468
504
|
pathExists = true;
|
|
469
505
|
}
|
|
470
506
|
catch (err) {
|
|
@@ -474,31 +510,39 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
474
510
|
try {
|
|
475
511
|
if (pathExists) {
|
|
476
512
|
this.log('done reading imported file data');
|
|
477
|
-
const importResult = this.onImportFile(this, fileData, this.
|
|
513
|
+
const importResult = await this.onImportFile(this, filePathUsed, fileData, this.onErrorHandler);
|
|
478
514
|
hasError = importResult.hasError;
|
|
479
515
|
hasParseError = importResult.hasParseError;
|
|
480
516
|
}
|
|
481
517
|
}
|
|
482
518
|
catch (err) {
|
|
483
|
-
|
|
519
|
+
if (ctx != null) {
|
|
520
|
+
throw new RuntimeExecutionError("An error occurred while importing file", ctx.start, ctx.stop);
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
this.log('An error occurred while importing file:', err.message);
|
|
524
|
+
}
|
|
484
525
|
}
|
|
485
526
|
let errorMessage = null;
|
|
486
527
|
if (throwErrors && (hasError || hasParseError || !pathExists)) {
|
|
487
528
|
if (!pathExists) {
|
|
488
|
-
errorMessage = `File does not exist: ${name}`;
|
|
529
|
+
errorMessage = `File does not exist: ${name} (${filePathUsed})`;
|
|
489
530
|
}
|
|
490
531
|
else {
|
|
491
532
|
errorMessage = `Failed to import: ${name}`;
|
|
492
533
|
}
|
|
493
534
|
}
|
|
494
535
|
if (errorMessage !== null && ctx) {
|
|
495
|
-
|
|
536
|
+
throw new RuntimeExecutionError(errorMessage, ctx.start, ctx.end);
|
|
496
537
|
}
|
|
497
|
-
|
|
538
|
+
const newImportedFile = {
|
|
539
|
+
id: name.trim(),
|
|
498
540
|
hasError,
|
|
499
541
|
hasParseError,
|
|
500
542
|
pathExists,
|
|
501
543
|
};
|
|
544
|
+
this.importedFiles.push(newImportedFile);
|
|
545
|
+
return newImportedFile;
|
|
502
546
|
}
|
|
503
547
|
visitRoundedBracketsExpr = (ctx) => {
|
|
504
548
|
const ctxDataExpr = ctx.data_expr();
|
|
@@ -528,9 +572,9 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
528
572
|
executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
|
|
529
573
|
}
|
|
530
574
|
}
|
|
531
|
-
else if (tmpFuncArg.length ===
|
|
575
|
+
else if (tmpFuncArg.length === 3) {
|
|
532
576
|
const variableName = tmpFuncArg[0];
|
|
533
|
-
const defaultValue = tmpFuncArg[
|
|
577
|
+
const defaultValue = tmpFuncArg[2];
|
|
534
578
|
executor.log('set variable in scope, var name: ', variableName);
|
|
535
579
|
executor.scope.variables.set(variableName, defaultValue);
|
|
536
580
|
}
|
|
@@ -594,7 +638,6 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
594
638
|
const executionContextNamespace = currentExecutionContext.namespace
|
|
595
639
|
+ executionContextName + ".";
|
|
596
640
|
const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, parentContext);
|
|
597
|
-
this.setupPrintFunction(newExecutor);
|
|
598
641
|
executionStack.push(newExecutor);
|
|
599
642
|
this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
|
|
600
643
|
return newExecutor;
|
|
@@ -602,7 +645,32 @@ export class BaseVisitor extends CircuitScriptVisitor {
|
|
|
602
645
|
prepareStringValue(value) {
|
|
603
646
|
return value.slice(1, value.length - 1);
|
|
604
647
|
}
|
|
605
|
-
throwWithContext(context,
|
|
606
|
-
throwWithContext(context,
|
|
648
|
+
throwWithContext(context, messageOrError) {
|
|
649
|
+
throwWithContext(context, messageOrError);
|
|
650
|
+
}
|
|
651
|
+
validateType(value, context, validateFunction, expectedType) {
|
|
652
|
+
if (value === undefined) {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
const result = validateFunction(value);
|
|
656
|
+
if (!result) {
|
|
657
|
+
throw new RuntimeExecutionError(`Invalid ${expectedType}`, context.start, context.stop);
|
|
658
|
+
}
|
|
659
|
+
return result;
|
|
660
|
+
}
|
|
661
|
+
validateString(value, context) {
|
|
662
|
+
this.validateType(value, context, (val) => {
|
|
663
|
+
return typeof val === 'string';
|
|
664
|
+
}, 'string');
|
|
665
|
+
}
|
|
666
|
+
validateBoolean(value, context) {
|
|
667
|
+
this.validateType(value, context, (val) => {
|
|
668
|
+
return typeof val === 'boolean';
|
|
669
|
+
}, 'boolean');
|
|
670
|
+
}
|
|
671
|
+
validateNumeric(value, context) {
|
|
672
|
+
this.validateType(value, context, (val) => {
|
|
673
|
+
return (val instanceof NumericValue);
|
|
674
|
+
}, 'numeric value');
|
|
607
675
|
}
|
|
608
676
|
}
|