circuitscript 0.0.24 → 0.0.25
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 +487 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +209 -195
- package/dist/cjs/antlr/CircuitScriptParser.js +2310 -2087
- package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
- package/dist/cjs/draw_symbols.js +67 -22
- package/dist/cjs/execute.js +51 -53
- package/dist/cjs/geometry.js +28 -8
- package/dist/cjs/helpers.js +175 -5
- 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 +6 -11
- package/dist/cjs/objects/ClassComponent.js +3 -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/validate.js +81 -0
- package/dist/cjs/visitor.js +529 -820
- package/dist/esm/BaseVisitor.mjs +488 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +184 -194
- package/dist/esm/antlr/CircuitScriptParser.mjs +2279 -2084
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +8 -3
- package/dist/esm/draw_symbols.mjs +67 -22
- package/dist/esm/execute.mjs +50 -52
- package/dist/esm/geometry.mjs +28 -8
- package/dist/esm/helpers.mjs +165 -6
- 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 +7 -12
- package/dist/esm/objects/ClassComponent.mjs +3 -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/validate.mjs +74 -0
- package/dist/esm/visitor.mjs +343 -640
- package/dist/types/BaseVisitor.d.ts +69 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +8 -7
- package/dist/types/antlr/CircuitScriptParser.d.ts +513 -469
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +69 -59
- package/dist/types/draw_symbols.d.ts +9 -0
- package/dist/types/execute.d.ts +5 -8
- package/dist/types/geometry.d.ts +4 -0
- 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/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 +40 -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 +183 -0
- package/package.json +11 -6
package/dist/esm/visitor.mjs
CHANGED
|
@@ -1,239 +1,87 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import { ExecutionContext } from './execute.mjs';
|
|
1
|
+
import { isNetOnlyComponent } from './execute.mjs';
|
|
5
2
|
import { ClassComponent } from './objects/ClassComponent.mjs';
|
|
6
|
-
import { NumericValue, ParamDefinition,
|
|
3
|
+
import { NumericValue, ParamDefinition, } from './objects/ParamDefinition.mjs';
|
|
7
4
|
import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
|
|
8
5
|
import { PinTypes } from './objects/PinTypes.mjs';
|
|
9
6
|
import { UndeclaredReference } from './objects/types.mjs';
|
|
10
|
-
import { Logger } from './logger.mjs';
|
|
11
7
|
import { BlockTypes, ComponentTypes, NoNetText } from './globals.mjs';
|
|
12
8
|
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) {
|
|
9
|
+
import { BaseVisitor } from './BaseVisitor.mjs';
|
|
10
|
+
export class ParserVisitor extends BaseVisitor {
|
|
11
|
+
visitKeyword_assignment_expr = (ctx) => {
|
|
95
12
|
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());
|
|
13
|
+
const ctxDataExpr = ctx.data_expr();
|
|
14
|
+
this.visit(ctxDataExpr);
|
|
15
|
+
const value = this.getResult(ctxDataExpr);
|
|
16
|
+
this.setResult(ctx, [id, value]);
|
|
17
|
+
};
|
|
18
|
+
visitPin_select_expr = (ctx) => {
|
|
19
|
+
let value = null;
|
|
20
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
21
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
22
|
+
if (ctxIntegerValue) {
|
|
23
|
+
value = Number(ctxIntegerValue.getText());
|
|
178
24
|
}
|
|
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());
|
|
25
|
+
else if (ctxStringValue) {
|
|
26
|
+
value = this.prepareStringValue(ctxStringValue.getText());
|
|
185
27
|
}
|
|
28
|
+
this.setResult(ctx, value);
|
|
29
|
+
};
|
|
30
|
+
visitAdd_component_expr = (ctx) => {
|
|
31
|
+
const ctxDataWithAssignmentExpr = ctx.data_expr_with_assignment();
|
|
32
|
+
this.setParam(ctxDataWithAssignmentExpr, { clone: false });
|
|
33
|
+
this.visit(ctxDataWithAssignmentExpr);
|
|
34
|
+
const [component, pinValue] = this.getResult(ctxDataWithAssignmentExpr);
|
|
186
35
|
return this.getExecutor().addComponentExisting(component, pinValue);
|
|
187
|
-
}
|
|
188
|
-
visitAt_component_expr(ctx) {
|
|
36
|
+
};
|
|
37
|
+
visitAt_component_expr = (ctx) => {
|
|
189
38
|
if (ctx.Point()) {
|
|
190
39
|
this.getExecutor().atPointBlock();
|
|
191
40
|
}
|
|
192
41
|
else {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
42
|
+
const ctxComponentSelectExpr = ctx.component_select_expr();
|
|
43
|
+
this.visit(ctxComponentSelectExpr);
|
|
44
|
+
const [component, pin] = this.getResult(ctxComponentSelectExpr);
|
|
45
|
+
this.getExecutor().atComponent(component, pin, {
|
|
46
|
+
addSequence: true
|
|
197
47
|
});
|
|
198
|
-
if (ctx.ID()) {
|
|
199
|
-
this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
|
|
200
|
-
}
|
|
201
48
|
}
|
|
202
49
|
return this.getExecutor().getCurrentPoint();
|
|
203
|
-
}
|
|
204
|
-
visitTo_component_expr(ctx) {
|
|
205
|
-
let currentPoint;
|
|
50
|
+
};
|
|
51
|
+
visitTo_component_expr = (ctx) => {
|
|
206
52
|
if (ctx.Point()) {
|
|
207
53
|
this.getExecutor().toPointBlock();
|
|
208
54
|
}
|
|
209
55
|
else {
|
|
210
|
-
ctx.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
56
|
+
ctx.component_select_expr().forEach(item => {
|
|
57
|
+
this.visit(item);
|
|
58
|
+
const [component, pin] = this.getResult(item);
|
|
59
|
+
this.getExecutor().toComponent(component, pin, {
|
|
60
|
+
addSequence: true
|
|
214
61
|
});
|
|
215
62
|
});
|
|
216
|
-
if (ctx.ID()) {
|
|
217
|
-
this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
|
|
218
|
-
}
|
|
219
63
|
}
|
|
220
64
|
return this.getExecutor().getCurrentPoint();
|
|
221
|
-
}
|
|
222
|
-
visitComponent_select_expr(ctx) {
|
|
223
|
-
|
|
224
|
-
|
|
65
|
+
};
|
|
66
|
+
visitComponent_select_expr = (ctx) => {
|
|
67
|
+
const ctxDataExprWithAssigment = ctx.data_expr_with_assignment();
|
|
68
|
+
if (ctxDataExprWithAssigment) {
|
|
69
|
+
this.visit(ctxDataExprWithAssigment);
|
|
70
|
+
this.setResult(ctx, this.getResult(ctxDataExprWithAssigment));
|
|
225
71
|
}
|
|
226
72
|
else {
|
|
227
73
|
const component = this.getExecutor().scope.currentComponent;
|
|
228
74
|
let pinId = null;
|
|
229
|
-
|
|
230
|
-
|
|
75
|
+
const ctxPinSelectExpr = ctx.pin_select_expr();
|
|
76
|
+
if (ctxPinSelectExpr) {
|
|
77
|
+
this.visit(ctxPinSelectExpr);
|
|
78
|
+
pinId = this.getResult(ctxPinSelectExpr);
|
|
231
79
|
}
|
|
232
|
-
|
|
80
|
+
this.setResult(ctx, [component, pinId]);
|
|
233
81
|
}
|
|
234
|
-
}
|
|
235
|
-
visitPath_blocks(ctx) {
|
|
236
|
-
const blocks = ctx.
|
|
82
|
+
};
|
|
83
|
+
visitPath_blocks = (ctx) => {
|
|
84
|
+
const blocks = ctx.path_block_inner();
|
|
237
85
|
let blockIndex = 0;
|
|
238
86
|
let blockType = BlockTypes.Branch;
|
|
239
87
|
let prevBlockType = null;
|
|
@@ -265,13 +113,9 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
265
113
|
});
|
|
266
114
|
this.getExecutor().exitBlocks();
|
|
267
115
|
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());
|
|
116
|
+
};
|
|
117
|
+
visitCreate_component_expr = (ctx) => {
|
|
118
|
+
const properties = this.getPropertyExprList(ctx.property_expr());
|
|
275
119
|
const pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
276
120
|
let instanceName = this.getExecutor().getUniqueInstanceName('');
|
|
277
121
|
const propParams = properties.get('params');
|
|
@@ -299,11 +143,12 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
299
143
|
type,
|
|
300
144
|
width,
|
|
301
145
|
};
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
visitCreate_graphic_expr(ctx) {
|
|
305
|
-
const commands = ctx.
|
|
306
|
-
|
|
146
|
+
this.setResult(ctx, this.getExecutor().createComponent(instanceName, pins, params, props));
|
|
147
|
+
};
|
|
148
|
+
visitCreate_graphic_expr = (ctx) => {
|
|
149
|
+
const commands = ctx.sub_expr().reduce((accum, item) => {
|
|
150
|
+
this.visit(item);
|
|
151
|
+
const [commandName, parameters] = this.getResult(item);
|
|
307
152
|
const keywordParams = new Map();
|
|
308
153
|
const positionParams = parameters.reduce((accum, [argType, name, value]) => {
|
|
309
154
|
if (argType === 'position') {
|
|
@@ -317,100 +162,144 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
317
162
|
accum.push([commandName, positionParams, keywordParams]);
|
|
318
163
|
return accum;
|
|
319
164
|
}, []);
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
165
|
+
const drawing = new SymbolDrawingCommands(commands);
|
|
166
|
+
drawing.source = ctx.getText();
|
|
167
|
+
this.setResult(ctx, drawing);
|
|
168
|
+
};
|
|
169
|
+
visitSub_expr = (ctx) => {
|
|
323
170
|
let commandName = null;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
else if (ctx.Pin()) {
|
|
328
|
-
commandName = ctx.Pin().getText();
|
|
171
|
+
const command = ctx._command;
|
|
172
|
+
if (command) {
|
|
173
|
+
commandName = command.text;
|
|
329
174
|
}
|
|
330
175
|
else {
|
|
331
176
|
throw "Invalid command!";
|
|
332
177
|
}
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
178
|
+
const ctxParameters = ctx.parameters();
|
|
179
|
+
this.visit(ctxParameters);
|
|
180
|
+
const parameters = this.getResult(ctxParameters);
|
|
181
|
+
this.setResult(ctx, [commandName, parameters]);
|
|
182
|
+
};
|
|
183
|
+
visitProperty_expr = (ctx) => {
|
|
184
|
+
const ctxPropertyKeyExpr = ctx.property_key_expr();
|
|
185
|
+
const ctxPropertyValueExpr = ctx.property_value_expr();
|
|
186
|
+
this.visit(ctxPropertyKeyExpr);
|
|
187
|
+
this.visit(ctxPropertyValueExpr);
|
|
188
|
+
const keyName = this.getResult(ctxPropertyKeyExpr);
|
|
189
|
+
const value = this.getResult(ctxPropertyValueExpr);
|
|
339
190
|
const map = new Map();
|
|
340
191
|
map.set(keyName, value);
|
|
341
|
-
|
|
342
|
-
}
|
|
343
|
-
visitSingle_line_property(ctx) {
|
|
192
|
+
this.setResult(ctx, map);
|
|
193
|
+
};
|
|
194
|
+
visitSingle_line_property = (ctx) => {
|
|
344
195
|
let value;
|
|
345
|
-
if (ctx.
|
|
346
|
-
|
|
196
|
+
if (ctx.data_expr().length === 1) {
|
|
197
|
+
const ctxFirst = ctx.data_expr(0);
|
|
198
|
+
this.visit(ctxFirst);
|
|
199
|
+
value = this.getResult(ctxFirst);
|
|
347
200
|
}
|
|
348
201
|
else {
|
|
349
|
-
value = ctx.
|
|
350
|
-
|
|
202
|
+
value = ctx.data_expr().map(item => {
|
|
203
|
+
this.visit(item);
|
|
204
|
+
return this.getResult(item);
|
|
351
205
|
});
|
|
352
206
|
}
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
visitNested_properties(ctx) {
|
|
207
|
+
this.setResult(ctx, value);
|
|
208
|
+
};
|
|
209
|
+
visitNested_properties = (ctx) => {
|
|
356
210
|
const result = new Map();
|
|
357
|
-
ctx.
|
|
358
|
-
|
|
211
|
+
ctx.property_expr().forEach((item) => {
|
|
212
|
+
this.visit(item);
|
|
213
|
+
const property = this.getResult(item);
|
|
359
214
|
for (const [key, value] of property) {
|
|
360
215
|
result.set(key, value);
|
|
361
216
|
}
|
|
362
217
|
});
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
visitProperty_key_expr(ctx) {
|
|
366
|
-
|
|
367
|
-
|
|
218
|
+
this.setResult(ctx, result);
|
|
219
|
+
};
|
|
220
|
+
visitProperty_key_expr = (ctx) => {
|
|
221
|
+
const ctxID = ctx.ID();
|
|
222
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
223
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
224
|
+
let result = null;
|
|
225
|
+
if (ctxID) {
|
|
226
|
+
result = ctxID.getText();
|
|
368
227
|
}
|
|
369
|
-
else if (
|
|
370
|
-
|
|
228
|
+
else if (ctxIntegerValue) {
|
|
229
|
+
result = Number(ctxIntegerValue.getText());
|
|
371
230
|
}
|
|
372
|
-
else if (
|
|
373
|
-
|
|
231
|
+
else if (ctxStringValue) {
|
|
232
|
+
result = this.prepareStringValue(ctxStringValue.getText());
|
|
374
233
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
234
|
+
this.setResult(ctx, result);
|
|
235
|
+
};
|
|
236
|
+
visitData_expr_with_assignment = (ctx) => {
|
|
237
|
+
let component = null;
|
|
238
|
+
const ctxDataExpr = ctx.data_expr();
|
|
239
|
+
const ctxAssignmentExpr = ctx.assignment_expr();
|
|
240
|
+
if (ctxDataExpr) {
|
|
241
|
+
this.visit(ctxDataExpr);
|
|
242
|
+
component = this.getResult(ctxDataExpr);
|
|
380
243
|
if (component === null || component === undefined) {
|
|
381
|
-
throw "Could not find component: " +
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
else if (
|
|
385
|
-
|
|
244
|
+
throw "Could not find component: " + ctxDataExpr.getText();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else if (ctxAssignmentExpr) {
|
|
248
|
+
this.visit(ctxAssignmentExpr);
|
|
249
|
+
component = this.getResult(ctxAssignmentExpr);
|
|
250
|
+
}
|
|
251
|
+
let allowClone = true;
|
|
252
|
+
if (this.hasParam(ctx)) {
|
|
253
|
+
const { clone } = this.getParam(ctx);
|
|
254
|
+
allowClone = clone;
|
|
255
|
+
}
|
|
256
|
+
if (allowClone && component instanceof ClassComponent
|
|
257
|
+
&& isNetOnlyComponent(component)) {
|
|
258
|
+
component = this.getExecutor().cloneComponent(component);
|
|
259
|
+
}
|
|
260
|
+
if (component && component instanceof ClassComponent) {
|
|
261
|
+
const modifiers = ctx.component_modifier_expr();
|
|
262
|
+
modifiers.forEach(modifier => {
|
|
263
|
+
const modifierText = modifier.ID(0).getText();
|
|
264
|
+
const ctxValueExpr = modifier.value_expr();
|
|
265
|
+
const ctxID2 = modifier.ID(1);
|
|
266
|
+
let result = null;
|
|
267
|
+
if (ctxValueExpr) {
|
|
268
|
+
this.visit(ctxValueExpr);
|
|
269
|
+
result = this.getResult(ctxValueExpr);
|
|
270
|
+
}
|
|
271
|
+
else if (ctxID2) {
|
|
272
|
+
result = ctxID2.getText();
|
|
273
|
+
}
|
|
274
|
+
if (modifierText === 'flip') {
|
|
275
|
+
const flipValue = result;
|
|
276
|
+
if (flipValue.indexOf('x') !== -1) {
|
|
277
|
+
component.setParam('flipX', 1);
|
|
278
|
+
}
|
|
279
|
+
if (flipValue.indexOf('y') !== -1) {
|
|
280
|
+
component.setParam('flipY', 1);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else if (modifierText === 'angle') {
|
|
284
|
+
const angleValue = Number(result);
|
|
285
|
+
component.setParam('angle', angleValue);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
386
288
|
}
|
|
387
289
|
let pinValue = null;
|
|
388
|
-
|
|
389
|
-
|
|
290
|
+
const ctxPinSelectExpr = ctx.pin_select_expr();
|
|
291
|
+
if (ctxPinSelectExpr) {
|
|
292
|
+
this.visit(ctxPinSelectExpr);
|
|
293
|
+
pinValue = this.getResult(ctxPinSelectExpr);
|
|
390
294
|
}
|
|
391
295
|
else {
|
|
392
296
|
pinValue = component.getDefaultPin();
|
|
393
297
|
}
|
|
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());
|
|
298
|
+
this.setResult(ctx, [component, pinValue]);
|
|
299
|
+
};
|
|
300
|
+
visitUnaryOperatorExpr = (ctx) => {
|
|
301
|
+
this.visit(ctx.data_expr());
|
|
302
|
+
let value = this.getResult(ctx.data_expr());
|
|
414
303
|
const unaryOp = ctx.unary_operator();
|
|
415
304
|
if (unaryOp) {
|
|
416
305
|
if (unaryOp.Not()) {
|
|
@@ -423,334 +312,234 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
423
312
|
}
|
|
424
313
|
else if (unaryOp.Minus()) {
|
|
425
314
|
if (typeof value === 'number') {
|
|
426
|
-
|
|
315
|
+
value = -value;
|
|
427
316
|
}
|
|
428
317
|
else {
|
|
429
318
|
throw "Failed to do Negation operator";
|
|
430
319
|
}
|
|
431
320
|
}
|
|
432
321
|
}
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
visitDataExpr(ctx) {
|
|
322
|
+
this.setResult(ctx, value);
|
|
323
|
+
};
|
|
324
|
+
visitDataExpr = (ctx) => {
|
|
436
325
|
let value;
|
|
437
|
-
|
|
438
|
-
|
|
326
|
+
const ctxCreateComponentExpr = ctx.create_component_expr();
|
|
327
|
+
const ctxCreateGraphicExpr = ctx.create_graphic_expr();
|
|
328
|
+
if (ctxCreateComponentExpr) {
|
|
329
|
+
this.visit(ctxCreateComponentExpr);
|
|
330
|
+
value = this.getResult(ctxCreateComponentExpr);
|
|
439
331
|
}
|
|
440
|
-
else if (
|
|
441
|
-
|
|
332
|
+
else if (ctxCreateGraphicExpr) {
|
|
333
|
+
this.visit(ctxCreateGraphicExpr);
|
|
334
|
+
value = this.getResult(ctxCreateGraphicExpr);
|
|
442
335
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
336
|
+
else {
|
|
337
|
+
throw "Invalid data expression";
|
|
338
|
+
}
|
|
339
|
+
this.setResult(ctx, value);
|
|
340
|
+
};
|
|
341
|
+
visitBinaryOperatorExpr = (ctx) => {
|
|
342
|
+
const ctx0 = ctx.data_expr(0);
|
|
343
|
+
const ctx1 = ctx.data_expr(1);
|
|
344
|
+
this.visit(ctx0);
|
|
345
|
+
this.visit(ctx1);
|
|
346
|
+
const value1 = this.getResult(ctx0);
|
|
347
|
+
const value2 = this.getResult(ctx1);
|
|
448
348
|
const binaryOperatorType = ctx.binary_operator();
|
|
349
|
+
let result = null;
|
|
449
350
|
if (binaryOperatorType.Equals()) {
|
|
450
|
-
|
|
351
|
+
result = value1 == value2;
|
|
451
352
|
}
|
|
452
353
|
else if (binaryOperatorType.NotEquals()) {
|
|
453
|
-
|
|
354
|
+
result = value1 != value2;
|
|
454
355
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
356
|
+
this.setResult(ctx, result);
|
|
357
|
+
};
|
|
358
|
+
visitMultiplyExpr = (ctx) => {
|
|
359
|
+
this.visit(ctx.data_expr(0));
|
|
360
|
+
this.visit(ctx.data_expr(1));
|
|
361
|
+
const value1 = this.getResult(ctx.data_expr(0));
|
|
362
|
+
const value2 = this.getResult(ctx.data_expr(1));
|
|
363
|
+
let result = null;
|
|
459
364
|
if (ctx.Multiply()) {
|
|
460
|
-
|
|
365
|
+
result = value1 * value2;
|
|
461
366
|
}
|
|
462
367
|
else if (ctx.Divide()) {
|
|
463
|
-
|
|
368
|
+
result = value1 / value2;
|
|
464
369
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
370
|
+
this.setResult(ctx, result);
|
|
371
|
+
};
|
|
372
|
+
visitAdditionExpr = (ctx) => {
|
|
373
|
+
this.visit(ctx.data_expr(0));
|
|
374
|
+
this.visit(ctx.data_expr(1));
|
|
375
|
+
const value1 = this.getResult(ctx.data_expr(0));
|
|
376
|
+
const value2 = this.getResult(ctx.data_expr(1));
|
|
377
|
+
let result = null;
|
|
469
378
|
if (ctx.Addition()) {
|
|
470
|
-
|
|
379
|
+
result = value1 + value2;
|
|
471
380
|
}
|
|
472
381
|
else if (ctx.Minus()) {
|
|
473
|
-
|
|
382
|
+
result = value1 - value2;
|
|
474
383
|
}
|
|
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) {
|
|
384
|
+
this.setResult(ctx, result);
|
|
385
|
+
};
|
|
386
|
+
visitFunction_def_expr = (ctx) => {
|
|
511
387
|
const functionName = ctx.ID().getText();
|
|
512
388
|
let funcDefinedParameters = [];
|
|
513
|
-
|
|
514
|
-
|
|
389
|
+
const ctxFunctionArgsExpr = ctx.function_args_expr();
|
|
390
|
+
if (ctxFunctionArgsExpr) {
|
|
391
|
+
this.visit(ctxFunctionArgsExpr);
|
|
392
|
+
funcDefinedParameters = this.getResult(ctxFunctionArgsExpr);
|
|
515
393
|
}
|
|
516
394
|
const executionStack = this.executionStack;
|
|
517
395
|
const functionCounter = { counter: 0 };
|
|
518
396
|
const resolveNet = this.createNetResolver(this.executionStack);
|
|
519
397
|
const __runFunc = (passedInParameters, options) => {
|
|
520
|
-
const { netNamespace = "" } = options;
|
|
521
|
-
const currentExecutionContext = executionStack[executionStack.length - 1];
|
|
522
|
-
const executionLevel = currentExecutionContext.executionLevel;
|
|
523
398
|
const executionContextName = functionName + '_' + functionCounter['counter'];
|
|
524
|
-
const
|
|
525
|
-
+ executionContextName + ".";
|
|
399
|
+
const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
|
|
526
400
|
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
401
|
newExecutor.resolveNet = resolveNet;
|
|
530
|
-
|
|
531
|
-
this.setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, newExecutor);
|
|
532
|
-
const returnValue = this.runExpressions(newExecutor, ctx.function_expr_list());
|
|
402
|
+
const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
|
|
533
403
|
const lastExecution = executionStack.pop();
|
|
534
404
|
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
535
405
|
nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
536
406
|
return [lastExecution, returnValue];
|
|
537
407
|
};
|
|
538
408
|
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());
|
|
409
|
+
};
|
|
410
|
+
visitPin_select_expr2 = (ctx) => {
|
|
411
|
+
const ctxStringValue = ctx.STRING_VALUE();
|
|
412
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
413
|
+
let result = null;
|
|
414
|
+
if (ctxStringValue) {
|
|
415
|
+
result = this.prepareStringValue(ctxStringValue.getText());
|
|
631
416
|
}
|
|
632
|
-
else if (
|
|
633
|
-
|
|
417
|
+
else if (ctxIntegerValue) {
|
|
418
|
+
result = Number(ctxIntegerValue.getText());
|
|
634
419
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
420
|
+
this.setResult(ctx, result);
|
|
421
|
+
};
|
|
422
|
+
visitAt_block_pin_expr = (ctx) => {
|
|
423
|
+
const ctxPinSelectExpr2 = ctx.pin_select_expr2();
|
|
424
|
+
this.visit(ctxPinSelectExpr2);
|
|
425
|
+
const atPin = this.getResult(ctxPinSelectExpr2);
|
|
638
426
|
const executor = this.getExecutor();
|
|
639
427
|
const currentComponent = executor.scope.currentComponent;
|
|
640
428
|
const currentPin = executor.scope.currentPin;
|
|
641
429
|
executor.atComponent(currentComponent, atPin, {
|
|
642
430
|
addSequence: true
|
|
643
431
|
});
|
|
644
|
-
executor.
|
|
645
|
-
|
|
646
|
-
|
|
432
|
+
executor.log('at block pin expressions');
|
|
433
|
+
const ctxAtBlockSimple = ctx.at_block_pin_expression_simple();
|
|
434
|
+
const ctxAtBlockComplex = ctx.at_block_pin_expression_complex();
|
|
435
|
+
if (ctxAtBlockSimple) {
|
|
436
|
+
this.visit(ctxAtBlockSimple);
|
|
647
437
|
}
|
|
648
|
-
else if (
|
|
649
|
-
this.visit(
|
|
438
|
+
else if (ctxAtBlockComplex) {
|
|
439
|
+
this.visit(ctxAtBlockComplex);
|
|
650
440
|
}
|
|
651
|
-
executor.
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
visitAt_block(ctx) {
|
|
441
|
+
executor.log('end at block pin expressions');
|
|
442
|
+
executor.atComponent(currentComponent, currentPin);
|
|
443
|
+
};
|
|
444
|
+
visitAt_block = (ctx) => {
|
|
655
445
|
const executor = this.getExecutor();
|
|
656
|
-
executor.
|
|
446
|
+
executor.log('entering at block');
|
|
657
447
|
this.visit(ctx.at_component_expr());
|
|
658
448
|
const currentComponent = executor.scope.currentComponent;
|
|
659
449
|
const currentPin = executor.scope.currentPin;
|
|
660
450
|
executor.scope.indentLevel += 1;
|
|
661
|
-
ctx.
|
|
451
|
+
ctx.at_block_expressions().forEach(expression => {
|
|
662
452
|
this.visit(expression);
|
|
663
453
|
});
|
|
664
454
|
executor.scope.indentLevel -= 1;
|
|
665
455
|
executor.scope.currentComponent = currentComponent;
|
|
666
456
|
executor.scope.currentPin = currentPin;
|
|
667
|
-
executor.
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
if (
|
|
672
|
-
this.visit(
|
|
457
|
+
executor.log('leaving at block');
|
|
458
|
+
};
|
|
459
|
+
visitAt_block_pin_expression_simple = (ctx) => {
|
|
460
|
+
const ctxExpression = ctx.expression();
|
|
461
|
+
if (ctxExpression) {
|
|
462
|
+
this.visit(ctxExpression);
|
|
673
463
|
}
|
|
674
464
|
else if (ctx.NOT_CONNECTED()) {
|
|
675
465
|
return;
|
|
676
466
|
}
|
|
677
|
-
}
|
|
678
|
-
visitAt_block_pin_expression_complex(ctx) {
|
|
679
|
-
ctx.
|
|
467
|
+
};
|
|
468
|
+
visitAt_block_pin_expression_complex = (ctx) => {
|
|
469
|
+
ctx.expression().forEach(item => {
|
|
680
470
|
this.visit(item);
|
|
681
471
|
});
|
|
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
|
-
}
|
|
472
|
+
};
|
|
473
|
+
visitWire_expr_direction_only = (ctx) => {
|
|
474
|
+
const value = ctx.ID().getText();
|
|
475
|
+
if (value === 'auto' || value === 'auto_') {
|
|
476
|
+
this.setResult(ctx, [value]);
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
throw 'Invalid direction for wire';
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
visitWire_expr_direction_value = (ctx) => {
|
|
483
|
+
const direction = ctx.ID().getText();
|
|
484
|
+
if (this.acceptedDirections.indexOf(direction) !== -1) {
|
|
485
|
+
let useValue = null;
|
|
486
|
+
const ctxIntegerValue = ctx.INTEGER_VALUE();
|
|
487
|
+
const ctxDataExpr = ctx.data_expr();
|
|
488
|
+
if (ctxIntegerValue) {
|
|
489
|
+
useValue = Number(ctxIntegerValue);
|
|
490
|
+
}
|
|
491
|
+
else if (ctxDataExpr) {
|
|
492
|
+
this.visit(ctxDataExpr);
|
|
493
|
+
useValue = this.getResult(ctxDataExpr);
|
|
709
494
|
}
|
|
710
|
-
|
|
711
|
-
|
|
495
|
+
if (useValue !== null) {
|
|
496
|
+
this.setResult(ctx, [direction, useValue]);
|
|
497
|
+
return;
|
|
712
498
|
}
|
|
713
499
|
}
|
|
500
|
+
throw "Invalid direction or value for wire";
|
|
501
|
+
};
|
|
502
|
+
visitWire_expr = (ctx) => {
|
|
503
|
+
const wireAtomExpr = ctx.wire_atom_expr();
|
|
504
|
+
const segments = wireAtomExpr.map(wireSegment => {
|
|
505
|
+
this.visit(wireSegment);
|
|
506
|
+
return this.getResult(wireSegment);
|
|
507
|
+
});
|
|
714
508
|
this.getExecutor().addWire(segments);
|
|
715
|
-
}
|
|
716
|
-
visitPoint_expr(ctx) {
|
|
509
|
+
};
|
|
510
|
+
visitPoint_expr = (ctx) => {
|
|
717
511
|
const ID = ctx.ID();
|
|
718
512
|
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());
|
|
513
|
+
};
|
|
514
|
+
visitProperty_set_expr = (ctx) => {
|
|
515
|
+
const ctxDataExpr = ctx.data_expr();
|
|
516
|
+
this.visit(ctxDataExpr);
|
|
517
|
+
const result = this.getResult(ctxDataExpr);
|
|
518
|
+
const ctxAtomExpr = ctx.atom_expr();
|
|
519
|
+
this.visit(ctxAtomExpr);
|
|
520
|
+
const resolvedProperty = this.getResult(ctxAtomExpr);
|
|
733
521
|
this.getExecutor().setProperty(resolvedProperty, result);
|
|
734
|
-
}
|
|
735
|
-
visitDouble_dot_property_set_expr(ctx) {
|
|
736
|
-
const
|
|
522
|
+
};
|
|
523
|
+
visitDouble_dot_property_set_expr = (ctx) => {
|
|
524
|
+
const ctxDataExpr = ctx.data_expr();
|
|
525
|
+
this.visit(ctxDataExpr);
|
|
526
|
+
const result = this.getResult(ctxDataExpr);
|
|
737
527
|
const propertyName = ctx.ID().getText();
|
|
738
528
|
this.getExecutor().setProperty('..' + propertyName, result);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
return this.visit(ctx.data_expr());
|
|
742
|
-
}
|
|
743
|
-
visitFrame_expr(ctx) {
|
|
529
|
+
};
|
|
530
|
+
visitFrame_expr = (ctx) => {
|
|
744
531
|
const frameId = this.getExecutor().enterFrame();
|
|
745
|
-
this.runExpressions(this.getExecutor(), ctx.
|
|
532
|
+
this.runExpressions(this.getExecutor(), ctx.expression());
|
|
746
533
|
this.getExecutor().exitFrame(frameId);
|
|
747
|
-
}
|
|
748
|
-
visitNet_namespace_expr(ctx) {
|
|
534
|
+
};
|
|
535
|
+
visitNet_namespace_expr = (ctx) => {
|
|
749
536
|
let dataValue = null;
|
|
750
537
|
let netNamespace = null;
|
|
751
538
|
const hasPlus = ctx.Addition();
|
|
752
|
-
|
|
753
|
-
|
|
539
|
+
const ctxDataExpr = ctx.data_expr();
|
|
540
|
+
if (ctxDataExpr) {
|
|
541
|
+
this.visit(ctxDataExpr);
|
|
542
|
+
dataValue = this.getResult(ctxDataExpr);
|
|
754
543
|
if (dataValue instanceof UndeclaredReference) {
|
|
755
544
|
netNamespace = "/" + dataValue.reference.name;
|
|
756
545
|
}
|
|
@@ -764,8 +553,8 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
764
553
|
else {
|
|
765
554
|
netNamespace = "/";
|
|
766
555
|
}
|
|
767
|
-
|
|
768
|
-
}
|
|
556
|
+
this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
|
|
557
|
+
};
|
|
769
558
|
pinTypes = [
|
|
770
559
|
PinTypes.Any,
|
|
771
560
|
PinTypes.IO,
|
|
@@ -773,44 +562,6 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
773
562
|
PinTypes.Output,
|
|
774
563
|
PinTypes.Power,
|
|
775
564
|
];
|
|
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
565
|
parseCreateComponentPins(pinData) {
|
|
815
566
|
const pins = [];
|
|
816
567
|
if (typeof pinData === 'number') {
|
|
@@ -862,18 +613,6 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
862
613
|
}
|
|
863
614
|
return result;
|
|
864
615
|
}
|
|
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
616
|
printNets() {
|
|
878
617
|
this.getExecutor().scope.printNets();
|
|
879
618
|
}
|
|
@@ -935,7 +674,10 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
935
674
|
}
|
|
936
675
|
getGraph() {
|
|
937
676
|
const executor = this.getExecutor();
|
|
938
|
-
const
|
|
677
|
+
const fullSequence = executor.scope.sequence;
|
|
678
|
+
const tmpNet = executor.scope.getNet(executor.scope.componentRoot, 1);
|
|
679
|
+
const sequence = (tmpNet === null)
|
|
680
|
+
? fullSequence.slice(1) : fullSequence;
|
|
939
681
|
const nets = executor.scope.getNets();
|
|
940
682
|
return {
|
|
941
683
|
sequence,
|
|
@@ -944,7 +686,7 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
944
686
|
};
|
|
945
687
|
}
|
|
946
688
|
annotateComponents() {
|
|
947
|
-
this.
|
|
689
|
+
this.log('===== annotate components =====');
|
|
948
690
|
const annotater = new ComponentAnnotater();
|
|
949
691
|
const instances = this.getExecutor().scope.instances;
|
|
950
692
|
const toAnnotate = [];
|
|
@@ -956,7 +698,7 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
956
698
|
continue;
|
|
957
699
|
}
|
|
958
700
|
if (instance.typeProp === null) {
|
|
959
|
-
this.
|
|
701
|
+
this.log('Instance has no type:', instance.instanceName, ' assuming connector');
|
|
960
702
|
instance.typeProp = 'conn';
|
|
961
703
|
}
|
|
962
704
|
if (instance.parameters.has('refdes')) {
|
|
@@ -964,7 +706,7 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
964
706
|
if (refdes) {
|
|
965
707
|
instance.assignedRefDes = refdes;
|
|
966
708
|
annotater.trackRefDes(refdes);
|
|
967
|
-
this.
|
|
709
|
+
this.log(refdes, '-', instance.instanceName);
|
|
968
710
|
continue;
|
|
969
711
|
}
|
|
970
712
|
}
|
|
@@ -975,14 +717,14 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
975
717
|
const newRefDes = annotater.getAnnotation(instance.typeProp);
|
|
976
718
|
if (newRefDes !== null) {
|
|
977
719
|
instance.assignedRefDes = newRefDes;
|
|
978
|
-
this.
|
|
720
|
+
this.log(newRefDes, '-', instance.instanceName);
|
|
979
721
|
}
|
|
980
722
|
else {
|
|
981
|
-
this.
|
|
723
|
+
this.log('Failed to annotate:', instance.instanceName);
|
|
982
724
|
}
|
|
983
725
|
});
|
|
984
|
-
this.
|
|
985
|
-
this.
|
|
726
|
+
this.log('===== annotate done =====');
|
|
727
|
+
this.log('');
|
|
986
728
|
}
|
|
987
729
|
resolveNets(scope, instance) {
|
|
988
730
|
const result = [];
|
|
@@ -1011,61 +753,22 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
1011
753
|
throw "Invalid modifier for orientation";
|
|
1012
754
|
}
|
|
1013
755
|
}
|
|
756
|
+
setComponentFlip(component, flipValue) {
|
|
757
|
+
if (this.acceptedFlip.indexOf(flipValue) !== -1) {
|
|
758
|
+
component.setParam(flipValue, 1);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
1014
761
|
getPropertyExprList(items) {
|
|
1015
762
|
const properties = new Map();
|
|
1016
763
|
items.forEach((item) => {
|
|
1017
|
-
|
|
764
|
+
this.visit(item);
|
|
765
|
+
const result = this.getResult(item);
|
|
1018
766
|
for (const [key, value] of result) {
|
|
1019
767
|
properties.set(key, value);
|
|
1020
768
|
}
|
|
1021
769
|
});
|
|
1022
770
|
return properties;
|
|
1023
771
|
}
|
|
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
772
|
}
|
|
1070
773
|
const ComponentRefDesPrefixes = {
|
|
1071
774
|
'res': 'R',
|