circuitscript 0.1.4 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/cjs/BaseVisitor.js +149 -80
  2. package/dist/cjs/SemanticTokenVisitor.js +19 -13
  3. package/dist/cjs/antlr/CircuitScriptParser.js +711 -671
  4. package/dist/cjs/builtinMethods.js +48 -22
  5. package/dist/cjs/draw_symbols.js +4 -1
  6. package/dist/cjs/environment.js +118 -0
  7. package/dist/cjs/execute.js +98 -46
  8. package/dist/cjs/geometry.js +1 -0
  9. package/dist/cjs/globals.js +14 -7
  10. package/dist/cjs/helpers.js +142 -150
  11. package/dist/cjs/index.js +5 -0
  12. package/dist/cjs/layout.js +39 -14
  13. package/dist/cjs/main.js +34 -21
  14. package/dist/cjs/objects/ClassComponent.js +4 -1
  15. package/dist/cjs/objects/ExecutionScope.js +40 -2
  16. package/dist/cjs/objects/ParamDefinition.js +15 -15
  17. package/dist/cjs/parser.js +27 -21
  18. package/dist/cjs/regenerate-tests.js +9 -6
  19. package/dist/cjs/render.js +3 -1
  20. package/dist/cjs/sizing.js +10 -60
  21. package/dist/cjs/utils.js +148 -17
  22. package/dist/cjs/validate/SymbolTable.js +96 -0
  23. package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +14 -0
  24. package/dist/cjs/validate/SymbolValidatorVisitor.js +170 -0
  25. package/dist/cjs/validate.js +52 -44
  26. package/dist/cjs/visitor.js +149 -31
  27. package/dist/esm/{BaseVisitor.mjs → BaseVisitor.js} +124 -56
  28. package/dist/esm/{SemanticTokenVisitor.mjs → SemanticTokenVisitor.js} +17 -11
  29. package/dist/esm/antlr/{CircuitScriptParser.mjs → CircuitScriptParser.js} +711 -671
  30. package/dist/esm/{builtinMethods.mjs → builtinMethods.js} +40 -14
  31. package/dist/esm/{draw_symbols.mjs → draw_symbols.js} +11 -8
  32. package/dist/esm/environment.js +110 -0
  33. package/dist/esm/{execute.mjs → execute.js} +111 -58
  34. package/dist/esm/{export.mjs → export.js} +2 -2
  35. package/dist/esm/{geometry.mjs → geometry.js} +6 -5
  36. package/dist/esm/{globals.mjs → globals.js} +9 -2
  37. package/dist/esm/helpers.js +377 -0
  38. package/dist/esm/index.js +20 -0
  39. package/dist/esm/{layout.mjs → layout.js} +44 -22
  40. package/dist/esm/{lexer.mjs → lexer.js} +2 -2
  41. package/dist/esm/{main.mjs → main.js} +36 -23
  42. package/dist/esm/objects/{ClassComponent.mjs → ClassComponent.js} +9 -5
  43. package/dist/esm/objects/{ExecutionScope.mjs → ExecutionScope.js} +40 -2
  44. package/dist/esm/objects/{Frame.mjs → Frame.js} +1 -1
  45. package/dist/esm/objects/{ParamDefinition.mjs → ParamDefinition.js} +1 -1
  46. package/dist/esm/objects/{PinDefinition.mjs → PinDefinition.js} +1 -1
  47. package/dist/esm/parser.js +71 -0
  48. package/dist/esm/{regenerate-tests.mjs → regenerate-tests.js} +10 -7
  49. package/dist/esm/{render.mjs → render.js} +11 -9
  50. package/dist/esm/{sizing.mjs → sizing.js} +11 -36
  51. package/dist/esm/utils.js +286 -0
  52. package/dist/esm/validate/SymbolTable.js +90 -0
  53. package/dist/esm/validate/SymbolValidatorResolveVisitor.js +10 -0
  54. package/dist/esm/validate/SymbolValidatorVisitor.js +163 -0
  55. package/dist/esm/validate.js +86 -0
  56. package/dist/esm/{visitor.mjs → visitor.js} +160 -42
  57. package/dist/fonts/Arial.ttf +0 -0
  58. package/dist/fonts/Inter-Bold.ttf +0 -0
  59. package/dist/fonts/Inter-Regular.ttf +0 -0
  60. package/dist/fonts/OpenSans-Regular.ttf +0 -0
  61. package/dist/fonts/Roboto-Regular.ttf +0 -0
  62. package/dist/libs/lib.cst +423 -0
  63. package/dist/types/BaseVisitor.d.ts +36 -22
  64. package/dist/types/SemanticTokenVisitor.d.ts +6 -5
  65. package/dist/types/antlr/CircuitScriptParser.d.ts +4 -2
  66. package/dist/types/builtinMethods.d.ts +3 -2
  67. package/dist/types/draw_symbols.d.ts +2 -6
  68. package/dist/types/environment.d.ts +31 -0
  69. package/dist/types/execute.d.ts +2 -3
  70. package/dist/types/globals.d.ts +7 -2
  71. package/dist/types/helpers.d.ts +12 -14
  72. package/dist/types/index.d.ts +5 -0
  73. package/dist/types/objects/ClassComponent.d.ts +2 -3
  74. package/dist/types/objects/ExecutionScope.d.ts +20 -6
  75. package/dist/types/objects/types.d.ts +6 -1
  76. package/dist/types/parser.d.ts +7 -11
  77. package/dist/types/sizing.d.ts +0 -3
  78. package/dist/types/utils.d.ts +33 -4
  79. package/dist/types/validate/SymbolTable.d.ts +40 -0
  80. package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +7 -0
  81. package/dist/types/validate/SymbolValidatorVisitor.d.ts +32 -0
  82. package/dist/types/validate.d.ts +1 -1
  83. package/libs/lib.cst +12 -22
  84. package/package.json +14 -13
  85. package/dist/cjs/SymbolValidatorVisitor.js +0 -233
  86. package/dist/esm/SymbolValidatorVisitor.mjs +0 -222
  87. package/dist/esm/helpers.mjs +0 -380
  88. package/dist/esm/index.mjs +0 -15
  89. package/dist/esm/parser.mjs +0 -64
  90. package/dist/esm/utils.mjs +0 -169
  91. package/dist/esm/validate.mjs +0 -74
  92. package/dist/types/SymbolValidatorVisitor.d.ts +0 -61
  93. package/dist/types/layout.d.ts +0 -148
  94. /package/dist/esm/antlr/{CircuitScriptLexer.mjs → CircuitScriptLexer.js} +0 -0
  95. /package/dist/esm/antlr/{CircuitScriptVisitor.mjs → CircuitScriptVisitor.js} +0 -0
  96. /package/dist/esm/{fonts.mjs → fonts.js} +0 -0
  97. /package/dist/esm/{logger.mjs → logger.js} +0 -0
  98. /package/dist/esm/objects/{Net.mjs → Net.js} +0 -0
  99. /package/dist/esm/objects/{PinTypes.mjs → PinTypes.js} +0 -0
  100. /package/dist/esm/objects/{Wire.mjs → Wire.js} +0 -0
  101. /package/dist/esm/objects/{types.mjs → types.js} +0 -0
  102. /package/dist/esm/{server.mjs → server.js} +0 -0
@@ -0,0 +1,163 @@
1
+ import { buildInMethodNamesList } from "../builtinMethods.js";
2
+ import { ParseSymbolType } from "../objects/types.js";
3
+ import { SymbolTable } from "./SymbolTable.js";
4
+ import { BaseVisitor } from "../BaseVisitor.js";
5
+ import { SymbolValidatorContext } from "../globals.js";
6
+ export class SymbolValidatorVisitor extends BaseVisitor {
7
+ symbolTable = new SymbolTable();
8
+ filePathStack = [];
9
+ enterFile(filePath) {
10
+ this.filePathStack.push(filePath);
11
+ }
12
+ exitFile() {
13
+ this.filePathStack.pop();
14
+ }
15
+ getCurrentFile() {
16
+ return this.filePathStack[this.filePathStack.length - 1];
17
+ }
18
+ addSymbolVariable(token, name, value, executor = null) {
19
+ const useExecutor = executor === null ? this.getExecutor() : executor;
20
+ this.symbolTable.addVariable(token, this.getCurrentFile(), useExecutor, name, value);
21
+ this.log2('add symbol variable: ' + name);
22
+ }
23
+ addSymbolFunction(token, functionName, funcDefinedParameters) {
24
+ if (!this.symbolTable.exists(this.getExecutor(), functionName)) {
25
+ this.symbolTable.addFunction(token, this.getCurrentFile(), this.getExecutor(), functionName, funcDefinedParameters);
26
+ this.log2('add symbol function: ' + functionName);
27
+ }
28
+ }
29
+ handleAtomSymbol(atom) {
30
+ const atomId = atom.getText();
31
+ const executor = this.getExecutor();
32
+ let tmpSymbol;
33
+ if (this.symbolTable.exists(executor, atomId)) {
34
+ tmpSymbol = this.symbolTable.get(executor, atomId);
35
+ }
36
+ else {
37
+ if (buildInMethodNamesList.indexOf(atomId) !== -1) {
38
+ tmpSymbol = this.symbolTable.addFunction(null, "<builtIn>", this.getRootExecutor(), atomId, {});
39
+ }
40
+ else {
41
+ const foundContext = this.symbolTable.searchParentContext(executor, atomId);
42
+ if (foundContext === null) {
43
+ tmpSymbol = this.symbolTable.addUndefined(this.getCurrentFile(), executor, atomId, atom.getSymbol());
44
+ this.log2('symbol not found: ' + atomId);
45
+ }
46
+ else {
47
+ tmpSymbol = this.symbolTable.get(foundContext, atomId);
48
+ }
49
+ }
50
+ }
51
+ if (tmpSymbol.type !== ParseSymbolType.Undefined) {
52
+ this.addSymbolInstance(tmpSymbol, atom.getSymbol());
53
+ }
54
+ return tmpSymbol;
55
+ }
56
+ addSymbolInstance(symbol, token) {
57
+ symbol = symbol;
58
+ if (symbol.instances.indexOf(token) == -1) {
59
+ symbol.instances.push(token);
60
+ }
61
+ }
62
+ setSymbols(symbolTable) {
63
+ this.symbolTable = symbolTable;
64
+ }
65
+ visitImport_expr = (ctx) => {
66
+ const ID = ctx.ID().toString();
67
+ const { pathExists } = this.handleImportFile(ID, false, ctx);
68
+ if (!pathExists) {
69
+ this.symbolTable.addUndefined(this.getCurrentFile(), this.getExecutor(), ID, ctx.ID().getSymbol());
70
+ }
71
+ };
72
+ visitAssignment_expr = (ctx) => {
73
+ const ctxDataExpr = ctx.data_expr();
74
+ this.visit(ctxDataExpr);
75
+ const value = this.getResult(ctxDataExpr);
76
+ const atomId = ctx.atom_expr().ID(0);
77
+ const atomText = atomId.getText();
78
+ const executor = this.getExecutor();
79
+ if (!this.symbolTable.exists(executor, atomText)) {
80
+ this.addSymbolVariable(atomId.getSymbol(), atomId.getText(), value);
81
+ }
82
+ else {
83
+ const tmpSymbol = this.symbolTable.get(executor, atomText);
84
+ this.addSymbolInstance(tmpSymbol, atomId.getSymbol());
85
+ }
86
+ return null;
87
+ };
88
+ visitAtom_expr = (ctx) => {
89
+ const tmpSymbol = this.handleAtomSymbol(ctx.ID(0));
90
+ this.setResult(ctx, tmpSymbol);
91
+ };
92
+ visitFunction_call_expr = (ctx) => {
93
+ this.handleAtomSymbol(ctx.ID());
94
+ if (ctx.trailer_expr().length > 0) {
95
+ ctx.trailer_expr().forEach(item => {
96
+ if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
97
+ const params = item.parameters();
98
+ if (params) {
99
+ this.visit(params);
100
+ }
101
+ }
102
+ });
103
+ }
104
+ };
105
+ visitValueAtomExpr = (ctx) => {
106
+ let value = null;
107
+ const ctxValueExpr = ctx.value_expr();
108
+ const cxtAtomExpr = ctx.atom_expr();
109
+ if (ctxValueExpr) {
110
+ this.visit(ctxValueExpr);
111
+ value = this.getResult(ctxValueExpr);
112
+ }
113
+ else if (cxtAtomExpr) {
114
+ this.visit(cxtAtomExpr);
115
+ value = this.getResult(cxtAtomExpr);
116
+ }
117
+ this.setResult(ctx, value);
118
+ };
119
+ visitUnaryOperatorExpr = (ctx) => {
120
+ this.visit(ctx.data_expr());
121
+ };
122
+ visitMultiplyExpr = (ctx) => {
123
+ this.visit(ctx.data_expr(0));
124
+ this.visit(ctx.data_expr(1));
125
+ };
126
+ visitAdditionExpr = (ctx) => {
127
+ this.visit(ctx.data_expr(0));
128
+ this.visit(ctx.data_expr(1));
129
+ };
130
+ visitBinaryOperatorExpr = (ctx) => {
131
+ this.visit(ctx.data_expr(0));
132
+ this.visit(ctx.data_expr(1));
133
+ };
134
+ visitDataExpr = (ctx) => {
135
+ return;
136
+ };
137
+ visitFunction_def_expr = (ctx) => {
138
+ const functionName = ctx.ID().getText();
139
+ let funcDefinedParameters = [];
140
+ const ctxFunctionArgsExpr = ctx.function_args_expr();
141
+ if (ctxFunctionArgsExpr) {
142
+ this.visit(ctxFunctionArgsExpr);
143
+ funcDefinedParameters = this.getResult(ctxFunctionArgsExpr);
144
+ }
145
+ this.addSymbolFunction(ctx.ID().getSymbol(), functionName, funcDefinedParameters);
146
+ const executionContextName = functionName + SymbolValidatorContext;
147
+ const passedInParamsNull = funcDefinedParameters.map((param, index) => {
148
+ return ['position', index, null];
149
+ });
150
+ const newExecutor = this.enterNewChildContext(this.executionStack, this.getExecutor(), executionContextName, { netNamespace: "" }, funcDefinedParameters, passedInParamsNull);
151
+ funcDefinedParameters.forEach(param => {
152
+ this.addSymbolVariable(param[1], param[0], null, newExecutor);
153
+ });
154
+ this.runExpressions(newExecutor, ctx.function_expr());
155
+ this.executionStack.pop();
156
+ };
157
+ getSymbols() {
158
+ return this.symbolTable;
159
+ }
160
+ dumpSymbols() {
161
+ this.symbolTable.dumpSymbols();
162
+ }
163
+ }
@@ -0,0 +1,86 @@
1
+ #! /usr/bin/env node
2
+ import { program } from 'commander';
3
+ import { readFileSync, existsSync } from 'fs';
4
+ import { getSemanticTokens, validateScript } from './helpers.js';
5
+ import { NodeScriptEnvironment } from "./environment.js";
6
+ import { ParseSymbolType } from './objects/types.js';
7
+ export default async function validate() {
8
+ const env = new NodeScriptEnvironment();
9
+ NodeScriptEnvironment.setInstance(env);
10
+ const version = env.getPackageVersion();
11
+ program
12
+ .description('generate validation output circuitscript files')
13
+ .version(version)
14
+ .argument('[input path]', 'Input path')
15
+ .argument('[output path]', 'Output path')
16
+ .option('-i, --input text <input text>', 'Input text directly')
17
+ .option('-c, --current-directory <path>', 'Set current directory')
18
+ .option('-w, --watch', 'Watch for file changes')
19
+ .option('-n, --dump-nets', 'Dump out net information')
20
+ .option('-d, --dump-data', 'Dump data during parsing')
21
+ .option('-s, --stats', 'Show stats during generation')
22
+ .option('-x, --skip-output', 'Skip output generation');
23
+ if (process.argv.length < 3) {
24
+ program.help();
25
+ }
26
+ program.parse();
27
+ const options = program.opts();
28
+ const args = program.args;
29
+ const watchFileChanges = options.watch;
30
+ const dumpNets = options.dumpNets;
31
+ const dumpData = options.dumpData;
32
+ if (options.currentDirectory) {
33
+ env.setModuleDirectory(options.currentDirectory);
34
+ }
35
+ if (watchFileChanges) {
36
+ console.log('watching for file changes...');
37
+ }
38
+ await env.prepareSVGEnvironment();
39
+ let inputFilePath = "";
40
+ if (args.length > 2) {
41
+ console.log("Error: Extra arguments passed");
42
+ return;
43
+ }
44
+ let scriptData;
45
+ if (args.length > 0 && args[0]) {
46
+ inputFilePath = args[0];
47
+ if (existsSync(inputFilePath)) {
48
+ scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
49
+ }
50
+ else {
51
+ console.error("Error: File could not be found");
52
+ return;
53
+ }
54
+ }
55
+ else if (options.input) {
56
+ scriptData = options.input;
57
+ }
58
+ else {
59
+ console.error("Error: No input provided");
60
+ return;
61
+ }
62
+ const scriptOptions = {
63
+ dumpNets,
64
+ dumpData,
65
+ showStats: options.stats,
66
+ environment: env,
67
+ };
68
+ const visitor = await validateScript(inputFilePath, scriptData, scriptOptions);
69
+ const symbols = visitor.getSymbols().getSymbols();
70
+ symbols.forEach((value, key) => {
71
+ if (value.type !== ParseSymbolType.Undefined) {
72
+ value = value;
73
+ const token = value.token;
74
+ console.log(key, value.fileName, token !== null ? (token.line + ":" + token.column) : "");
75
+ value.instances.forEach(instance => {
76
+ console.log(" " + instance.line + ":" + instance.column + " " + instance.start);
77
+ });
78
+ }
79
+ });
80
+ const { parsedTokens } = await getSemanticTokens(scriptData, scriptOptions);
81
+ parsedTokens.forEach(item => {
82
+ const { line, column, tokenType, tokenModifiers, textValue } = item;
83
+ console.log(`${line}:${column} - ${textValue} - ${tokenType} | ${tokenModifiers.join(',')}`);
84
+ });
85
+ }
86
+ validate();
@@ -1,14 +1,14 @@
1
- import { ClassComponent } from './objects/ClassComponent.mjs';
2
- import { NumberOperator, numeric, NumericValue, ParamDefinition } from './objects/ParamDefinition.mjs';
3
- import { PinDefinition, PinIdType } from './objects/PinDefinition.mjs';
4
- import { PinTypes } from './objects/PinTypes.mjs';
5
- import { DeclaredReference, UndeclaredReference } from './objects/types.mjs';
6
- import { BlockTypes, ComponentTypes, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide, WireAutoDirection } from './globals.mjs';
7
- import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.mjs';
8
- import { BaseVisitor } from './BaseVisitor.mjs';
9
- import { getPortType } from './utils.mjs';
10
- import { UnitDimension } from './helpers.mjs';
11
- import { FrameParamKeys } from './objects/Frame.mjs';
1
+ import { ClassComponent } from './objects/ClassComponent.js';
2
+ import { NumberOperator, numeric, NumericValue, ParamDefinition } from './objects/ParamDefinition.js';
3
+ import { PinDefinition, PinIdType } from './objects/PinDefinition.js';
4
+ import { PinTypes } from './objects/PinTypes.js';
5
+ import { DeclaredReference, UndeclaredReference } from './objects/types.js';
6
+ import { BlockTypes, ComponentTypes, Delimiter1, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, ReferenceTypes, SymbolPinSide, ValidPinSides, WireAutoDirection } from './globals.js';
7
+ import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.js';
8
+ import { BaseVisitor } from './BaseVisitor.js';
9
+ import { getPortType, RuntimeExecutionError } from './utils.js';
10
+ import { UnitDimension } from './helpers.js';
11
+ import { FrameParamKeys } from './objects/Frame.js';
12
12
  export class ParserVisitor extends BaseVisitor {
13
13
  visitKeyword_assignment_expr = (ctx) => {
14
14
  const id = ctx.ID().getText();
@@ -41,9 +41,14 @@ export class ParserVisitor extends BaseVisitor {
41
41
  visitTo_component_expr = (ctx) => {
42
42
  ctx.component_select_expr().forEach(item => {
43
43
  const [component, pin] = this.visitResult(item);
44
- this.getExecutor().toComponent(component, pin, {
45
- addSequence: true
46
- });
44
+ try {
45
+ this.getExecutor().toComponent(component, pin, {
46
+ addSequence: true
47
+ });
48
+ }
49
+ catch (err) {
50
+ throw new RuntimeExecutionError(err.message, ctx.start, ctx.stop);
51
+ }
47
52
  });
48
53
  return this.getExecutor().getCurrentPoint();
49
54
  };
@@ -58,7 +63,10 @@ export class ParserVisitor extends BaseVisitor {
58
63
  componentPin = this.visitResult(ctxDataExprWithAssigment);
59
64
  }
60
65
  else {
61
- const component = this.getExecutor().scope.currentComponent;
66
+ let component = this.getScope().currentComponent;
67
+ if (component._pointLinkComponent) {
68
+ component = component._pointLinkComponent;
69
+ }
62
70
  let pinId = null;
63
71
  const ctxPinSelectExpr = ctx.pin_select_expr();
64
72
  if (ctxPinSelectExpr) {
@@ -106,6 +114,92 @@ export class ParserVisitor extends BaseVisitor {
106
114
  return this.getExecutor().getCurrentPoint();
107
115
  };
108
116
  visitCreate_component_expr = (ctx) => {
117
+ const scope = this.getScope();
118
+ scope.setOnPropertyHandler((path, value, ctx) => {
119
+ if (path.length === 1) {
120
+ const [, keyName] = path[0];
121
+ switch (keyName) {
122
+ case 'type':
123
+ this.validateString(value, ctx);
124
+ break;
125
+ case 'angle':
126
+ case 'width':
127
+ case 'height':
128
+ this.validateNumeric(value, ctx);
129
+ break;
130
+ case 'pins':
131
+ if (!(value instanceof Map)) {
132
+ this.validateNumeric(value, ctx);
133
+ }
134
+ break;
135
+ case 'copy':
136
+ if (value instanceof NumericValue) {
137
+ this.validateNumeric(value, ctx);
138
+ }
139
+ else if (typeof value === 'boolean') {
140
+ this.validateBoolean(value, ctx);
141
+ }
142
+ else {
143
+ throw new RuntimeExecutionError("Invalid value for 'copy' property", ctx.start, ctx.end);
144
+ }
145
+ break;
146
+ }
147
+ }
148
+ else {
149
+ const [, keyName] = path[0];
150
+ if (keyName === 'arrange') {
151
+ const [sideKeyCtx, sideKeyName] = path[1];
152
+ if (ValidPinSides.indexOf(sideKeyName) === -1) {
153
+ throw new RuntimeExecutionError(`Invalid side ${sideKeyName} in arrange`, sideKeyCtx.start, sideKeyCtx.stop);
154
+ }
155
+ else {
156
+ if (path.length > 2 && path[2][0] === 'index') {
157
+ if (Array.isArray(value)) {
158
+ const goodBlank = value.length === 1 &&
159
+ value[0] instanceof NumericValue;
160
+ if (!goodBlank) {
161
+ throw new RuntimeExecutionError(`Invalid blank specifier`, ctx.start, ctx.stop);
162
+ }
163
+ }
164
+ else {
165
+ if (!(value instanceof NumericValue)) {
166
+ throw new RuntimeExecutionError(`Invalid numeric value for arrange.${sideKeyName}`, ctx.start, ctx.stop);
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
172
+ else if (keyName === 'params') {
173
+ const [, subKeyName] = path[1];
174
+ switch (subKeyName) {
175
+ case 'mpn':
176
+ case 'refdes':
177
+ case 'footprint':
178
+ this.validateString(value, ctx);
179
+ break;
180
+ case 'place':
181
+ this.validateBoolean(value, ctx);
182
+ break;
183
+ }
184
+ }
185
+ else if (keyName === 'pins') {
186
+ if (path.length === 2) {
187
+ if (value.length === 2) {
188
+ const [pinType,] = value;
189
+ if (pinType instanceof UndeclaredReference) {
190
+ throw new RuntimeExecutionError(`Invalid pin type: ${pinType.reference.name}`, ctx.start, ctx.end);
191
+ }
192
+ }
193
+ }
194
+ }
195
+ }
196
+ });
197
+ scope.enterContext(ctx);
198
+ ctx.property_expr().forEach(item => {
199
+ this.visitResult(item);
200
+ });
201
+ scope.exitContext();
202
+ scope.popOnPropertyHandler();
109
203
  const properties = this.getPropertyExprList(ctx.property_expr());
110
204
  const pins = this.parseCreateComponentPins(properties.get('pins'));
111
205
  let instanceName = this.getExecutor().getUniqueInstanceName();
@@ -118,7 +212,7 @@ export class ParserVisitor extends BaseVisitor {
118
212
  if (paramValue instanceof NumericValue) {
119
213
  appendValue = paramValue.value;
120
214
  }
121
- instanceName += '_' + appendValue;
215
+ instanceName += `${Delimiter1}${appendValue}`;
122
216
  }
123
217
  const arrange = properties.has('arrange') ?
124
218
  properties.get('arrange') : null;
@@ -140,8 +234,13 @@ export class ParserVisitor extends BaseVisitor {
140
234
  arrange, display, type, width, height, copy,
141
235
  angle, followWireOrientation
142
236
  };
143
- const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
144
- this.setResult(ctx, createdComponent);
237
+ try {
238
+ const createdComponent = this.getExecutor().createComponent(instanceName, pins, params, props);
239
+ this.setResult(ctx, createdComponent);
240
+ }
241
+ catch (error) {
242
+ this.throwWithContext(ctx, error.message);
243
+ }
145
244
  };
146
245
  visitCreate_graphic_expr = (ctx) => {
147
246
  const ctxId = ctx.ID();
@@ -149,7 +248,7 @@ export class ParserVisitor extends BaseVisitor {
149
248
  if (ctxId !== null) {
150
249
  const varName = ctxId.getText();
151
250
  paramIds.push(varName);
152
- this.getExecutor().scope.variables.set(varName, {});
251
+ this.getScope().variables.set(varName, {});
153
252
  }
154
253
  const executor = this.getExecutor();
155
254
  const stack = [...this.executionStack];
@@ -251,7 +350,7 @@ export class ParserVisitor extends BaseVisitor {
251
350
  useValueArray = [useValueArray];
252
351
  }
253
352
  useValueArray.forEach((value, index) => {
254
- this.getExecutor().scope.variables.set(forVariableNames[index], value);
353
+ this.getScope().variables.set(forVariableNames[index], value);
255
354
  });
256
355
  const commands = this.visitResult(ctx.graphic_expressions_block());
257
356
  allCommands = allCommands.concat(commands);
@@ -310,8 +409,16 @@ export class ParserVisitor extends BaseVisitor {
310
409
  this.setResult(ctx, [keyName, expressionsBlock]);
311
410
  };
312
411
  visitProperty_expr = (ctx) => {
313
- const keyName = this.visitResult(ctx.property_key_expr());
314
- const value = this.visitResult(ctx.property_value_expr());
412
+ const ctxKey = ctx.property_key_expr();
413
+ const ctxValue = ctx.property_value_expr();
414
+ const scope = this.getScope();
415
+ this.getScope().enterContext(ctxKey);
416
+ this.getScope().enterContext(ctxValue);
417
+ const keyName = this.visitResult(ctxKey);
418
+ const value = this.visitResult(ctxValue);
419
+ scope.triggerPropertyHandler(value, ctxValue);
420
+ this.getScope().exitContext();
421
+ this.getScope().exitContext();
315
422
  if (value instanceof UndeclaredReference && (value.reference.parentValue === undefined
316
423
  && value.reference.value === undefined)) {
317
424
  throw value.throwMessage();
@@ -321,15 +428,21 @@ export class ParserVisitor extends BaseVisitor {
321
428
  this.setResult(ctx, map);
322
429
  };
323
430
  visitSingle_line_property = (ctx) => {
431
+ this.getScope().enterContext(ctx);
324
432
  let value;
325
433
  if (ctx.data_expr().length === 1) {
326
434
  value = this.visitResult(ctx.data_expr(0));
327
435
  }
328
436
  else {
329
- value = ctx.data_expr().map(item => {
330
- return this.visitResult(item);
437
+ value = ctx.data_expr().map((item, index) => {
438
+ this.getScope().enterContext(index);
439
+ const result = this.visitResult(item);
440
+ this.getScope().triggerPropertyHandler(result, item);
441
+ this.getScope().exitContext();
442
+ return result;
331
443
  });
332
444
  }
445
+ this.getScope().exitContext();
333
446
  this.setResult(ctx, value);
334
447
  };
335
448
  visitNested_properties_inner = (ctx) => {
@@ -446,15 +559,15 @@ export class ParserVisitor extends BaseVisitor {
446
559
  expandModuleContains(component, netNamespace) {
447
560
  this.getExecutor().log('expanding module `contains`');
448
561
  const executionStack = this.executionStack;
449
- const resolveNet = this.createNetResolver(executionStack);
450
562
  const executor = this.getExecutor();
451
- const executionContextName = executor.namespace + "_"
563
+ const executionContextName = executor.namespace + Delimiter1
452
564
  + component.instanceName
453
- + '_' + component.moduleCounter;
454
- const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + "_" + component.moduleCounter);
565
+ + Delimiter1 + component.moduleCounter;
566
+ const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + Delimiter1 + component.moduleCounter);
455
567
  const newExecutor = this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
456
568
  component.moduleCounter += 1;
457
- newExecutor.resolveNet = resolveNet;
569
+ newExecutor.resolveNet = this.createNetResolver(executionStack);
570
+ newExecutor.resolveComponentPinNet = this.createComponentPinNetResolver(executionStack);
458
571
  this.visit(component.moduleContainsExpressions);
459
572
  const executionContext = executionStack.pop();
460
573
  component.moduleExecutionContext = executionContext;
@@ -659,11 +772,13 @@ export class ParserVisitor extends BaseVisitor {
659
772
  const executionStack = this.executionStack;
660
773
  const functionCounter = { counter: 0 };
661
774
  const resolveNet = this.createNetResolver(this.executionStack);
775
+ const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
662
776
  const __runFunc = (passedInParameters, options) => {
663
- const executionContextName = functionName + '_' + functionCounter['counter'];
777
+ const executionContextName = `${functionName}-${functionCounter['counter']}`;
664
778
  const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
665
779
  functionCounter['counter'] += 1;
666
780
  newExecutor.resolveNet = resolveNet;
781
+ newExecutor.resolveComponentPinNet = resolveComponentPinNet;
667
782
  const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
668
783
  const lastExecution = executionStack.pop();
669
784
  const nextLastExecution = executionStack[executionStack.length - 1];
@@ -750,6 +865,9 @@ export class ParserVisitor extends BaseVisitor {
750
865
  }
751
866
  else if (ctxDataExpr) {
752
867
  useValue = this.visitResult(ctxDataExpr);
868
+ if (useValue instanceof NumericValue) {
869
+ useValue = useValue.toNumber();
870
+ }
753
871
  }
754
872
  if (useValue !== null) {
755
873
  this.setResult(ctx, [direction, new UnitDimension(useValue)]);
@@ -891,7 +1009,7 @@ export class ParserVisitor extends BaseVisitor {
891
1009
  useValueArray = [useValueArray];
892
1010
  }
893
1011
  useValueArray.forEach((value, index) => {
894
- this.getExecutor().scope.variables.set(forVariableNames[index], value);
1012
+ this.getScope().variables.set(forVariableNames[index], value);
895
1013
  });
896
1014
  this.visit(ctx.expressions_block());
897
1015
  keepLooping = true;
@@ -1035,32 +1153,32 @@ export class ParserVisitor extends BaseVisitor {
1035
1153
  return result;
1036
1154
  }
1037
1155
  printNets() {
1038
- this.getExecutor().scope.printNets();
1156
+ this.getScope().printNets();
1039
1157
  }
1040
1158
  dumpNets() {
1041
- return this.getExecutor().scope.dumpNets();
1159
+ return this.getScope().dumpNets();
1042
1160
  }
1043
1161
  dumpUniqueNets() {
1044
- const nets = this.getExecutor().scope.getNets();
1162
+ const nets = this.getScope().getNets();
1045
1163
  return nets.reduce((accum, [, , net]) => {
1046
1164
  accum.push(net);
1047
1165
  return accum;
1048
1166
  }, []);
1049
1167
  }
1050
1168
  dumpVariables() {
1051
- return this.getExecutor().scope.variables;
1169
+ return this.getScope().variables;
1052
1170
  }
1053
1171
  dumpInstances() {
1054
- return this.getExecutor().scope.instances;
1172
+ return this.getScope().instances;
1055
1173
  }
1056
1174
  dump2() {
1057
- const instances = this.getExecutor().scope.instances;
1175
+ const instances = this.getScope().instances;
1058
1176
  const items = [];
1059
1177
  for (const [instanceName, instance] of instances) {
1060
1178
  if (instance.assignedRefDes === null) {
1061
1179
  continue;
1062
1180
  }
1063
- const pinNets = this.resolveNets(this.getExecutor().scope, instance);
1181
+ const pinNets = this.resolveNets(this.getScope(), instance);
1064
1182
  const componentItem = {
1065
1183
  name: instanceName,
1066
1184
  refdes: instance.assignedRefDes,
@@ -1075,9 +1193,9 @@ export class ParserVisitor extends BaseVisitor {
1075
1193
  }
1076
1194
  getNetList() {
1077
1195
  const netlist = [];
1078
- const instances = this.getExecutor().scope.instances;
1196
+ const instances = this.getScope().instances;
1079
1197
  for (const [instanceName, instance] of instances) {
1080
- const pinNets = this.resolveNets(this.getExecutor().scope, instance);
1198
+ const pinNets = this.resolveNets(this.getScope(), instance);
1081
1199
  const componentItem = {
1082
1200
  instanceName,
1083
1201
  instance,
@@ -1108,7 +1226,7 @@ export class ParserVisitor extends BaseVisitor {
1108
1226
  annotateComponents() {
1109
1227
  this.log('===== annotate components =====');
1110
1228
  const annotater = new ComponentAnnotater();
1111
- const instances = this.getExecutor().scope.instances;
1229
+ const instances = this.getScope().instances;
1112
1230
  const toAnnotate = [];
1113
1231
  for (const [, instance] of instances) {
1114
1232
  if (instance.typeProp === ComponentTypes.net
@@ -1145,7 +1263,7 @@ export class ParserVisitor extends BaseVisitor {
1145
1263
  this.log('');
1146
1264
  }
1147
1265
  applySheetFrameComponent() {
1148
- const baseScope = this.getExecutor().scope;
1266
+ const baseScope = this.getScope();
1149
1267
  const document = baseScope.variables.get(GlobalDocumentName);
1150
1268
  let frameComponent = null;
1151
1269
  if (document && document[FrameParamKeys.SheetType]) {
Binary file
Binary file
Binary file
Binary file
Binary file