circuitscript 0.0.22 → 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 +302 -0
- package/dist/cjs/antlr/CircuitScriptParser.js +5128 -0
- package/dist/cjs/antlr/CircuitScriptVisitor.js +7 -0
- package/dist/cjs/draw_symbols.js +819 -0
- package/dist/cjs/execute.js +778 -0
- package/{src/export.ts → dist/cjs/export.js} +34 -56
- package/dist/cjs/fonts.js +4 -0
- package/dist/cjs/geometry.js +450 -0
- package/dist/cjs/globals.js +60 -0
- package/dist/cjs/helpers.js +269 -0
- package/dist/cjs/index.js +31 -0
- package/{src/layout.ts → dist/cjs/layout.js} +421 -1002
- package/dist/cjs/lexer.js +111 -0
- package/dist/cjs/logger.js +17 -0
- package/dist/cjs/main.js +82 -0
- package/dist/cjs/objects/ClassComponent.js +145 -0
- package/dist/cjs/objects/ExecutionScope.js +135 -0
- package/dist/cjs/objects/Frame.js +22 -0
- package/{src/objects/Net.ts → dist/cjs/objects/Net.js} +9 -24
- package/dist/cjs/objects/ParamDefinition.js +42 -0
- package/dist/cjs/objects/PinDefinition.js +31 -0
- package/dist/cjs/objects/PinTypes.js +11 -0
- package/dist/cjs/objects/Wire.js +9 -0
- package/dist/cjs/objects/types.js +15 -0
- package/dist/cjs/parser.js +70 -0
- package/dist/cjs/regenerate-tests.js +23 -0
- package/dist/cjs/render.js +155 -0
- package/{src/server.ts → dist/cjs/server.js} +15 -21
- package/dist/cjs/sizing.js +105 -0
- package/{src/utils.ts → dist/cjs/utils.js} +25 -35
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +844 -0
- 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 +276 -0
- package/dist/esm/antlr/CircuitScriptParser.mjs +5038 -0
- package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +8 -3
- package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +78 -33
- package/{build/src/execute.js → dist/esm/execute.mjs} +59 -60
- package/{build/src/export.js → dist/esm/export.mjs} +2 -2
- package/{build/src/geometry.js → dist/esm/geometry.mjs} +31 -15
- package/dist/esm/helpers.mjs +252 -0
- package/dist/esm/index.mjs +15 -0
- package/{build/src/layout.js → dist/esm/layout.mjs} +19 -11
- package/{build/src/lexer.js → dist/esm/lexer.mjs} +10 -10
- package/{build/src/main.js → dist/esm/main.mjs} +9 -14
- package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +6 -3
- package/{build/src/objects/ExecutionScope.js → dist/esm/objects/ExecutionScope.mjs} +1 -0
- package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
- package/dist/esm/objects/types.mjs +12 -0
- package/dist/esm/parser.mjs +64 -0
- package/{build/src/regenerate-tests.js → dist/esm/regenerate-tests.mjs} +1 -1
- package/{build/src/render.js → dist/esm/render.mjs} +7 -24
- package/{build/src/sizing.js → dist/esm/sizing.mjs} +22 -8
- package/{src/main.ts → dist/esm/validate.mjs} +31 -62
- package/dist/esm/visitor.mjs +838 -0
- 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/{build/src → dist/types}/antlr/CircuitScriptLexer.d.ts +28 -27
- package/dist/types/antlr/CircuitScriptParser.d.ts +719 -0
- package/{build/src → dist/types}/antlr/CircuitScriptVisitor.d.ts +69 -59
- package/{build/src → dist/types}/draw_symbols.d.ts +11 -2
- package/{build/src → dist/types}/execute.d.ts +6 -9
- package/{build/src → dist/types}/geometry.d.ts +5 -1
- package/dist/types/helpers.d.ts +40 -0
- package/dist/types/index.d.ts +15 -0
- package/{build/src → dist/types}/layout.d.ts +10 -10
- package/{build/src → dist/types}/lexer.d.ts +2 -2
- package/{build/src → dist/types}/objects/ClassComponent.d.ts +2 -2
- package/{build/src → dist/types}/objects/ExecutionScope.d.ts +4 -1
- package/{build/src → dist/types}/objects/PinDefinition.d.ts +1 -1
- package/{build/src → dist/types}/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +25 -0
- package/{build/src → dist/types}/render.d.ts +1 -1
- package/{build/src → dist/types}/sizing.d.ts +3 -1
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +80 -0
- package/libs/lib.cst +0 -2
- package/package.json +38 -15
- package/.editorconfig +0 -15
- package/.eslintignore +0 -1
- package/.eslintrc.json +0 -27
- package/.gitlab-ci.yml +0 -81
- package/.prettierignore +0 -8
- package/.prettierrc +0 -16
- package/__tests__/expectedResults.ts +0 -657
- package/__tests__/helpers.ts +0 -82
- package/__tests__/parseScripts.ts +0 -593
- package/__tests__/renderData/script1.cst +0 -58
- package/__tests__/renderData/script1.cst.svg +0 -1
- package/__tests__/renderData/script2.cst +0 -16
- package/__tests__/renderData/script2.cst.svg +0 -1
- package/__tests__/renderData/script3.cst +0 -30
- package/__tests__/renderData/script3.cst.svg +0 -1
- package/__tests__/renderData/script4.cst +0 -54
- package/__tests__/renderData/script4.cst.svg +0 -1
- package/__tests__/renderData/script5.cst +0 -23
- package/__tests__/renderData/script5.cst.svg +0 -1
- package/__tests__/renderData/script6.cst +0 -28
- package/__tests__/renderData/script6.cst.svg +0 -1
- package/__tests__/renderData/script7.cst +0 -26
- package/__tests__/renderData/script7.cst.svg +0 -1
- package/__tests__/renderData/script8.cst +0 -37
- package/__tests__/renderData/script8.cst.svg +0 -1
- package/__tests__/testCLI.ts +0 -68
- package/__tests__/testMathOps.ts +0 -36
- package/__tests__/testMergeWires.ts +0 -141
- package/__tests__/testParse.ts +0 -263
- package/__tests__/testRender.ts +0 -38
- package/build/src/antlr/CircuitScriptLexer.js +0 -287
- package/build/src/antlr/CircuitScriptParser.d.ts +0 -674
- package/build/src/antlr/CircuitScriptParser.js +0 -4841
- package/build/src/helpers.d.ts +0 -1
- package/build/src/helpers.js +0 -73
- package/build/src/objects/types.js +0 -6
- package/build/src/parser.js +0 -69
- package/build/src/visitor.d.ts +0 -133
- package/build/src/visitor.js +0 -1154
- package/documentation.md +0 -238
- package/examples/example_arduino_uno.cst +0 -1146
- package/examples/example_garden_pump.cst +0 -567
- package/examples/lib.cst +0 -185
- package/jest.config.js +0 -23
- package/refresh.html +0 -42
- package/server.cjs +0 -50
- package/src/antlr/CircuitScript.g4 +0 -209
- package/src/antlr/CircuitScriptLexer.ts +0 -317
- package/src/antlr/CircuitScriptParser.ts +0 -4979
- package/src/antlr/CircuitScriptVisitor.ts +0 -420
- package/src/draw_symbols.ts +0 -1085
- package/src/execute.ts +0 -1227
- package/src/fonts.ts +0 -1
- package/src/geometry.ts +0 -638
- package/src/globals.ts +0 -67
- package/src/helpers.ts +0 -114
- package/src/lexer.ts +0 -151
- package/src/logger.ts +0 -17
- package/src/objects/ClassComponent.ts +0 -223
- package/src/objects/ExecutionScope.ts +0 -201
- package/src/objects/Frame.ts +0 -20
- package/src/objects/ParamDefinition.ts +0 -49
- package/src/objects/PinDefinition.ts +0 -49
- package/src/objects/PinTypes.ts +0 -7
- package/src/objects/Wire.ts +0 -19
- package/src/objects/types.ts +0 -66
- package/src/parser.ts +0 -106
- package/src/regenerate-tests.ts +0 -25
- package/src/render.ts +0 -260
- package/src/sizing.ts +0 -96
- package/src/visitor.ts +0 -1691
- package/tsconfig.json +0 -27
- package/tsconfig.release.json +0 -8
- /package/{build/src/fonts.js → dist/esm/fonts.mjs} +0 -0
- /package/{build/src/globals.js → dist/esm/globals.mjs} +0 -0
- /package/{build/src/logger.js → dist/esm/logger.mjs} +0 -0
- /package/{build/src/objects/Frame.js → dist/esm/objects/Frame.mjs} +0 -0
- /package/{build/src/objects/Net.js → dist/esm/objects/Net.mjs} +0 -0
- /package/{build/src/objects/ParamDefinition.js → dist/esm/objects/ParamDefinition.mjs} +0 -0
- /package/{build/src/objects/PinTypes.js → dist/esm/objects/PinTypes.mjs} +0 -0
- /package/{build/src/objects/Wire.js → dist/esm/objects/Wire.mjs} +0 -0
- /package/{build/src/server.js → dist/esm/server.mjs} +0 -0
- /package/{build/src/utils.js → dist/esm/utils.mjs} +0 -0
- /package/{build/src → dist/types}/export.d.ts +0 -0
- /package/{build/src → dist/types}/fonts.d.ts +0 -0
- /package/{build/src → dist/types}/globals.d.ts +0 -0
- /package/{build/src → dist/types}/logger.d.ts +0 -0
- /package/{build/src → dist/types}/main.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Frame.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Net.d.ts +0 -0
- /package/{build/src → dist/types}/objects/ParamDefinition.d.ts +0 -0
- /package/{build/src → dist/types}/objects/PinTypes.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Wire.d.ts +0 -0
- /package/{build/src → dist/types}/regenerate-tests.d.ts +0 -0
- /package/{build/src → dist/types}/server.d.ts +0 -0
- /package/{build/src → dist/types}/utils.d.ts +0 -0
package/build/src/visitor.js
DELETED
|
@@ -1,1154 +0,0 @@
|
|
|
1
|
-
import { ParseTreeVisitor } from 'antlr4';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import { ExecutionContext } from './execute.js';
|
|
5
|
-
import { ClassComponent } from './objects/ClassComponent.js';
|
|
6
|
-
import { NumericValue, ParamDefinition, PercentageValue, PinBlankValue, } from './objects/ParamDefinition.js';
|
|
7
|
-
import { PinDefinition, PinIdType } from './objects/PinDefinition.js';
|
|
8
|
-
import { PinTypes } from './objects/PinTypes.js';
|
|
9
|
-
import { UndeclaredReference } from './objects/types.js';
|
|
10
|
-
import { Logger } from './logger.js';
|
|
11
|
-
import { BlockTypes, ComponentTypes, NoNetText } from './globals.js';
|
|
12
|
-
import { SymbolDrawingCommands } from './draw_symbols.js';
|
|
13
|
-
import { parseFileWithVisitor } from './parser.js';
|
|
14
|
-
export class MainVisitor extends ParseTreeVisitor {
|
|
15
|
-
indentLevel = 0;
|
|
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) {
|
|
95
|
-
const id = ctx.ID().getText();
|
|
96
|
-
const value = this.visit(ctx.data_expr());
|
|
97
|
-
return [id, value];
|
|
98
|
-
}
|
|
99
|
-
visitAssignment_expr(ctx) {
|
|
100
|
-
const atomStr = ctx.atom_expr().getText();
|
|
101
|
-
if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
|
|
102
|
-
throw "Invalid assignment expression!";
|
|
103
|
-
}
|
|
104
|
-
const reference = this.visit(ctx.atom_expr());
|
|
105
|
-
const value = this.visit(ctx.data_expr());
|
|
106
|
-
if (value instanceof ClassComponent) {
|
|
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());
|
|
178
|
-
}
|
|
179
|
-
return null;
|
|
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());
|
|
185
|
-
}
|
|
186
|
-
return this.getExecutor().addComponentExisting(component, pinValue);
|
|
187
|
-
}
|
|
188
|
-
visitAt_component_expr(ctx) {
|
|
189
|
-
if (ctx.Point()) {
|
|
190
|
-
this.getExecutor().atPointBlock();
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
const [component, pin] = this.visit(ctx.component_select_expr());
|
|
194
|
-
const currentPoint = this.getExecutor().atComponent(component, pin, {
|
|
195
|
-
addSequence: true,
|
|
196
|
-
cloneNetComponent: true
|
|
197
|
-
});
|
|
198
|
-
if (ctx.ID()) {
|
|
199
|
-
this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return this.getExecutor().getCurrentPoint();
|
|
203
|
-
}
|
|
204
|
-
visitTo_component_expr(ctx) {
|
|
205
|
-
let currentPoint;
|
|
206
|
-
if (ctx.Point()) {
|
|
207
|
-
this.getExecutor().toPointBlock();
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
ctx.component_select_expr_list().forEach((item) => {
|
|
211
|
-
const [component, pin] = this.visit(item);
|
|
212
|
-
currentPoint = this.getExecutor().toComponent(component, pin, {
|
|
213
|
-
addSequence: true, cloneNetComponent: true
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
if (ctx.ID()) {
|
|
217
|
-
this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return this.getExecutor().getCurrentPoint();
|
|
221
|
-
}
|
|
222
|
-
visitComponent_select_expr(ctx) {
|
|
223
|
-
if (ctx.data_expr_with_assignment()) {
|
|
224
|
-
return this.visit(ctx.data_expr_with_assignment());
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
const component = this.getExecutor().scope.currentComponent;
|
|
228
|
-
let pinId = null;
|
|
229
|
-
if (ctx.pin_select_expr()) {
|
|
230
|
-
pinId = this.visit(ctx.pin_select_expr());
|
|
231
|
-
}
|
|
232
|
-
return [component, pinId];
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
visitPath_blocks(ctx) {
|
|
236
|
-
const blocks = ctx.path_block_inner_list();
|
|
237
|
-
let blockIndex = 0;
|
|
238
|
-
let blockType = BlockTypes.Branch;
|
|
239
|
-
let prevBlockType = null;
|
|
240
|
-
blocks.forEach((block, index) => {
|
|
241
|
-
if (block.Branch()) {
|
|
242
|
-
blockType = BlockTypes.Branch;
|
|
243
|
-
}
|
|
244
|
-
else if (block.Join()) {
|
|
245
|
-
blockType = BlockTypes.Join;
|
|
246
|
-
}
|
|
247
|
-
else if (block.Parallel()) {
|
|
248
|
-
blockType = BlockTypes.Parallel;
|
|
249
|
-
}
|
|
250
|
-
else if (block.Point()) {
|
|
251
|
-
blockType = BlockTypes.Point;
|
|
252
|
-
}
|
|
253
|
-
if (prevBlockType !== blockType) {
|
|
254
|
-
if (index > 0) {
|
|
255
|
-
this.getExecutor().exitBlocks();
|
|
256
|
-
}
|
|
257
|
-
this.getExecutor().enterBlocks(blockType);
|
|
258
|
-
blockIndex = 0;
|
|
259
|
-
}
|
|
260
|
-
this.getExecutor().enterBlock(blockIndex);
|
|
261
|
-
this.visit(block);
|
|
262
|
-
this.getExecutor().exitBlock(blockIndex);
|
|
263
|
-
blockIndex += 1;
|
|
264
|
-
prevBlockType = blockType;
|
|
265
|
-
});
|
|
266
|
-
this.getExecutor().exitBlocks();
|
|
267
|
-
return this.getExecutor().getCurrentPoint();
|
|
268
|
-
}
|
|
269
|
-
visitBreak_keyword() {
|
|
270
|
-
this.getExecutor().breakBranch();
|
|
271
|
-
return -1;
|
|
272
|
-
}
|
|
273
|
-
visitCreate_component_expr(ctx) {
|
|
274
|
-
const properties = this.getPropertyExprList(ctx.property_expr_list());
|
|
275
|
-
const pins = this.parseCreateComponentPins(properties.get('pins'));
|
|
276
|
-
let instanceName = this.getExecutor().getUniqueInstanceName('');
|
|
277
|
-
const propParams = properties.get('params');
|
|
278
|
-
const params = this.parseCreateComponentParams(propParams);
|
|
279
|
-
if (params.length > 0) {
|
|
280
|
-
const firstParam = params[0];
|
|
281
|
-
const paramValue = firstParam.paramValue;
|
|
282
|
-
let appendValue = paramValue.toString();
|
|
283
|
-
if (paramValue instanceof NumericValue) {
|
|
284
|
-
appendValue = paramValue.value;
|
|
285
|
-
}
|
|
286
|
-
instanceName += '_' + appendValue;
|
|
287
|
-
}
|
|
288
|
-
const arrange = properties.has('arrange') ?
|
|
289
|
-
properties.get('arrange') : null;
|
|
290
|
-
const display = properties.has('display') ?
|
|
291
|
-
properties.get('display') : null;
|
|
292
|
-
const type = properties.has('type') ?
|
|
293
|
-
properties.get('type') : null;
|
|
294
|
-
const width = properties.has('width') ?
|
|
295
|
-
properties.get('width') : null;
|
|
296
|
-
const props = {
|
|
297
|
-
arrange,
|
|
298
|
-
display,
|
|
299
|
-
type,
|
|
300
|
-
width,
|
|
301
|
-
};
|
|
302
|
-
return this.getExecutor().createComponent(instanceName, pins, params, props);
|
|
303
|
-
}
|
|
304
|
-
visitCreate_graphic_expr(ctx) {
|
|
305
|
-
const commands = ctx.sub_expr_list().reduce((accum, item) => {
|
|
306
|
-
const [commandName, parameters] = this.visit(item);
|
|
307
|
-
const keywordParams = new Map();
|
|
308
|
-
const positionParams = parameters.reduce((accum, [argType, name, value]) => {
|
|
309
|
-
if (argType === 'position') {
|
|
310
|
-
accum.push(value);
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
keywordParams.set(name, value);
|
|
314
|
-
}
|
|
315
|
-
return accum;
|
|
316
|
-
}, []);
|
|
317
|
-
accum.push([commandName, positionParams, keywordParams]);
|
|
318
|
-
return accum;
|
|
319
|
-
}, []);
|
|
320
|
-
return new SymbolDrawingCommands(commands);
|
|
321
|
-
}
|
|
322
|
-
visitSub_expr(ctx) {
|
|
323
|
-
let commandName = null;
|
|
324
|
-
if (ctx.ID()) {
|
|
325
|
-
commandName = ctx.ID().getText();
|
|
326
|
-
}
|
|
327
|
-
else if (ctx.Pin()) {
|
|
328
|
-
commandName = ctx.Pin().getText();
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
throw "Invalid command!";
|
|
332
|
-
}
|
|
333
|
-
const parameters = this.visit(ctx.parameters());
|
|
334
|
-
return [commandName, parameters];
|
|
335
|
-
}
|
|
336
|
-
visitProperty_expr(ctx) {
|
|
337
|
-
const keyName = this.visit(ctx.property_key_expr());
|
|
338
|
-
const value = this.visit(ctx.property_value_expr());
|
|
339
|
-
const map = new Map();
|
|
340
|
-
map.set(keyName, value);
|
|
341
|
-
return map;
|
|
342
|
-
}
|
|
343
|
-
visitSingle_line_property(ctx) {
|
|
344
|
-
let value;
|
|
345
|
-
if (ctx.data_expr_list().length === 1) {
|
|
346
|
-
value = this.visit(ctx.data_expr(0));
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
value = ctx.data_expr_list().map(item => {
|
|
350
|
-
return this.visit(item);
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
return value;
|
|
354
|
-
}
|
|
355
|
-
visitNested_properties(ctx) {
|
|
356
|
-
const result = new Map();
|
|
357
|
-
ctx.property_expr_list().forEach((item) => {
|
|
358
|
-
const property = this.visit(item);
|
|
359
|
-
for (const [key, value] of property) {
|
|
360
|
-
result.set(key, value);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
return result;
|
|
364
|
-
}
|
|
365
|
-
visitProperty_key_expr(ctx) {
|
|
366
|
-
if (ctx.ID()) {
|
|
367
|
-
return ctx.ID().getText();
|
|
368
|
-
}
|
|
369
|
-
else if (ctx.INTEGER_VALUE()) {
|
|
370
|
-
return Number(ctx.INTEGER_VALUE().getText());
|
|
371
|
-
}
|
|
372
|
-
else if (ctx.STRING_VALUE()) {
|
|
373
|
-
return this.prepareStringValue(ctx.STRING_VALUE().getText());
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
visitData_expr_with_assignment(ctx) {
|
|
377
|
-
let component;
|
|
378
|
-
if (ctx.data_expr()) {
|
|
379
|
-
component = this.visit(ctx.data_expr());
|
|
380
|
-
if (component === null || component === undefined) {
|
|
381
|
-
throw "Could not find component: " + ctx.data_expr().getText();
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
else if (ctx.assignment_expr()) {
|
|
385
|
-
component = this.visit(ctx.assignment_expr());
|
|
386
|
-
}
|
|
387
|
-
let pinValue = null;
|
|
388
|
-
if (ctx.pin_select_expr()) {
|
|
389
|
-
pinValue = this.visit(ctx.pin_select_expr());
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
392
|
-
pinValue = component.getDefaultPin();
|
|
393
|
-
}
|
|
394
|
-
return [component, pinValue];
|
|
395
|
-
}
|
|
396
|
-
visitValueAtomExpr(ctx) {
|
|
397
|
-
let value;
|
|
398
|
-
if (ctx.value_expr()) {
|
|
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());
|
|
414
|
-
const unaryOp = ctx.unary_operator();
|
|
415
|
-
if (unaryOp) {
|
|
416
|
-
if (unaryOp.Not()) {
|
|
417
|
-
if (typeof value === "boolean") {
|
|
418
|
-
value = !value;
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
throw "Failed to do Not operator";
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
else if (unaryOp.Minus()) {
|
|
425
|
-
if (typeof value === 'number') {
|
|
426
|
-
return -value;
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
throw "Failed to do Negation operator";
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return value;
|
|
434
|
-
}
|
|
435
|
-
visitDataExpr(ctx) {
|
|
436
|
-
let value;
|
|
437
|
-
if (ctx.create_component_expr()) {
|
|
438
|
-
value = this.visit(ctx.create_component_expr());
|
|
439
|
-
}
|
|
440
|
-
else if (ctx.create_graphic_expr()) {
|
|
441
|
-
value = this.visit(ctx.create_graphic_expr());
|
|
442
|
-
}
|
|
443
|
-
return value;
|
|
444
|
-
}
|
|
445
|
-
visitBinaryOperatorExpr(ctx) {
|
|
446
|
-
const value1 = this.visit(ctx.data_expr(0));
|
|
447
|
-
const value2 = this.visit(ctx.data_expr(1));
|
|
448
|
-
const binaryOperatorType = ctx.binary_operator();
|
|
449
|
-
if (binaryOperatorType.Equals()) {
|
|
450
|
-
return value1 == value2;
|
|
451
|
-
}
|
|
452
|
-
else if (binaryOperatorType.NotEquals()) {
|
|
453
|
-
return value1 != value2;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
visitMultiplyExpr(ctx) {
|
|
457
|
-
const value1 = this.visit(ctx.data_expr(0));
|
|
458
|
-
const value2 = this.visit(ctx.data_expr(1));
|
|
459
|
-
if (ctx.Multiply()) {
|
|
460
|
-
return value1 * value2;
|
|
461
|
-
}
|
|
462
|
-
else if (ctx.Divide()) {
|
|
463
|
-
return value1 / value2;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
visitAdditionExpr(ctx) {
|
|
467
|
-
const value1 = this.visit(ctx.data_expr(0));
|
|
468
|
-
const value2 = this.visit(ctx.data_expr(1));
|
|
469
|
-
if (ctx.Addition()) {
|
|
470
|
-
return value1 + value2;
|
|
471
|
-
}
|
|
472
|
-
else if (ctx.Minus()) {
|
|
473
|
-
return value1 - value2;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
visitFunction_args_expr(ctx) {
|
|
477
|
-
const defaultValuesProvided = ctx.value_expr_list();
|
|
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) {
|
|
511
|
-
const functionName = ctx.ID().getText();
|
|
512
|
-
let funcDefinedParameters = [];
|
|
513
|
-
if (ctx.function_args_expr()) {
|
|
514
|
-
funcDefinedParameters = this.visit(ctx.function_args_expr());
|
|
515
|
-
}
|
|
516
|
-
const executionStack = this.executionStack;
|
|
517
|
-
const functionCounter = { counter: 0 };
|
|
518
|
-
const resolveNet = this.createNetResolver(this.executionStack);
|
|
519
|
-
const __runFunc = (passedInParameters, options) => {
|
|
520
|
-
const { netNamespace = "" } = options;
|
|
521
|
-
const currentExecutionContext = executionStack[executionStack.length - 1];
|
|
522
|
-
const executionLevel = currentExecutionContext.executionLevel;
|
|
523
|
-
const executionContextName = functionName + '_' + functionCounter['counter'];
|
|
524
|
-
const executionContextNamespace = currentExecutionContext.namespace
|
|
525
|
-
+ executionContextName + ".";
|
|
526
|
-
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
|
-
newExecutor.resolveNet = resolveNet;
|
|
530
|
-
executionStack.push(newExecutor);
|
|
531
|
-
this.setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, newExecutor);
|
|
532
|
-
const returnValue = this.runExpressions(newExecutor, ctx.function_expr_list());
|
|
533
|
-
const lastExecution = executionStack.pop();
|
|
534
|
-
const nextLastExecution = executionStack[executionStack.length - 1];
|
|
535
|
-
nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
|
|
536
|
-
return [lastExecution, returnValue];
|
|
537
|
-
};
|
|
538
|
-
this.getExecutor().createFunction(functionName, __runFunc);
|
|
539
|
-
}
|
|
540
|
-
setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, executor) {
|
|
541
|
-
for (let i = 0; i < funcDefinedParameters.length; i++) {
|
|
542
|
-
const tmpFuncArg = funcDefinedParameters[i];
|
|
543
|
-
if (i < passedInParameters.length) {
|
|
544
|
-
const tmpPassedInArgs = passedInParameters[i];
|
|
545
|
-
if (tmpPassedInArgs[0] === 'position') {
|
|
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());
|
|
631
|
-
}
|
|
632
|
-
else if (ctx.INTEGER_VALUE()) {
|
|
633
|
-
return Number(ctx.INTEGER_VALUE().getText());
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
visitAt_block_pin_expr(ctx) {
|
|
637
|
-
const atPin = this.visit(ctx.pin_select_expr2());
|
|
638
|
-
const executor = this.getExecutor();
|
|
639
|
-
const currentComponent = executor.scope.currentComponent;
|
|
640
|
-
const currentPin = executor.scope.currentPin;
|
|
641
|
-
executor.atComponent(currentComponent, atPin, {
|
|
642
|
-
addSequence: true
|
|
643
|
-
});
|
|
644
|
-
executor.print('at block pin expressions');
|
|
645
|
-
if (ctx.at_block_pin_expression_simple()) {
|
|
646
|
-
this.visit(ctx.at_block_pin_expression_simple());
|
|
647
|
-
}
|
|
648
|
-
else if (ctx.at_block_pin_expression_complex()) {
|
|
649
|
-
this.visit(ctx.at_block_pin_expression_complex());
|
|
650
|
-
}
|
|
651
|
-
executor.print('end at block pin expressions');
|
|
652
|
-
return executor.atComponent(currentComponent, currentPin);
|
|
653
|
-
}
|
|
654
|
-
visitAt_block(ctx) {
|
|
655
|
-
const executor = this.getExecutor();
|
|
656
|
-
executor.print('entering at block');
|
|
657
|
-
this.visit(ctx.at_component_expr());
|
|
658
|
-
const currentComponent = executor.scope.currentComponent;
|
|
659
|
-
const currentPin = executor.scope.currentPin;
|
|
660
|
-
executor.scope.indentLevel += 1;
|
|
661
|
-
ctx.at_block_expressions_list().forEach(expression => {
|
|
662
|
-
this.visit(expression);
|
|
663
|
-
});
|
|
664
|
-
executor.scope.indentLevel -= 1;
|
|
665
|
-
executor.scope.currentComponent = currentComponent;
|
|
666
|
-
executor.scope.currentPin = currentPin;
|
|
667
|
-
executor.print('leaving at block');
|
|
668
|
-
return executor.getCurrentPoint();
|
|
669
|
-
}
|
|
670
|
-
visitAt_block_pin_expression_simple(ctx) {
|
|
671
|
-
if (ctx.expression()) {
|
|
672
|
-
this.visit(ctx.expression());
|
|
673
|
-
}
|
|
674
|
-
else if (ctx.NOT_CONNECTED()) {
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
visitAt_block_pin_expression_complex(ctx) {
|
|
679
|
-
ctx.expression_list().forEach(item => {
|
|
680
|
-
this.visit(item);
|
|
681
|
-
});
|
|
682
|
-
return this.getExecutor().getCurrentPoint();
|
|
683
|
-
}
|
|
684
|
-
visitWire_expr(ctx) {
|
|
685
|
-
const segments = [];
|
|
686
|
-
const parts = ctx.children.slice(1);
|
|
687
|
-
for (let i = 0; i < parts.length; i++) {
|
|
688
|
-
const textValue = parts[i].getText();
|
|
689
|
-
if (this.acceptedDirections.indexOf(textValue) !== -1) {
|
|
690
|
-
const segment = [textValue];
|
|
691
|
-
let skipNext = false;
|
|
692
|
-
let invalidValue = true;
|
|
693
|
-
if (i + 1 < parts.length) {
|
|
694
|
-
const nextValue = parts[i + 1].getText();
|
|
695
|
-
const nextValueNumber = Number(nextValue);
|
|
696
|
-
if (!isNaN(nextValueNumber)) {
|
|
697
|
-
invalidValue = false;
|
|
698
|
-
segment.push(nextValueNumber);
|
|
699
|
-
skipNext = true;
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
if (invalidValue) {
|
|
703
|
-
throw `Invalid value provided for direction ${textValue} in wire`;
|
|
704
|
-
}
|
|
705
|
-
segments.push(segment);
|
|
706
|
-
if (skipNext) {
|
|
707
|
-
i += 1;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
else if (textValue === "auto" || textValue === "auto_") {
|
|
711
|
-
segments.push([textValue]);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
this.getExecutor().addWire(segments);
|
|
715
|
-
}
|
|
716
|
-
visitPoint_expr(ctx) {
|
|
717
|
-
const ID = ctx.ID();
|
|
718
|
-
return this.getExecutor().addPoint(ID.getText());
|
|
719
|
-
}
|
|
720
|
-
visitImport_expr(ctx) {
|
|
721
|
-
const ID = ctx.ID().toString();
|
|
722
|
-
this.print('import', ID);
|
|
723
|
-
const { hasError, hasParseError } = this.onImportFile(this, ID);
|
|
724
|
-
if (hasError || hasParseError) {
|
|
725
|
-
this.print('import', ID, 'failed');
|
|
726
|
-
throw `import ${ID} failed`;
|
|
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());
|
|
733
|
-
this.getExecutor().setProperty(resolvedProperty, result);
|
|
734
|
-
}
|
|
735
|
-
visitDouble_dot_property_set_expr(ctx) {
|
|
736
|
-
const result = this.visit(ctx.data_expr());
|
|
737
|
-
const propertyName = ctx.ID().getText();
|
|
738
|
-
this.getExecutor().setProperty('..' + propertyName, result);
|
|
739
|
-
}
|
|
740
|
-
visitRoundedBracketsExpr(ctx) {
|
|
741
|
-
return this.visit(ctx.data_expr());
|
|
742
|
-
}
|
|
743
|
-
visitFrame_expr(ctx) {
|
|
744
|
-
const frameId = this.getExecutor().enterFrame();
|
|
745
|
-
this.runExpressions(this.getExecutor(), ctx.expression_list());
|
|
746
|
-
this.getExecutor().exitFrame(frameId);
|
|
747
|
-
}
|
|
748
|
-
visitNet_namespace_expr(ctx) {
|
|
749
|
-
let dataValue = null;
|
|
750
|
-
let netNamespace = null;
|
|
751
|
-
const hasPlus = ctx.Addition();
|
|
752
|
-
if (ctx.data_expr()) {
|
|
753
|
-
dataValue = this.visit(ctx.data_expr());
|
|
754
|
-
if (dataValue instanceof UndeclaredReference) {
|
|
755
|
-
netNamespace = "/" + dataValue.reference.name;
|
|
756
|
-
}
|
|
757
|
-
else if (typeof dataValue === "string") {
|
|
758
|
-
netNamespace = "/" + dataValue;
|
|
759
|
-
}
|
|
760
|
-
else {
|
|
761
|
-
throw "Failed to resolve net namespace value";
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
else {
|
|
765
|
-
netNamespace = "/";
|
|
766
|
-
}
|
|
767
|
-
return (hasPlus ? "+" : "") + netNamespace;
|
|
768
|
-
}
|
|
769
|
-
pinTypes = [
|
|
770
|
-
PinTypes.Any,
|
|
771
|
-
PinTypes.IO,
|
|
772
|
-
PinTypes.Input,
|
|
773
|
-
PinTypes.Output,
|
|
774
|
-
PinTypes.Power,
|
|
775
|
-
];
|
|
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
|
-
parseCreateComponentPins(pinData) {
|
|
815
|
-
const pins = [];
|
|
816
|
-
if (typeof pinData === 'number') {
|
|
817
|
-
const lastPin = pinData;
|
|
818
|
-
for (let i = 0; i < lastPin; i++) {
|
|
819
|
-
const pinId = i + 1;
|
|
820
|
-
pins.push(new PinDefinition(pinId, PinIdType.Int, pinId.toString()));
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
else if (pinData instanceof Map) {
|
|
824
|
-
for (const [pinId, pinDef] of pinData) {
|
|
825
|
-
let pinIdType = PinIdType.Int;
|
|
826
|
-
let pinType = PinTypes.Any;
|
|
827
|
-
let pinName = null;
|
|
828
|
-
let altPinNames = [];
|
|
829
|
-
if (typeof pinId === 'string') {
|
|
830
|
-
pinIdType = PinIdType.Str;
|
|
831
|
-
}
|
|
832
|
-
if (Array.isArray(pinDef)) {
|
|
833
|
-
const firstValue = pinDef[0];
|
|
834
|
-
if (this.pinTypes.indexOf(firstValue) !== -1) {
|
|
835
|
-
pinType = firstValue;
|
|
836
|
-
pinName = pinDef[1];
|
|
837
|
-
if (pinDef.length > 2) {
|
|
838
|
-
altPinNames = pinDef.slice(2);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
else {
|
|
842
|
-
pinName = pinDef[0];
|
|
843
|
-
if (pinDef.length > 1) {
|
|
844
|
-
altPinNames = pinDef.slice(1);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
else {
|
|
849
|
-
pinName = pinDef;
|
|
850
|
-
}
|
|
851
|
-
pins.push(new PinDefinition(pinId, pinIdType, pinName, pinType, altPinNames));
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
return pins;
|
|
855
|
-
}
|
|
856
|
-
parseCreateComponentParams(params) {
|
|
857
|
-
const result = [];
|
|
858
|
-
if (params) {
|
|
859
|
-
for (const [key, value] of params) {
|
|
860
|
-
result.push(new ParamDefinition(key, value));
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
return result;
|
|
864
|
-
}
|
|
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
|
-
printNets() {
|
|
878
|
-
this.getExecutor().scope.printNets();
|
|
879
|
-
}
|
|
880
|
-
dumpNets() {
|
|
881
|
-
return this.getExecutor().scope.dumpNets();
|
|
882
|
-
}
|
|
883
|
-
dumpUniqueNets() {
|
|
884
|
-
const nets = this.getExecutor().scope.getNets();
|
|
885
|
-
return nets.reduce((accum, [, , net]) => {
|
|
886
|
-
accum.push(net);
|
|
887
|
-
return accum;
|
|
888
|
-
}, []);
|
|
889
|
-
}
|
|
890
|
-
dumpVariables() {
|
|
891
|
-
return this.getExecutor().scope.variables;
|
|
892
|
-
}
|
|
893
|
-
dumpInstances() {
|
|
894
|
-
return this.getExecutor().scope.instances;
|
|
895
|
-
}
|
|
896
|
-
dump2() {
|
|
897
|
-
const instances = this.getExecutor().scope.instances;
|
|
898
|
-
const items = [];
|
|
899
|
-
for (const [instanceName, instance] of instances) {
|
|
900
|
-
if (instance.assignedRefDes === null) {
|
|
901
|
-
continue;
|
|
902
|
-
}
|
|
903
|
-
const pinNets = this.resolveNets(this.getExecutor().scope, instance);
|
|
904
|
-
const componentItem = {
|
|
905
|
-
name: instanceName,
|
|
906
|
-
refdes: instance.assignedRefDes,
|
|
907
|
-
pins: {},
|
|
908
|
-
};
|
|
909
|
-
pinNets.forEach((item) => {
|
|
910
|
-
componentItem.pins[item.pin.id] = item.netName;
|
|
911
|
-
});
|
|
912
|
-
items.push(componentItem);
|
|
913
|
-
}
|
|
914
|
-
return items;
|
|
915
|
-
}
|
|
916
|
-
getNetList() {
|
|
917
|
-
const netlist = [];
|
|
918
|
-
const instances = this.getExecutor().scope.instances;
|
|
919
|
-
for (const [instanceName, instance] of instances) {
|
|
920
|
-
const pinNets = this.resolveNets(this.getExecutor().scope, instance);
|
|
921
|
-
const componentItem = {
|
|
922
|
-
instanceName,
|
|
923
|
-
instance,
|
|
924
|
-
pins: {},
|
|
925
|
-
};
|
|
926
|
-
pinNets.forEach((item) => {
|
|
927
|
-
componentItem.pins[item.pin.id] = {
|
|
928
|
-
netName: item.netName,
|
|
929
|
-
netBaseName: item.netBaseName
|
|
930
|
-
};
|
|
931
|
-
});
|
|
932
|
-
netlist.push(componentItem);
|
|
933
|
-
}
|
|
934
|
-
return netlist;
|
|
935
|
-
}
|
|
936
|
-
getGraph() {
|
|
937
|
-
const executor = this.getExecutor();
|
|
938
|
-
const sequence = executor.scope.sequence;
|
|
939
|
-
const nets = executor.scope.getNets();
|
|
940
|
-
return {
|
|
941
|
-
sequence,
|
|
942
|
-
nets,
|
|
943
|
-
components: Array.from(executor.scope.instances.values())
|
|
944
|
-
};
|
|
945
|
-
}
|
|
946
|
-
annotateComponents() {
|
|
947
|
-
this.print('===== annotate components =====');
|
|
948
|
-
const annotater = new ComponentAnnotater();
|
|
949
|
-
const instances = this.getExecutor().scope.instances;
|
|
950
|
-
const toAnnotate = [];
|
|
951
|
-
for (const [, instance] of instances) {
|
|
952
|
-
if (instance.assignedRefDes === null) {
|
|
953
|
-
if (instance.typeProp === ComponentTypes.label ||
|
|
954
|
-
instance.typeProp === ComponentTypes.net ||
|
|
955
|
-
instance.typeProp === ComponentTypes.point) {
|
|
956
|
-
continue;
|
|
957
|
-
}
|
|
958
|
-
if (instance.typeProp === null) {
|
|
959
|
-
this.print('Instance has no type:', instance.instanceName, ' assuming connector');
|
|
960
|
-
instance.typeProp = 'conn';
|
|
961
|
-
}
|
|
962
|
-
if (instance.parameters.has('refdes')) {
|
|
963
|
-
const refdes = instance.parameters.get('refdes');
|
|
964
|
-
if (refdes) {
|
|
965
|
-
instance.assignedRefDes = refdes;
|
|
966
|
-
annotater.trackRefDes(refdes);
|
|
967
|
-
this.print(refdes, '-', instance.instanceName);
|
|
968
|
-
continue;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
toAnnotate.push(instance);
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
toAnnotate.forEach(instance => {
|
|
975
|
-
const newRefDes = annotater.getAnnotation(instance.typeProp);
|
|
976
|
-
if (newRefDes !== null) {
|
|
977
|
-
instance.assignedRefDes = newRefDes;
|
|
978
|
-
this.print(newRefDes, '-', instance.instanceName);
|
|
979
|
-
}
|
|
980
|
-
else {
|
|
981
|
-
this.print('Failed to annotate:', instance.instanceName);
|
|
982
|
-
}
|
|
983
|
-
});
|
|
984
|
-
this.print('===== annotate done =====');
|
|
985
|
-
this.print('');
|
|
986
|
-
}
|
|
987
|
-
resolveNets(scope, instance) {
|
|
988
|
-
const result = [];
|
|
989
|
-
for (const [pinId, pin] of instance.pins) {
|
|
990
|
-
let netName = NoNetText;
|
|
991
|
-
let netBaseName = NoNetText;
|
|
992
|
-
if (scope.hasNet(instance, pinId)) {
|
|
993
|
-
const netObject = scope.getNet(instance, pinId);
|
|
994
|
-
netName = netObject.namespace + netObject.name;
|
|
995
|
-
netBaseName = netObject.baseName;
|
|
996
|
-
}
|
|
997
|
-
result.push({
|
|
998
|
-
pin: pin,
|
|
999
|
-
netName: netName,
|
|
1000
|
-
netBaseName,
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
return result;
|
|
1004
|
-
}
|
|
1005
|
-
setComponentOrientation(component, pin, orientation) {
|
|
1006
|
-
if (this.acceptedDirections.indexOf(orientation) !== -1) {
|
|
1007
|
-
component.setParam('_addDirection', orientation);
|
|
1008
|
-
component.setParam('_addPin', pin);
|
|
1009
|
-
}
|
|
1010
|
-
else {
|
|
1011
|
-
throw "Invalid modifier for orientation";
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
getPropertyExprList(items) {
|
|
1015
|
-
const properties = new Map();
|
|
1016
|
-
items.forEach((item) => {
|
|
1017
|
-
const result = this.visit(item);
|
|
1018
|
-
for (const [key, value] of result) {
|
|
1019
|
-
properties.set(key, value);
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
return properties;
|
|
1023
|
-
}
|
|
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
|
-
checkNetNamespaceIncludes(targetNetName, targetNamespaceParts, net) {
|
|
1037
|
-
if (net.name === targetNetName) {
|
|
1038
|
-
const netNamespaceParts = this.getNamespaceParts(net.namespace);
|
|
1039
|
-
this.print('check namespace', targetNetName, targetNamespaceParts, netNamespaceParts);
|
|
1040
|
-
let matches = 0;
|
|
1041
|
-
for (let i = 0; i < netNamespaceParts.length; i++) {
|
|
1042
|
-
if (netNamespaceParts[i] === targetNamespaceParts[i]) {
|
|
1043
|
-
matches++;
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
if (matches === netNamespaceParts.length) {
|
|
1047
|
-
return true;
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
return false;
|
|
1051
|
-
}
|
|
1052
|
-
getNamespaceParts(namespace) {
|
|
1053
|
-
return namespace.split(".").slice(0, -2);
|
|
1054
|
-
}
|
|
1055
|
-
setupPrintFunction(context) {
|
|
1056
|
-
context.createFunction('print', (params) => {
|
|
1057
|
-
const items = params.map(([, , value]) => {
|
|
1058
|
-
return value;
|
|
1059
|
-
});
|
|
1060
|
-
if (this.printToConsole) {
|
|
1061
|
-
console.log('::', ...items);
|
|
1062
|
-
}
|
|
1063
|
-
this.printStream.push(...items);
|
|
1064
|
-
return [this, null];
|
|
1065
|
-
});
|
|
1066
|
-
}
|
|
1067
|
-
getNetNamespace(executorNetNamespace, passedNetNamespace) {
|
|
1068
|
-
let result = executorNetNamespace;
|
|
1069
|
-
if (passedNetNamespace !== null && passedNetNamespace.length > 0) {
|
|
1070
|
-
if (passedNetNamespace === '/' || passedNetNamespace === '_') {
|
|
1071
|
-
result = '';
|
|
1072
|
-
}
|
|
1073
|
-
else if (passedNetNamespace[0] === '+') {
|
|
1074
|
-
if (executorNetNamespace === '/') {
|
|
1075
|
-
result = passedNetNamespace.slice(1);
|
|
1076
|
-
}
|
|
1077
|
-
else {
|
|
1078
|
-
result = executorNetNamespace + passedNetNamespace.slice(2);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
else {
|
|
1082
|
-
result = passedNetNamespace;
|
|
1083
|
-
}
|
|
1084
|
-
result = result + '/';
|
|
1085
|
-
}
|
|
1086
|
-
return result;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
const ComponentRefDesPrefixes = {
|
|
1090
|
-
'res': 'R',
|
|
1091
|
-
'cap': 'C',
|
|
1092
|
-
'ind': 'L',
|
|
1093
|
-
'diode': 'D',
|
|
1094
|
-
'conn': 'J',
|
|
1095
|
-
'transistor': 'Q',
|
|
1096
|
-
'relay': 'K',
|
|
1097
|
-
'ic': 'U',
|
|
1098
|
-
'?': '?',
|
|
1099
|
-
};
|
|
1100
|
-
class ComponentAnnotater {
|
|
1101
|
-
counter = {};
|
|
1102
|
-
existingRefDes = [];
|
|
1103
|
-
constructor() {
|
|
1104
|
-
for (const key in ComponentRefDesPrefixes) {
|
|
1105
|
-
this.counter[key] = 1;
|
|
1106
|
-
}
|
|
1107
|
-
this.counter['?'] = 1;
|
|
1108
|
-
}
|
|
1109
|
-
getAnnotation(type) {
|
|
1110
|
-
if (this.counter[type] === undefined && type.length <= 2) {
|
|
1111
|
-
for (const [, value] of Object.entries(ComponentRefDesPrefixes)) {
|
|
1112
|
-
if (value === type) {
|
|
1113
|
-
throw "Refdes prefix is already in use!";
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
1117
|
-
ComponentRefDesPrefixes[type] = type;
|
|
1118
|
-
this.counter[type] = 1;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
let attempts = 100;
|
|
1122
|
-
let proposedName;
|
|
1123
|
-
while (attempts >= 0) {
|
|
1124
|
-
proposedName = ComponentRefDesPrefixes[type] + this.counter[type];
|
|
1125
|
-
this.counter[type]++;
|
|
1126
|
-
if (this.existingRefDes.indexOf(proposedName) === -1) {
|
|
1127
|
-
break;
|
|
1128
|
-
}
|
|
1129
|
-
attempts--;
|
|
1130
|
-
}
|
|
1131
|
-
if (attempts === 0) {
|
|
1132
|
-
throw "Annotation failed!";
|
|
1133
|
-
}
|
|
1134
|
-
return proposedName;
|
|
1135
|
-
}
|
|
1136
|
-
trackRefDes(name) {
|
|
1137
|
-
this.existingRefDes.push(name);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
export class VisitorExecutionException {
|
|
1141
|
-
errorMessage;
|
|
1142
|
-
context;
|
|
1143
|
-
constructor(context, errorMessage) {
|
|
1144
|
-
this.errorMessage = errorMessage;
|
|
1145
|
-
this.context = context;
|
|
1146
|
-
}
|
|
1147
|
-
print(scriptData) {
|
|
1148
|
-
const startPoint = this.context.start.start;
|
|
1149
|
-
const endPoint = this.context.stop.stop + 1;
|
|
1150
|
-
console.log('Error at line ' +
|
|
1151
|
-
this.context.start.line + "," + this.context.start.column + ": "
|
|
1152
|
-
+ scriptData.slice(startPoint, endPoint) + " - " + this.errorMessage);
|
|
1153
|
-
}
|
|
1154
|
-
}
|