circuitscript 0.0.24 → 0.0.26
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/LICENSE +1 -1
- package/dist/cjs/BaseVisitor.js +485 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +256 -219
- package/dist/cjs/antlr/CircuitScriptParser.js +2891 -2151
- package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
- package/dist/cjs/draw_symbols.js +73 -22
- package/dist/cjs/execute.js +70 -78
- package/dist/cjs/export.js +91 -5
- package/dist/cjs/geometry.js +28 -8
- package/dist/cjs/globals.js +1 -2
- package/dist/cjs/helpers.js +180 -7
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/layout.js +8 -0
- package/dist/cjs/lexer.js +19 -22
- package/dist/cjs/main.js +27 -20
- package/dist/cjs/objects/ClassComponent.js +4 -0
- package/dist/cjs/objects/ExecutionScope.js +1 -0
- package/dist/cjs/objects/types.js +7 -1
- package/dist/cjs/parser.js +29 -258
- package/dist/cjs/render.js +1 -1
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +601 -823
- package/dist/esm/BaseVisitor.mjs +486 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +231 -218
- package/dist/esm/antlr/CircuitScriptParser.mjs +2852 -2144
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +13 -4
- package/dist/esm/draw_symbols.mjs +74 -23
- package/dist/esm/execute.mjs +70 -75
- package/dist/esm/export.mjs +89 -6
- package/dist/esm/geometry.mjs +28 -8
- package/dist/esm/globals.mjs +1 -2
- package/dist/esm/helpers.mjs +171 -9
- package/dist/esm/index.mjs +2 -0
- package/dist/esm/layout.mjs +8 -0
- package/dist/esm/lexer.mjs +10 -10
- package/dist/esm/main.mjs +28 -21
- package/dist/esm/objects/ClassComponent.mjs +4 -0
- package/dist/esm/objects/ExecutionScope.mjs +1 -0
- package/dist/esm/objects/types.mjs +6 -0
- package/dist/esm/parser.mjs +25 -230
- package/dist/esm/render.mjs +2 -2
- package/dist/esm/validate.mjs +74 -0
- package/dist/esm/visitor.mjs +415 -643
- package/dist/types/BaseVisitor.d.ts +66 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +37 -29
- package/dist/types/antlr/CircuitScriptParser.d.ts +606 -494
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +78 -60
- package/dist/types/draw_symbols.d.ts +12 -3
- package/dist/types/execute.d.ts +5 -10
- package/dist/types/export.d.ts +27 -1
- package/dist/types/geometry.d.ts +4 -0
- package/dist/types/globals.d.ts +2 -3
- package/dist/types/helpers.d.ts +32 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lexer.d.ts +2 -2
- package/dist/types/objects/ClassComponent.d.ts +1 -0
- package/dist/types/objects/ExecutionScope.d.ts +4 -1
- package/dist/types/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +15 -28
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +43 -95
- package/fonts/Inter-Bold.ttf +0 -0
- package/fonts/Inter-Regular.ttf +0 -0
- package/fonts/OpenSans-Regular.ttf +0 -0
- package/fonts/Roboto-Regular.ttf +0 -0
- package/libs/lib.cst +184 -0
- package/package.json +11 -6
package/dist/esm/visitor.mjs
CHANGED
|
@@ -1,239 +1,85 @@
|
|
|
1
|
-
import { ParseTreeVisitor } from 'antlr4';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import { ExecutionContext } from './execute.mjs';
|
|
5
1
|
import { ClassComponent } from './objects/ClassComponent.mjs';
|
|
6
|
-
import { NumericValue, ParamDefinition,
|
|
2
|
+
import { NumericValue, ParamDefinition, } from './objects/ParamDefinition.mjs';
|
|
7
3
|
import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
|
|
8
4
|
import { PinTypes } from './objects/PinTypes.mjs';
|
|
9
5
|
import { UndeclaredReference } from './objects/types.mjs';
|
|
10
|
-
import {
|
|
11
|
-
import { BlockTypes, ComponentTypes, NoNetText } from './globals.mjs';
|
|
6
|
+
import { BlockTypes, ComponentTypes, NoNetText, ReferenceTypes } from './globals.mjs';
|
|
12
7
|
import { SymbolDrawingCommands } from './draw_symbols.mjs';
|
|
13
|
-
import {
|
|
14
|
-
export class
|
|
15
|
-
|
|
16
|
-
startingContext;
|
|
17
|
-
executionStack;
|
|
18
|
-
silent = false;
|
|
19
|
-
logger;
|
|
20
|
-
printStream = [];
|
|
21
|
-
printToConsole = true;
|
|
22
|
-
acceptedDirections = ['left', 'right', 'up', 'down'];
|
|
23
|
-
pinTypesList = [
|
|
24
|
-
PinTypes.Any,
|
|
25
|
-
PinTypes.Input,
|
|
26
|
-
PinTypes.Output,
|
|
27
|
-
PinTypes.IO,
|
|
28
|
-
PinTypes.Power,
|
|
29
|
-
];
|
|
30
|
-
onImportFile = (visitor, filePath) => {
|
|
31
|
-
throw "Import file not implemented";
|
|
32
|
-
};
|
|
33
|
-
constructor(silent = false) {
|
|
34
|
-
super();
|
|
35
|
-
this.logger = new Logger();
|
|
36
|
-
this.startingContext = new ExecutionContext('__', '__.', '/', 0, 0, silent, this.logger);
|
|
37
|
-
this.setupPrintFunction(this.startingContext);
|
|
38
|
-
this.executionStack = [this.startingContext];
|
|
39
|
-
this.startingContext.resolveNet =
|
|
40
|
-
this.createNetResolver(this.executionStack);
|
|
41
|
-
this.silent = silent;
|
|
42
|
-
}
|
|
43
|
-
getExecutor() {
|
|
44
|
-
return this.executionStack[this.executionStack.length - 1];
|
|
45
|
-
}
|
|
46
|
-
visit(ctx) {
|
|
47
|
-
if (Array.isArray(ctx)) {
|
|
48
|
-
return ctx.map(function (child) {
|
|
49
|
-
try {
|
|
50
|
-
return child.accept(this);
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
this.handleError(child, err);
|
|
54
|
-
}
|
|
55
|
-
}, this);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
try {
|
|
59
|
-
return ctx.accept(this);
|
|
60
|
-
}
|
|
61
|
-
catch (err) {
|
|
62
|
-
this.handleError(ctx, err);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
handleError(ctx, err) {
|
|
67
|
-
if (!(err instanceof VisitorExecutionException)) {
|
|
68
|
-
throw new VisitorExecutionException(ctx, err);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
throw err;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
visitScript(ctx) {
|
|
75
|
-
this.print('===', 'start', '===');
|
|
76
|
-
const result = this.visitChildren(ctx);
|
|
77
|
-
this.print('===', 'end', '===');
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
visitParameters(ctx) {
|
|
81
|
-
const dataExpressions = ctx.data_expr_list();
|
|
82
|
-
const keywordAssignmentExpressions = ctx.keyword_assignment_expr_list();
|
|
83
|
-
const returnList = [];
|
|
84
|
-
dataExpressions.forEach((item, index) => {
|
|
85
|
-
const value = this.visit(item);
|
|
86
|
-
returnList.push(['position', index, value]);
|
|
87
|
-
});
|
|
88
|
-
keywordAssignmentExpressions.forEach((item) => {
|
|
89
|
-
const [key, value] = this.visit(item);
|
|
90
|
-
returnList.push(['keyword', key, value]);
|
|
91
|
-
});
|
|
92
|
-
return returnList;
|
|
93
|
-
}
|
|
94
|
-
visitKeyword_assignment_expr(ctx) {
|
|
8
|
+
import { BaseVisitor } from './BaseVisitor.mjs';
|
|
9
|
+
export class ParserVisitor extends BaseVisitor {
|
|
10
|
+
visitKeyword_assignment_expr = (ctx) => {
|
|
95
11
|
const id = ctx.ID().getText();
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const instances = this.getExecutor().scope.instances;
|
|
108
|
-
const tmpComponent = value;
|
|
109
|
-
const oldName = tmpComponent.instanceName;
|
|
110
|
-
tmpComponent.instanceName = reference.name;
|
|
111
|
-
instances.delete(oldName);
|
|
112
|
-
instances.set(reference.name, tmpComponent);
|
|
113
|
-
this.getExecutor().print(`assigned '${reference.name}' to ClassComponent`);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
const trailers = reference.trailers ?? [];
|
|
117
|
-
if (trailers.length === 0) {
|
|
118
|
-
this.getExecutor().scope.variables.set(reference.name, value);
|
|
119
|
-
}
|
|
120
|
-
else if (reference.value instanceof ClassComponent) {
|
|
121
|
-
this.setInstanceParam(reference.value, trailers, value);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return value;
|
|
125
|
-
}
|
|
126
|
-
setInstanceParam(object, trailers, value) {
|
|
127
|
-
const paramName = trailers[0].slice(1);
|
|
128
|
-
object.setParam(paramName, value);
|
|
129
|
-
this.getExecutor().print(`set instance ${object.instanceName} param ${paramName} to ${value}`);
|
|
130
|
-
}
|
|
131
|
-
visitValue_expr(ctx) {
|
|
132
|
-
const sign = ctx.Minus() ? -1 : 1;
|
|
133
|
-
if (ctx.INTEGER_VALUE() || ctx.DECIMAL_VALUE() || ctx.NUMERIC_VALUE()) {
|
|
134
|
-
if (ctx.INTEGER_VALUE()) {
|
|
135
|
-
return sign * Number(ctx.INTEGER_VALUE().getText());
|
|
136
|
-
}
|
|
137
|
-
else if (ctx.DECIMAL_VALUE()) {
|
|
138
|
-
return sign * Number(ctx.DECIMAL_VALUE().getText());
|
|
139
|
-
}
|
|
140
|
-
else if (ctx.NUMERIC_VALUE()) {
|
|
141
|
-
const textExtra = ctx.Minus() ? '-' : '';
|
|
142
|
-
return new NumericValue(textExtra + ctx.NUMERIC_VALUE().getText());
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
if (sign === -1) {
|
|
147
|
-
throw "Invalid value!";
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
if (ctx.BOOLEAN_VALUE()) {
|
|
151
|
-
const stringValue = ctx.BOOLEAN_VALUE().getText();
|
|
152
|
-
if (stringValue === 'true') {
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
|
-
else if (stringValue === 'false') {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
else if (ctx.STRING_VALUE()) {
|
|
160
|
-
return this.prepareStringValue(ctx.STRING_VALUE().getText());
|
|
161
|
-
}
|
|
162
|
-
else if (ctx.PERCENTAGE_VALUE()) {
|
|
163
|
-
return new PercentageValue(ctx.PERCENTAGE_VALUE().getText());
|
|
164
|
-
}
|
|
165
|
-
else if (ctx.blank_expr()) {
|
|
166
|
-
return this.visit(ctx.blank_expr());
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
visitBlank_expr(ctx) {
|
|
170
|
-
return new PinBlankValue(Number(ctx.INTEGER_VALUE().getText()));
|
|
171
|
-
}
|
|
172
|
-
visitPin_select_expr(ctx) {
|
|
173
|
-
if (ctx.INTEGER_VALUE()) {
|
|
174
|
-
return Number(ctx.INTEGER_VALUE().getText());
|
|
175
|
-
}
|
|
176
|
-
else if (ctx.STRING_VALUE()) {
|
|
177
|
-
return this.prepareStringValue(ctx.STRING_VALUE().getText());
|
|
12
|
+
const ctxDataExpr = ctx.data_expr();
|
|
13
|
+
this.visit(ctxDataExpr);
|
|
14
|
+
const value = this.getResult(ctxDataExpr);
|
|
15
|
+
this.setResult(ctx, [id, value]);
|
|
16
|
+
};
|
|
17
|
+
visitPin_select_expr = (ctx) => {
|
|
18
|
+
let value = null;
|
|
19
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
20
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
21
|
+
if (ctxIntegerValue) {
|
|
22
|
+
value = Number(ctxIntegerValue.getText());
|
|
178
23
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
visitAdd_component_expr(ctx) {
|
|
182
|
-
const [component, pinValue] = this.visit(ctx.data_expr_with_assignment());
|
|
183
|
-
if (ctx.ID()) {
|
|
184
|
-
this.setComponentOrientation(component, pinValue, ctx.ID().getText());
|
|
24
|
+
else if (ctxStringValue) {
|
|
25
|
+
value = this.prepareStringValue(ctxStringValue.getText());
|
|
185
26
|
}
|
|
27
|
+
this.setResult(ctx, value);
|
|
28
|
+
};
|
|
29
|
+
visitAdd_component_expr = (ctx) => {
|
|
30
|
+
const ctxDataWithAssignmentExpr = ctx.data_expr_with_assignment();
|
|
31
|
+
this.visit(ctxDataWithAssignmentExpr);
|
|
32
|
+
const [component, pinValue] = this.getResult(ctxDataWithAssignmentExpr);
|
|
186
33
|
return this.getExecutor().addComponentExisting(component, pinValue);
|
|
187
|
-
}
|
|
188
|
-
visitAt_component_expr(ctx) {
|
|
34
|
+
};
|
|
35
|
+
visitAt_component_expr = (ctx) => {
|
|
189
36
|
if (ctx.Point()) {
|
|
190
37
|
this.getExecutor().atPointBlock();
|
|
191
38
|
}
|
|
192
39
|
else {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
40
|
+
const ctxComponentSelectExpr = ctx.component_select_expr();
|
|
41
|
+
this.visit(ctxComponentSelectExpr);
|
|
42
|
+
const [component, pin] = this.getResult(ctxComponentSelectExpr);
|
|
43
|
+
this.getExecutor().atComponent(component, pin, {
|
|
44
|
+
addSequence: true
|
|
197
45
|
});
|
|
198
|
-
if (ctx.ID()) {
|
|
199
|
-
this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
|
|
200
|
-
}
|
|
201
46
|
}
|
|
202
47
|
return this.getExecutor().getCurrentPoint();
|
|
203
|
-
}
|
|
204
|
-
visitTo_component_expr(ctx) {
|
|
205
|
-
let currentPoint;
|
|
48
|
+
};
|
|
49
|
+
visitTo_component_expr = (ctx) => {
|
|
206
50
|
if (ctx.Point()) {
|
|
207
51
|
this.getExecutor().toPointBlock();
|
|
208
52
|
}
|
|
209
53
|
else {
|
|
210
|
-
ctx.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
54
|
+
ctx.component_select_expr().forEach(item => {
|
|
55
|
+
this.visit(item);
|
|
56
|
+
const [component, pin] = this.getResult(item);
|
|
57
|
+
this.getExecutor().toComponent(component, pin, {
|
|
58
|
+
addSequence: true
|
|
214
59
|
});
|
|
215
60
|
});
|
|
216
|
-
if (ctx.ID()) {
|
|
217
|
-
this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
|
|
218
|
-
}
|
|
219
61
|
}
|
|
220
62
|
return this.getExecutor().getCurrentPoint();
|
|
221
|
-
}
|
|
222
|
-
visitComponent_select_expr(ctx) {
|
|
223
|
-
|
|
224
|
-
|
|
63
|
+
};
|
|
64
|
+
visitComponent_select_expr = (ctx) => {
|
|
65
|
+
const ctxDataExprWithAssigment = ctx.data_expr_with_assignment();
|
|
66
|
+
if (ctxDataExprWithAssigment) {
|
|
67
|
+
this.visit(ctxDataExprWithAssigment);
|
|
68
|
+
this.setResult(ctx, this.getResult(ctxDataExprWithAssigment));
|
|
225
69
|
}
|
|
226
70
|
else {
|
|
227
71
|
const component = this.getExecutor().scope.currentComponent;
|
|
228
72
|
let pinId = null;
|
|
229
|
-
|
|
230
|
-
|
|
73
|
+
const ctxPinSelectExpr = ctx.pin_select_expr();
|
|
74
|
+
if (ctxPinSelectExpr) {
|
|
75
|
+
this.visit(ctxPinSelectExpr);
|
|
76
|
+
pinId = this.getResult(ctxPinSelectExpr);
|
|
231
77
|
}
|
|
232
|
-
|
|
78
|
+
this.setResult(ctx, [component, pinId]);
|
|
233
79
|
}
|
|
234
|
-
}
|
|
235
|
-
visitPath_blocks(ctx) {
|
|
236
|
-
const blocks = ctx.
|
|
80
|
+
};
|
|
81
|
+
visitPath_blocks = (ctx) => {
|
|
82
|
+
const blocks = ctx.path_block_inner();
|
|
237
83
|
let blockIndex = 0;
|
|
238
84
|
let blockType = BlockTypes.Branch;
|
|
239
85
|
let prevBlockType = null;
|
|
@@ -265,13 +111,9 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
265
111
|
});
|
|
266
112
|
this.getExecutor().exitBlocks();
|
|
267
113
|
return this.getExecutor().getCurrentPoint();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
this.
|
|
271
|
-
return -1;
|
|
272
|
-
}
|
|
273
|
-
visitCreate_component_expr(ctx) {
|
|
274
|
-
const properties = this.getPropertyExprList(ctx.property_expr_list());
|
|
114
|
+
};
|
|
115
|
+
visitCreate_component_expr = (ctx) => {
|
|
116
|
+
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
275
117
|
const pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
276
118
|
let instanceName = this.getExecutor().getUniqueInstanceName('');
|
|
277
119
|
const propParams = properties.get('params');
|
|
@@ -291,6 +133,8 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
291
133
|
properties.get('display') : null;
|
|
292
134
|
const type = properties.has('type') ?
|
|
293
135
|
properties.get('type') : null;
|
|
136
|
+
const copy = properties.has('copy') ?
|
|
137
|
+
properties.get('copy') : false;
|
|
294
138
|
const width = properties.has('width') ?
|
|
295
139
|
properties.get('width') : null;
|
|
296
140
|
const props = {
|
|
@@ -298,12 +142,14 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
298
142
|
display,
|
|
299
143
|
type,
|
|
300
144
|
width,
|
|
145
|
+
copy
|
|
301
146
|
};
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
visitCreate_graphic_expr(ctx) {
|
|
305
|
-
const commands = ctx.
|
|
306
|
-
|
|
147
|
+
this.setResult(ctx, this.getExecutor().createComponent(instanceName, pins, params, props));
|
|
148
|
+
};
|
|
149
|
+
visitCreate_graphic_expr = (ctx) => {
|
|
150
|
+
const commands = ctx.graphic_expr().reduce((accum, item) => {
|
|
151
|
+
this.visit(item);
|
|
152
|
+
const [commandName, parameters] = this.getResult(item);
|
|
307
153
|
const keywordParams = new Map();
|
|
308
154
|
const positionParams = parameters.reduce((accum, [argType, name, value]) => {
|
|
309
155
|
if (argType === 'position') {
|
|
@@ -317,100 +163,139 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
317
163
|
accum.push([commandName, positionParams, keywordParams]);
|
|
318
164
|
return accum;
|
|
319
165
|
}, []);
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
166
|
+
const drawing = new SymbolDrawingCommands(commands);
|
|
167
|
+
drawing.source = ctx.getText();
|
|
168
|
+
this.setResult(ctx, drawing);
|
|
169
|
+
};
|
|
170
|
+
visitGraphic_expr = (ctx) => {
|
|
323
171
|
let commandName = null;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
else if (ctx.Pin()) {
|
|
328
|
-
commandName = ctx.Pin().getText();
|
|
172
|
+
const command = ctx._command;
|
|
173
|
+
if (command) {
|
|
174
|
+
commandName = command.text;
|
|
329
175
|
}
|
|
330
176
|
else {
|
|
331
177
|
throw "Invalid command!";
|
|
332
178
|
}
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
179
|
+
const ctxParameters = ctx.parameters();
|
|
180
|
+
this.visit(ctxParameters);
|
|
181
|
+
const parameters = this.getResult(ctxParameters);
|
|
182
|
+
this.setResult(ctx, [commandName, parameters]);
|
|
183
|
+
};
|
|
184
|
+
visitProperty_expr = (ctx) => {
|
|
185
|
+
const ctxPropertyKeyExpr = ctx.property_key_expr();
|
|
186
|
+
const ctxPropertyValueExpr = ctx.property_value_expr();
|
|
187
|
+
this.visit(ctxPropertyKeyExpr);
|
|
188
|
+
this.visit(ctxPropertyValueExpr);
|
|
189
|
+
const keyName = this.getResult(ctxPropertyKeyExpr);
|
|
190
|
+
const value = this.getResult(ctxPropertyValueExpr);
|
|
339
191
|
const map = new Map();
|
|
340
192
|
map.set(keyName, value);
|
|
341
|
-
|
|
342
|
-
}
|
|
343
|
-
visitSingle_line_property(ctx) {
|
|
193
|
+
this.setResult(ctx, map);
|
|
194
|
+
};
|
|
195
|
+
visitSingle_line_property = (ctx) => {
|
|
344
196
|
let value;
|
|
345
|
-
if (ctx.
|
|
346
|
-
|
|
197
|
+
if (ctx.data_expr().length === 1) {
|
|
198
|
+
const ctxFirst = ctx.data_expr(0);
|
|
199
|
+
this.visit(ctxFirst);
|
|
200
|
+
value = this.getResult(ctxFirst);
|
|
347
201
|
}
|
|
348
202
|
else {
|
|
349
|
-
value = ctx.
|
|
350
|
-
|
|
203
|
+
value = ctx.data_expr().map(item => {
|
|
204
|
+
this.visit(item);
|
|
205
|
+
return this.getResult(item);
|
|
351
206
|
});
|
|
352
207
|
}
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
visitNested_properties(ctx) {
|
|
208
|
+
this.setResult(ctx, value);
|
|
209
|
+
};
|
|
210
|
+
visitNested_properties = (ctx) => {
|
|
356
211
|
const result = new Map();
|
|
357
|
-
ctx.
|
|
358
|
-
|
|
212
|
+
ctx.property_expr().forEach((item) => {
|
|
213
|
+
this.visit(item);
|
|
214
|
+
const property = this.getResult(item);
|
|
359
215
|
for (const [key, value] of property) {
|
|
360
216
|
result.set(key, value);
|
|
361
217
|
}
|
|
362
218
|
});
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
visitProperty_key_expr(ctx) {
|
|
366
|
-
|
|
367
|
-
|
|
219
|
+
this.setResult(ctx, result);
|
|
220
|
+
};
|
|
221
|
+
visitProperty_key_expr = (ctx) => {
|
|
222
|
+
const ctxID = ctx.ID();
|
|
223
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
224
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
225
|
+
let result = null;
|
|
226
|
+
if (ctxID) {
|
|
227
|
+
result = ctxID.getText();
|
|
368
228
|
}
|
|
369
|
-
else if (
|
|
370
|
-
|
|
229
|
+
else if (ctxIntegerValue) {
|
|
230
|
+
result = Number(ctxIntegerValue.getText());
|
|
371
231
|
}
|
|
372
|
-
else if (
|
|
373
|
-
|
|
232
|
+
else if (ctxStringValue) {
|
|
233
|
+
result = this.prepareStringValue(ctxStringValue.getText());
|
|
374
234
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
235
|
+
this.setResult(ctx, result);
|
|
236
|
+
};
|
|
237
|
+
visitData_expr_with_assignment = (ctx) => {
|
|
238
|
+
let component = null;
|
|
239
|
+
const ctxDataExpr = ctx.data_expr();
|
|
240
|
+
const ctxAssignmentExpr = ctx.assignment_expr();
|
|
241
|
+
if (ctxDataExpr) {
|
|
242
|
+
this.visit(ctxDataExpr);
|
|
243
|
+
component = this.getResult(ctxDataExpr);
|
|
380
244
|
if (component === null || component === undefined) {
|
|
381
|
-
throw "Could not find component: " +
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
else if (
|
|
385
|
-
|
|
245
|
+
throw "Could not find component: " + ctxDataExpr.getText();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (ctxAssignmentExpr) {
|
|
249
|
+
this.visit(ctxAssignmentExpr);
|
|
250
|
+
component = this.getResult(ctxAssignmentExpr);
|
|
251
|
+
}
|
|
252
|
+
if (component instanceof ClassComponent
|
|
253
|
+
&& component.copyProp) {
|
|
254
|
+
component = this.getExecutor().copyComponent(component);
|
|
255
|
+
}
|
|
256
|
+
if (component && component instanceof ClassComponent) {
|
|
257
|
+
const modifiers = ctx.component_modifier_expr();
|
|
258
|
+
modifiers.forEach(modifier => {
|
|
259
|
+
const modifierText = modifier.ID(0).getText();
|
|
260
|
+
const ctxValueExpr = modifier.value_expr();
|
|
261
|
+
const ctxID2 = modifier.ID(1);
|
|
262
|
+
let result = null;
|
|
263
|
+
if (ctxValueExpr) {
|
|
264
|
+
this.visit(ctxValueExpr);
|
|
265
|
+
result = this.getResult(ctxValueExpr);
|
|
266
|
+
}
|
|
267
|
+
else if (ctxID2) {
|
|
268
|
+
result = ctxID2.getText();
|
|
269
|
+
}
|
|
270
|
+
if (modifierText === 'flip') {
|
|
271
|
+
const flipValue = result;
|
|
272
|
+
if (flipValue.indexOf('x') !== -1) {
|
|
273
|
+
component.setParam('flipX', 1);
|
|
274
|
+
}
|
|
275
|
+
if (flipValue.indexOf('y') !== -1) {
|
|
276
|
+
component.setParam('flipY', 1);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else if (modifierText === 'angle') {
|
|
280
|
+
const angleValue = Number(result);
|
|
281
|
+
component.setParam('angle', angleValue);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
386
284
|
}
|
|
387
285
|
let pinValue = null;
|
|
388
|
-
|
|
389
|
-
|
|
286
|
+
const ctxPinSelectExpr = ctx.pin_select_expr();
|
|
287
|
+
if (ctxPinSelectExpr) {
|
|
288
|
+
this.visit(ctxPinSelectExpr);
|
|
289
|
+
pinValue = this.getResult(ctxPinSelectExpr);
|
|
390
290
|
}
|
|
391
291
|
else {
|
|
392
292
|
pinValue = component.getDefaultPin();
|
|
393
293
|
}
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
value = this.visit(ctx.value_expr());
|
|
400
|
-
}
|
|
401
|
-
else if (ctx.atom_expr()) {
|
|
402
|
-
const reference = this.visit(ctx.atom_expr());
|
|
403
|
-
if (!reference.found) {
|
|
404
|
-
value = new UndeclaredReference(reference);
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
value = reference.value;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return value;
|
|
411
|
-
}
|
|
412
|
-
visitUnaryOperatorExpr(ctx) {
|
|
413
|
-
const value = this.visit(ctx.data_expr());
|
|
294
|
+
this.setResult(ctx, [component, pinValue]);
|
|
295
|
+
};
|
|
296
|
+
visitUnaryOperatorExpr = (ctx) => {
|
|
297
|
+
this.visit(ctx.data_expr());
|
|
298
|
+
let value = this.getResult(ctx.data_expr());
|
|
414
299
|
const unaryOp = ctx.unary_operator();
|
|
415
300
|
if (unaryOp) {
|
|
416
301
|
if (unaryOp.Not()) {
|
|
@@ -423,334 +308,269 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
423
308
|
}
|
|
424
309
|
else if (unaryOp.Minus()) {
|
|
425
310
|
if (typeof value === 'number') {
|
|
426
|
-
|
|
311
|
+
value = -value;
|
|
427
312
|
}
|
|
428
313
|
else {
|
|
429
314
|
throw "Failed to do Negation operator";
|
|
430
315
|
}
|
|
431
316
|
}
|
|
432
317
|
}
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
visitDataExpr(ctx) {
|
|
318
|
+
this.setResult(ctx, value);
|
|
319
|
+
};
|
|
320
|
+
visitDataExpr = (ctx) => {
|
|
436
321
|
let value;
|
|
437
|
-
|
|
438
|
-
|
|
322
|
+
const ctxCreateComponentExpr = ctx.create_component_expr();
|
|
323
|
+
const ctxCreateGraphicExpr = ctx.create_graphic_expr();
|
|
324
|
+
if (ctxCreateComponentExpr) {
|
|
325
|
+
this.visit(ctxCreateComponentExpr);
|
|
326
|
+
value = this.getResult(ctxCreateComponentExpr);
|
|
439
327
|
}
|
|
440
|
-
else if (
|
|
441
|
-
|
|
328
|
+
else if (ctxCreateGraphicExpr) {
|
|
329
|
+
this.visit(ctxCreateGraphicExpr);
|
|
330
|
+
value = this.getResult(ctxCreateGraphicExpr);
|
|
442
331
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
332
|
+
else {
|
|
333
|
+
throw "Invalid data expression";
|
|
334
|
+
}
|
|
335
|
+
this.setResult(ctx, value);
|
|
336
|
+
};
|
|
337
|
+
visitBinaryOperatorExpr = (ctx) => {
|
|
338
|
+
const ctx0 = ctx.data_expr(0);
|
|
339
|
+
const ctx1 = ctx.data_expr(1);
|
|
340
|
+
this.visit(ctx0);
|
|
341
|
+
this.visit(ctx1);
|
|
342
|
+
const value1 = this.getResult(ctx0);
|
|
343
|
+
const value2 = this.getResult(ctx1);
|
|
448
344
|
const binaryOperatorType = ctx.binary_operator();
|
|
345
|
+
let result = null;
|
|
449
346
|
if (binaryOperatorType.Equals()) {
|
|
450
|
-
|
|
347
|
+
result = value1 == value2;
|
|
451
348
|
}
|
|
452
349
|
else if (binaryOperatorType.NotEquals()) {
|
|
453
|
-
|
|
350
|
+
result = value1 != value2;
|
|
454
351
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
352
|
+
else if (binaryOperatorType.GreaterThan()) {
|
|
353
|
+
result = value1 > value2;
|
|
354
|
+
}
|
|
355
|
+
else if (binaryOperatorType.GreatOrEqualThan()) {
|
|
356
|
+
result = value1 >= value2;
|
|
357
|
+
}
|
|
358
|
+
else if (binaryOperatorType.LessThan()) {
|
|
359
|
+
result = value1 < value2;
|
|
360
|
+
}
|
|
361
|
+
else if (binaryOperatorType.LessOrEqualThan()) {
|
|
362
|
+
result = value1 <= value2;
|
|
363
|
+
}
|
|
364
|
+
this.setResult(ctx, result);
|
|
365
|
+
};
|
|
366
|
+
visitLogicalOperatorExpr = (ctx) => {
|
|
367
|
+
const ctx0 = ctx.data_expr(0);
|
|
368
|
+
const ctx1 = ctx.data_expr(1);
|
|
369
|
+
this.visit(ctx0);
|
|
370
|
+
const value1 = this.getResult(ctx0);
|
|
371
|
+
let value2 = false;
|
|
372
|
+
let skipNext = false;
|
|
373
|
+
if (ctx.LogicalOr() && value1) {
|
|
374
|
+
skipNext = true;
|
|
375
|
+
}
|
|
376
|
+
if (!skipNext) {
|
|
377
|
+
this.visit(ctx1);
|
|
378
|
+
value2 = this.getResult(ctx1);
|
|
379
|
+
}
|
|
380
|
+
let result = null;
|
|
381
|
+
if (ctx.LogicalAnd()) {
|
|
382
|
+
result = value1 && value2;
|
|
383
|
+
}
|
|
384
|
+
else if (ctx.LogicalOr()) {
|
|
385
|
+
result = value1 || value2;
|
|
386
|
+
}
|
|
387
|
+
this.setResult(ctx, result);
|
|
388
|
+
};
|
|
389
|
+
visitMultiplyExpr = (ctx) => {
|
|
390
|
+
this.visit(ctx.data_expr(0));
|
|
391
|
+
this.visit(ctx.data_expr(1));
|
|
392
|
+
const value1 = this.getResult(ctx.data_expr(0));
|
|
393
|
+
const value2 = this.getResult(ctx.data_expr(1));
|
|
394
|
+
let result = null;
|
|
459
395
|
if (ctx.Multiply()) {
|
|
460
|
-
|
|
396
|
+
result = value1 * value2;
|
|
461
397
|
}
|
|
462
398
|
else if (ctx.Divide()) {
|
|
463
|
-
|
|
399
|
+
result = value1 / value2;
|
|
464
400
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
401
|
+
this.setResult(ctx, result);
|
|
402
|
+
};
|
|
403
|
+
visitAdditionExpr = (ctx) => {
|
|
404
|
+
this.visit(ctx.data_expr(0));
|
|
405
|
+
this.visit(ctx.data_expr(1));
|
|
406
|
+
const value1 = this.getResult(ctx.data_expr(0));
|
|
407
|
+
const value2 = this.getResult(ctx.data_expr(1));
|
|
408
|
+
let result = null;
|
|
469
409
|
if (ctx.Addition()) {
|
|
470
|
-
|
|
410
|
+
result = value1 + value2;
|
|
471
411
|
}
|
|
472
412
|
else if (ctx.Minus()) {
|
|
473
|
-
|
|
413
|
+
result = value1 - value2;
|
|
474
414
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const IDs = ctx.ID_list();
|
|
479
|
-
const boundary = IDs.length - defaultValuesProvided.length;
|
|
480
|
-
return IDs.map((id, index) => {
|
|
481
|
-
if (index >= boundary) {
|
|
482
|
-
const defaultValue = this.visit(defaultValuesProvided[index - boundary]);
|
|
483
|
-
return [id.getText(), defaultValue];
|
|
484
|
-
}
|
|
485
|
-
else {
|
|
486
|
-
return [id.getText()];
|
|
487
|
-
}
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
createNetResolver(executionStack) {
|
|
491
|
-
const resolveNet = (netName, netNamespace) => {
|
|
492
|
-
this.print('find net', netNamespace, netName);
|
|
493
|
-
const reversed = [...executionStack].reverse();
|
|
494
|
-
for (let i = 0; i < reversed.length; i++) {
|
|
495
|
-
const context = reversed[i];
|
|
496
|
-
const net = context.scope.getNetWithName(netName);
|
|
497
|
-
if (net !== null && net.namespace === netNamespace) {
|
|
498
|
-
return {
|
|
499
|
-
found: true,
|
|
500
|
-
net,
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
return {
|
|
505
|
-
found: false
|
|
506
|
-
};
|
|
507
|
-
};
|
|
508
|
-
return resolveNet;
|
|
509
|
-
}
|
|
510
|
-
visitFunction_def_expr(ctx) {
|
|
415
|
+
this.setResult(ctx, result);
|
|
416
|
+
};
|
|
417
|
+
visitFunction_def_expr = (ctx) => {
|
|
511
418
|
const functionName = ctx.ID().getText();
|
|
512
419
|
let funcDefinedParameters = [];
|
|
513
|
-
|
|
514
|
-
|
|
420
|
+
const ctxFunctionArgsExpr = ctx.function_args_expr();
|
|
421
|
+
if (ctxFunctionArgsExpr) {
|
|
422
|
+
this.visit(ctxFunctionArgsExpr);
|
|
423
|
+
funcDefinedParameters = this.getResult(ctxFunctionArgsExpr);
|
|
515
424
|
}
|
|
516
425
|
const executionStack = this.executionStack;
|
|
517
426
|
const functionCounter = { counter: 0 };
|
|
518
427
|
const resolveNet = this.createNetResolver(this.executionStack);
|
|
519
428
|
const __runFunc = (passedInParameters, options) => {
|
|
520
|
-
const { netNamespace = "" } = options;
|
|
521
|
-
const currentExecutionContext = executionStack[executionStack.length - 1];
|
|
522
|
-
const executionLevel = currentExecutionContext.executionLevel;
|
|
523
429
|
const executionContextName = functionName + '_' + functionCounter['counter'];
|
|
524
|
-
const
|
|
525
|
-
+ executionContextName + ".";
|
|
430
|
+
const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
|
|
526
431
|
functionCounter['counter'] += 1;
|
|
527
|
-
const newExecutor = new ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger);
|
|
528
|
-
this.setupPrintFunction(newExecutor);
|
|
529
432
|
newExecutor.resolveNet = resolveNet;
|
|
530
|
-
|
|
531
|
-
this.setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, newExecutor);
|
|
532
|
-
const returnValue = this.runExpressions(newExecutor, ctx.function_expr_list());
|
|
433
|
+
const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
|
|
533
434
|
const lastExecution = executionStack.pop();
|
|
534
435
|
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
535
436
|
nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
536
437
|
return [lastExecution, returnValue];
|
|
537
438
|
};
|
|
538
439
|
this.getExecutor().createFunction(functionName, __runFunc);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
const variableName = tmpFuncArg[0];
|
|
547
|
-
executor.print('set variable in scope, var name: ', variableName);
|
|
548
|
-
executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
|
|
549
|
-
if (tmpPassedInArgs[2] instanceof ClassComponent) {
|
|
550
|
-
const component = tmpPassedInArgs[2];
|
|
551
|
-
for (const [pinNumber, net] of component.pinNets) {
|
|
552
|
-
executor.scope.setNet(component, pinNumber, net);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
else if (tmpFuncArg.length === 2) {
|
|
558
|
-
const variableName = tmpFuncArg[0];
|
|
559
|
-
const defaultValue = tmpFuncArg[1];
|
|
560
|
-
executor.print('set variable in scope, var name: ', variableName);
|
|
561
|
-
executor.scope.variables.set(variableName, defaultValue);
|
|
562
|
-
}
|
|
563
|
-
else {
|
|
564
|
-
throw `Invalid arguments for function '${functionName}', got: `
|
|
565
|
-
+ passedInParameters;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
visitFunction_return_expr(ctx) {
|
|
570
|
-
const executor = this.getExecutor();
|
|
571
|
-
executor.print('return from function');
|
|
572
|
-
const returnValue = this.visit(ctx.data_expr());
|
|
573
|
-
executor.stopFurtherExpressions = true;
|
|
574
|
-
executor.returnValue = returnValue;
|
|
575
|
-
return returnValue;
|
|
576
|
-
}
|
|
577
|
-
visitAtom_expr(ctx) {
|
|
578
|
-
const executor = this.getExecutor();
|
|
579
|
-
const atomId = ctx.ID().getText();
|
|
580
|
-
let passedNetNamespace = null;
|
|
581
|
-
if (ctx.net_namespace_expr()) {
|
|
582
|
-
passedNetNamespace = this.visit(ctx.net_namespace_expr());
|
|
583
|
-
}
|
|
584
|
-
let currentReference;
|
|
585
|
-
if (this.pinTypesList.indexOf(atomId) !== -1) {
|
|
586
|
-
currentReference = {
|
|
587
|
-
found: true,
|
|
588
|
-
value: atomId
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
else {
|
|
592
|
-
currentReference = executor.resolveVariable(this.executionStack, atomId);
|
|
593
|
-
}
|
|
594
|
-
if (currentReference.found && currentReference.type === 'instance') {
|
|
595
|
-
const tmpComponent = currentReference.value;
|
|
596
|
-
for (const [pinId, net] of tmpComponent.pinNets) {
|
|
597
|
-
executor.scope.setNet(tmpComponent, pinId, net);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
if (ctx.trailer_expr_list().length > 0) {
|
|
601
|
-
if (!currentReference.found) {
|
|
602
|
-
throw "Could not find reference! " + atomId;
|
|
603
|
-
}
|
|
604
|
-
currentReference.trailers = [];
|
|
605
|
-
ctx.trailer_expr_list().forEach(item => {
|
|
606
|
-
const itemValue = item.getText();
|
|
607
|
-
if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
|
|
608
|
-
let parameters = [];
|
|
609
|
-
if (item.parameters()) {
|
|
610
|
-
parameters = this.visit(item.parameters());
|
|
611
|
-
}
|
|
612
|
-
const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
|
|
613
|
-
const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
|
|
614
|
-
currentReference = {
|
|
615
|
-
found: true,
|
|
616
|
-
value: functionResult,
|
|
617
|
-
type: (functionResult instanceof ClassComponent) ?
|
|
618
|
-
'instance' : 'value',
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
else {
|
|
622
|
-
currentReference.trailers.push(itemValue);
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
return currentReference;
|
|
627
|
-
}
|
|
628
|
-
visitPin_select_expr2(ctx) {
|
|
629
|
-
if (ctx.STRING_VALUE()) {
|
|
630
|
-
return this.prepareStringValue(ctx.STRING_VALUE().getText());
|
|
440
|
+
};
|
|
441
|
+
visitPin_select_expr2 = (ctx) => {
|
|
442
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
443
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
444
|
+
let result = null;
|
|
445
|
+
if (ctxStringValue) {
|
|
446
|
+
result = this.prepareStringValue(ctxStringValue.getText());
|
|
631
447
|
}
|
|
632
|
-
else if (
|
|
633
|
-
|
|
448
|
+
else if (ctxIntegerValue) {
|
|
449
|
+
result = Number(ctxIntegerValue.getText());
|
|
634
450
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
451
|
+
this.setResult(ctx, result);
|
|
452
|
+
};
|
|
453
|
+
visitAt_block_pin_expr = (ctx) => {
|
|
454
|
+
const ctxPinSelectExpr2 = ctx.pin_select_expr2();
|
|
455
|
+
this.visit(ctxPinSelectExpr2);
|
|
456
|
+
const atPin = this.getResult(ctxPinSelectExpr2);
|
|
638
457
|
const executor = this.getExecutor();
|
|
639
458
|
const currentComponent = executor.scope.currentComponent;
|
|
640
459
|
const currentPin = executor.scope.currentPin;
|
|
641
460
|
executor.atComponent(currentComponent, atPin, {
|
|
642
461
|
addSequence: true
|
|
643
462
|
});
|
|
644
|
-
executor.
|
|
645
|
-
|
|
646
|
-
|
|
463
|
+
executor.log('at block pin expressions');
|
|
464
|
+
const ctxAtBlockSimple = ctx.at_block_pin_expression_simple();
|
|
465
|
+
const ctxAtBlockComplex = ctx.at_block_pin_expression_complex();
|
|
466
|
+
if (ctxAtBlockSimple) {
|
|
467
|
+
this.visit(ctxAtBlockSimple);
|
|
647
468
|
}
|
|
648
|
-
else if (
|
|
649
|
-
this.visit(
|
|
469
|
+
else if (ctxAtBlockComplex) {
|
|
470
|
+
this.visit(ctxAtBlockComplex);
|
|
650
471
|
}
|
|
651
|
-
executor.
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
visitAt_block(ctx) {
|
|
472
|
+
executor.log('end at block pin expressions');
|
|
473
|
+
executor.atComponent(currentComponent, currentPin);
|
|
474
|
+
};
|
|
475
|
+
visitAt_block = (ctx) => {
|
|
655
476
|
const executor = this.getExecutor();
|
|
656
|
-
executor.
|
|
477
|
+
executor.log('entering at block');
|
|
657
478
|
this.visit(ctx.at_component_expr());
|
|
658
479
|
const currentComponent = executor.scope.currentComponent;
|
|
659
480
|
const currentPin = executor.scope.currentPin;
|
|
660
481
|
executor.scope.indentLevel += 1;
|
|
661
|
-
ctx.
|
|
482
|
+
ctx.at_block_expressions().forEach(expression => {
|
|
662
483
|
this.visit(expression);
|
|
663
484
|
});
|
|
664
485
|
executor.scope.indentLevel -= 1;
|
|
665
486
|
executor.scope.currentComponent = currentComponent;
|
|
666
487
|
executor.scope.currentPin = currentPin;
|
|
667
|
-
executor.
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
if (
|
|
672
|
-
this.visit(
|
|
488
|
+
executor.log('leaving at block');
|
|
489
|
+
};
|
|
490
|
+
visitAt_block_pin_expression_simple = (ctx) => {
|
|
491
|
+
const ctxExpression = ctx.expression();
|
|
492
|
+
if (ctxExpression) {
|
|
493
|
+
this.visit(ctxExpression);
|
|
673
494
|
}
|
|
674
495
|
else if (ctx.NOT_CONNECTED()) {
|
|
675
496
|
return;
|
|
676
497
|
}
|
|
677
|
-
}
|
|
678
|
-
visitAt_block_pin_expression_complex(ctx) {
|
|
679
|
-
ctx.
|
|
498
|
+
};
|
|
499
|
+
visitAt_block_pin_expression_complex = (ctx) => {
|
|
500
|
+
ctx.expression().forEach(item => {
|
|
680
501
|
this.visit(item);
|
|
681
502
|
});
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
705
|
-
segments.push(segment);
|
|
706
|
-
if (skipNext) {
|
|
707
|
-
i += 1;
|
|
708
|
-
}
|
|
503
|
+
};
|
|
504
|
+
visitWire_expr_direction_only = (ctx) => {
|
|
505
|
+
const value = ctx.ID().getText();
|
|
506
|
+
if (value === 'auto' || value === 'auto_') {
|
|
507
|
+
this.setResult(ctx, [value]);
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
throw 'Invalid direction for wire';
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
visitWire_expr_direction_value = (ctx) => {
|
|
514
|
+
const direction = ctx.ID().getText();
|
|
515
|
+
if (this.acceptedDirections.indexOf(direction) !== -1) {
|
|
516
|
+
let useValue = null;
|
|
517
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
518
|
+
const ctxDataExpr = ctx.data_expr();
|
|
519
|
+
if (ctxIntegerValue) {
|
|
520
|
+
useValue = Number(ctxIntegerValue);
|
|
521
|
+
}
|
|
522
|
+
else if (ctxDataExpr) {
|
|
523
|
+
this.visit(ctxDataExpr);
|
|
524
|
+
useValue = this.getResult(ctxDataExpr);
|
|
709
525
|
}
|
|
710
|
-
|
|
711
|
-
|
|
526
|
+
if (useValue !== null) {
|
|
527
|
+
this.setResult(ctx, [direction, useValue]);
|
|
528
|
+
return;
|
|
712
529
|
}
|
|
713
530
|
}
|
|
531
|
+
throw "Invalid direction or value for wire";
|
|
532
|
+
};
|
|
533
|
+
visitWire_expr = (ctx) => {
|
|
534
|
+
const wireAtomExpr = ctx.wire_atom_expr();
|
|
535
|
+
const segments = wireAtomExpr.map(wireSegment => {
|
|
536
|
+
this.visit(wireSegment);
|
|
537
|
+
return this.getResult(wireSegment);
|
|
538
|
+
});
|
|
714
539
|
this.getExecutor().addWire(segments);
|
|
715
|
-
}
|
|
716
|
-
visitPoint_expr(ctx) {
|
|
540
|
+
};
|
|
541
|
+
visitPoint_expr = (ctx) => {
|
|
717
542
|
const ID = ctx.ID();
|
|
718
543
|
return this.getExecutor().addPoint(ID.getText());
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const
|
|
722
|
-
this.
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
this.print('done import', ID);
|
|
729
|
-
}
|
|
730
|
-
visitProperty_set_expr(ctx) {
|
|
731
|
-
const result = this.visit(ctx.data_expr());
|
|
732
|
-
const resolvedProperty = this.visit(ctx.atom_expr());
|
|
544
|
+
};
|
|
545
|
+
visitProperty_set_expr = (ctx) => {
|
|
546
|
+
const ctxDataExpr = ctx.data_expr();
|
|
547
|
+
this.visit(ctxDataExpr);
|
|
548
|
+
const result = this.getResult(ctxDataExpr);
|
|
549
|
+
const ctxAtomExpr = ctx.atom_expr();
|
|
550
|
+
this.visit(ctxAtomExpr);
|
|
551
|
+
const resolvedProperty = this.getResult(ctxAtomExpr);
|
|
733
552
|
this.getExecutor().setProperty(resolvedProperty, result);
|
|
734
|
-
}
|
|
735
|
-
visitDouble_dot_property_set_expr(ctx) {
|
|
736
|
-
const
|
|
553
|
+
};
|
|
554
|
+
visitDouble_dot_property_set_expr = (ctx) => {
|
|
555
|
+
const ctxDataExpr = ctx.data_expr();
|
|
556
|
+
this.visit(ctxDataExpr);
|
|
557
|
+
const result = this.getResult(ctxDataExpr);
|
|
737
558
|
const propertyName = ctx.ID().getText();
|
|
738
559
|
this.getExecutor().setProperty('..' + propertyName, result);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
return this.visit(ctx.data_expr());
|
|
742
|
-
}
|
|
743
|
-
visitFrame_expr(ctx) {
|
|
560
|
+
};
|
|
561
|
+
visitFrame_expr = (ctx) => {
|
|
744
562
|
const frameId = this.getExecutor().enterFrame();
|
|
745
|
-
this.runExpressions(this.getExecutor(), ctx.
|
|
563
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
746
564
|
this.getExecutor().exitFrame(frameId);
|
|
747
|
-
}
|
|
748
|
-
visitNet_namespace_expr(ctx) {
|
|
565
|
+
};
|
|
566
|
+
visitNet_namespace_expr = (ctx) => {
|
|
749
567
|
let dataValue = null;
|
|
750
568
|
let netNamespace = null;
|
|
751
569
|
const hasPlus = ctx.Addition();
|
|
752
|
-
|
|
753
|
-
|
|
570
|
+
const ctxDataExpr = ctx.data_expr();
|
|
571
|
+
if (ctxDataExpr) {
|
|
572
|
+
this.visit(ctxDataExpr);
|
|
573
|
+
dataValue = this.getResult(ctxDataExpr);
|
|
754
574
|
if (dataValue instanceof UndeclaredReference) {
|
|
755
575
|
netNamespace = "/" + dataValue.reference.name;
|
|
756
576
|
}
|
|
@@ -764,8 +584,44 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
764
584
|
else {
|
|
765
585
|
netNamespace = "/";
|
|
766
586
|
}
|
|
767
|
-
|
|
768
|
-
}
|
|
587
|
+
this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
|
|
588
|
+
};
|
|
589
|
+
visitIf_expr = (ctx) => {
|
|
590
|
+
const ctxDataExpr = ctx.data_expr();
|
|
591
|
+
this.visit(ctxDataExpr);
|
|
592
|
+
const result = this.getResult(ctxDataExpr);
|
|
593
|
+
if (result) {
|
|
594
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
const ctxInnerIfExprs = ctx.if_inner_expr();
|
|
598
|
+
let innerIfWasTrue = false;
|
|
599
|
+
for (let i = 0; i < ctxInnerIfExprs.length; i++) {
|
|
600
|
+
const tmpCtx = ctxInnerIfExprs[i];
|
|
601
|
+
this.visit(tmpCtx);
|
|
602
|
+
const innerResult = this.getResult(tmpCtx);
|
|
603
|
+
if (innerResult) {
|
|
604
|
+
innerIfWasTrue = true;
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (!innerIfWasTrue) {
|
|
609
|
+
const elseCtx = ctx.else_expr();
|
|
610
|
+
if (elseCtx) {
|
|
611
|
+
this.visit(elseCtx);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
visitIf_inner_expr = (ctx) => {
|
|
617
|
+
const ctxDataExpr = ctx.data_expr();
|
|
618
|
+
this.visit(ctxDataExpr);
|
|
619
|
+
const result = this.getResult(ctxDataExpr);
|
|
620
|
+
if (result) {
|
|
621
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
622
|
+
}
|
|
623
|
+
this.setResult(ctx, result);
|
|
624
|
+
};
|
|
769
625
|
pinTypes = [
|
|
770
626
|
PinTypes.Any,
|
|
771
627
|
PinTypes.IO,
|
|
@@ -773,44 +629,6 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
773
629
|
PinTypes.Output,
|
|
774
630
|
PinTypes.Power,
|
|
775
631
|
];
|
|
776
|
-
createImportFileHandler(directory, defaultLibsPath) {
|
|
777
|
-
return (visitor, importPath) => {
|
|
778
|
-
let importResult;
|
|
779
|
-
importResult = this.importLib(visitor, directory, importPath);
|
|
780
|
-
if (!importResult.pathExists && importPath == 'lib') {
|
|
781
|
-
importResult = this.importLib(visitor, defaultLibsPath, importPath);
|
|
782
|
-
}
|
|
783
|
-
return importResult;
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
importLib(visitor, directory, filename) {
|
|
787
|
-
const tmpFilePath = join(directory, filename + ".cst");
|
|
788
|
-
visitor.print('importing path:', tmpFilePath);
|
|
789
|
-
let pathExists = false;
|
|
790
|
-
let fileData = null;
|
|
791
|
-
try {
|
|
792
|
-
fileData = readFileSync(tmpFilePath, { encoding: 'utf8' });
|
|
793
|
-
pathExists = true;
|
|
794
|
-
}
|
|
795
|
-
catch (err) {
|
|
796
|
-
pathExists = false;
|
|
797
|
-
}
|
|
798
|
-
try {
|
|
799
|
-
if (pathExists) {
|
|
800
|
-
visitor.print('done reading imported file data');
|
|
801
|
-
const { hasError, hasParseError } = parseFileWithVisitor(visitor, fileData);
|
|
802
|
-
return { hasError, hasParseError, pathExists };
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
catch (err) {
|
|
806
|
-
visitor.print('Failed to import file: ', err.message);
|
|
807
|
-
}
|
|
808
|
-
return {
|
|
809
|
-
hasError: true,
|
|
810
|
-
hasParseError: true,
|
|
811
|
-
pathExists,
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
632
|
parseCreateComponentPins(pinData) {
|
|
815
633
|
const pins = [];
|
|
816
634
|
if (typeof pinData === 'number') {
|
|
@@ -831,8 +649,10 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
831
649
|
}
|
|
832
650
|
if (Array.isArray(pinDef)) {
|
|
833
651
|
const firstValue = pinDef[0];
|
|
834
|
-
if (
|
|
835
|
-
|
|
652
|
+
if (firstValue.type
|
|
653
|
+
&& firstValue.type === ReferenceTypes.pinType
|
|
654
|
+
&& this.pinTypes.indexOf(firstValue.value) !== -1) {
|
|
655
|
+
pinType = firstValue.value;
|
|
836
656
|
pinName = pinDef[1];
|
|
837
657
|
if (pinDef.length > 2) {
|
|
838
658
|
altPinNames = pinDef.slice(2);
|
|
@@ -862,18 +682,6 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
862
682
|
}
|
|
863
683
|
return result;
|
|
864
684
|
}
|
|
865
|
-
prepareStringValue(value) {
|
|
866
|
-
return value.slice(1, value.length - 1);
|
|
867
|
-
}
|
|
868
|
-
print(...params) {
|
|
869
|
-
const indentOutput = ''.padStart(this.indentLevel * 4, ' ');
|
|
870
|
-
const indentLevelText = this.indentLevel.toString().padStart(3, ' ');
|
|
871
|
-
const args = ['[' + indentLevelText + ']', indentOutput, ...params];
|
|
872
|
-
this.logger.add(args.join(' '));
|
|
873
|
-
if (!this.silent) {
|
|
874
|
-
console.log.apply(null, args);
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
685
|
printNets() {
|
|
878
686
|
this.getExecutor().scope.printNets();
|
|
879
687
|
}
|
|
@@ -935,7 +743,10 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
935
743
|
}
|
|
936
744
|
getGraph() {
|
|
937
745
|
const executor = this.getExecutor();
|
|
938
|
-
const
|
|
746
|
+
const fullSequence = executor.scope.sequence;
|
|
747
|
+
const tmpNet = executor.scope.getNet(executor.scope.componentRoot, 1);
|
|
748
|
+
const sequence = (tmpNet === null)
|
|
749
|
+
? fullSequence.slice(1) : fullSequence;
|
|
939
750
|
const nets = executor.scope.getNets();
|
|
940
751
|
return {
|
|
941
752
|
sequence,
|
|
@@ -944,7 +755,7 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
944
755
|
};
|
|
945
756
|
}
|
|
946
757
|
annotateComponents() {
|
|
947
|
-
this.
|
|
758
|
+
this.log('===== annotate components =====');
|
|
948
759
|
const annotater = new ComponentAnnotater();
|
|
949
760
|
const instances = this.getExecutor().scope.instances;
|
|
950
761
|
const toAnnotate = [];
|
|
@@ -956,7 +767,7 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
956
767
|
continue;
|
|
957
768
|
}
|
|
958
769
|
if (instance.typeProp === null) {
|
|
959
|
-
this.
|
|
770
|
+
this.log('Instance has no type:', instance.instanceName, ' assuming connector');
|
|
960
771
|
instance.typeProp = 'conn';
|
|
961
772
|
}
|
|
962
773
|
if (instance.parameters.has('refdes')) {
|
|
@@ -964,7 +775,7 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
964
775
|
if (refdes) {
|
|
965
776
|
instance.assignedRefDes = refdes;
|
|
966
777
|
annotater.trackRefDes(refdes);
|
|
967
|
-
this.
|
|
778
|
+
this.log(refdes, '-', instance.instanceName);
|
|
968
779
|
continue;
|
|
969
780
|
}
|
|
970
781
|
}
|
|
@@ -975,14 +786,14 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
975
786
|
const newRefDes = annotater.getAnnotation(instance.typeProp);
|
|
976
787
|
if (newRefDes !== null) {
|
|
977
788
|
instance.assignedRefDes = newRefDes;
|
|
978
|
-
this.
|
|
789
|
+
this.log(newRefDes, '-', instance.instanceName);
|
|
979
790
|
}
|
|
980
791
|
else {
|
|
981
|
-
this.
|
|
792
|
+
this.log('Failed to annotate:', instance.instanceName);
|
|
982
793
|
}
|
|
983
794
|
});
|
|
984
|
-
this.
|
|
985
|
-
this.
|
|
795
|
+
this.log('===== annotate done =====');
|
|
796
|
+
this.log('');
|
|
986
797
|
}
|
|
987
798
|
resolveNets(scope, instance) {
|
|
988
799
|
const result = [];
|
|
@@ -1011,61 +822,22 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
1011
822
|
throw "Invalid modifier for orientation";
|
|
1012
823
|
}
|
|
1013
824
|
}
|
|
825
|
+
setComponentFlip(component, flipValue) {
|
|
826
|
+
if (this.acceptedFlip.indexOf(flipValue) !== -1) {
|
|
827
|
+
component.setParam(flipValue, 1);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
1014
830
|
getPropertyExprList(items) {
|
|
1015
831
|
const properties = new Map();
|
|
1016
832
|
items.forEach((item) => {
|
|
1017
|
-
|
|
833
|
+
this.visit(item);
|
|
834
|
+
const result = this.getResult(item);
|
|
1018
835
|
for (const [key, value] of result) {
|
|
1019
836
|
properties.set(key, value);
|
|
1020
837
|
}
|
|
1021
838
|
});
|
|
1022
839
|
return properties;
|
|
1023
840
|
}
|
|
1024
|
-
runExpressions(executor, expressions) {
|
|
1025
|
-
let returnValue = null;
|
|
1026
|
-
for (let i = 0; i < expressions.length; i++) {
|
|
1027
|
-
const expr = expressions[i];
|
|
1028
|
-
this.visit(expr);
|
|
1029
|
-
if (executor.stopFurtherExpressions) {
|
|
1030
|
-
returnValue = executor.returnValue;
|
|
1031
|
-
break;
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
return returnValue;
|
|
1035
|
-
}
|
|
1036
|
-
setupPrintFunction(context) {
|
|
1037
|
-
context.createFunction('print', (params) => {
|
|
1038
|
-
const items = params.map(([, , value]) => {
|
|
1039
|
-
return value;
|
|
1040
|
-
});
|
|
1041
|
-
if (this.printToConsole) {
|
|
1042
|
-
console.log('::', ...items);
|
|
1043
|
-
}
|
|
1044
|
-
this.printStream.push(...items);
|
|
1045
|
-
return [this, null];
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
getNetNamespace(executorNetNamespace, passedNetNamespace) {
|
|
1049
|
-
let result = executorNetNamespace;
|
|
1050
|
-
if (passedNetNamespace !== null && passedNetNamespace.length > 0) {
|
|
1051
|
-
if (passedNetNamespace === '/' || passedNetNamespace === '_') {
|
|
1052
|
-
result = '';
|
|
1053
|
-
}
|
|
1054
|
-
else if (passedNetNamespace[0] === '+') {
|
|
1055
|
-
if (executorNetNamespace === '/') {
|
|
1056
|
-
result = passedNetNamespace.slice(1);
|
|
1057
|
-
}
|
|
1058
|
-
else {
|
|
1059
|
-
result = executorNetNamespace + passedNetNamespace.slice(2);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
else {
|
|
1063
|
-
result = passedNetNamespace;
|
|
1064
|
-
}
|
|
1065
|
-
result = result + '/';
|
|
1066
|
-
}
|
|
1067
|
-
return result;
|
|
1068
|
-
}
|
|
1069
841
|
}
|
|
1070
842
|
const ComponentRefDesPrefixes = {
|
|
1071
843
|
'res': 'R',
|