circuitscript 0.3.2 → 0.4.0

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 (147) hide show
  1. package/dist/cjs/BaseVisitor.js +394 -262
  2. package/dist/cjs/LexerDiagnosticListener.js +375 -0
  3. package/dist/cjs/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
  4. package/dist/cjs/annotate/DefaultPostAnnotationCallback.js +126 -0
  5. package/dist/cjs/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
  6. package/dist/cjs/annotate/utils.js +70 -0
  7. package/dist/cjs/antlr/CircuitScriptLexer.js +279 -286
  8. package/dist/cjs/antlr/CircuitScriptParser.js +1954 -3535
  9. package/dist/cjs/antlr/CircuitScriptParserVisitor.js +7 -0
  10. package/dist/cjs/cache/deserializer.js +34 -0
  11. package/dist/cjs/cache/hash.js +8 -0
  12. package/dist/cjs/cache/serializer.js +122 -0
  13. package/dist/cjs/cache/storage.js +45 -0
  14. package/dist/cjs/cache/types.js +4 -0
  15. package/dist/cjs/{environment.js → environment/environment.js} +18 -6
  16. package/dist/cjs/environment/esm-environment.js +21 -0
  17. package/dist/cjs/environment/helpers.js +8 -0
  18. package/dist/cjs/execute.js +49 -15
  19. package/dist/cjs/globals.js +9 -1
  20. package/dist/cjs/helpers.js +3 -485
  21. package/dist/cjs/importResolver.js +102 -0
  22. package/dist/cjs/index.js +7 -6
  23. package/dist/cjs/lexer.js +48 -12
  24. package/dist/cjs/main.js +14 -4
  25. package/dist/cjs/objects/ClassComponent.js +1 -1
  26. package/dist/cjs/objects/ExecutionScope.js +0 -1
  27. package/dist/cjs/objects/types.js +17 -1
  28. package/dist/cjs/parser.js +18 -4
  29. package/dist/cjs/pipeline.js +284 -0
  30. package/dist/cjs/regenerate-tests.js +4 -3
  31. package/dist/cjs/render/KiCadNetListOutputHandler.js +30 -0
  32. package/dist/cjs/render/PaperSizes.js +46 -0
  33. package/dist/cjs/{draw_symbols.js → render/draw_symbols.js} +58 -36
  34. package/dist/cjs/{export.js → render/export.js} +2 -2
  35. package/dist/cjs/{geometry.js → render/geometry.js} +5 -5
  36. package/dist/cjs/{graph.js → render/graph.js} +7 -7
  37. package/dist/cjs/{layout.js → render/layout.js} +8 -8
  38. package/dist/cjs/{render.js → render/render.js} +9 -8
  39. package/dist/cjs/rules-check/no-connect-on-connected-pin.js +1 -1
  40. package/dist/cjs/rules-check/unconnected-pins.js +1 -1
  41. package/dist/cjs/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
  42. package/dist/cjs/semantic-tokens/getSemanticTokens.js +55 -0
  43. package/dist/cjs/sizing.js +2 -2
  44. package/dist/cjs/utils.js +2 -2
  45. package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +6 -0
  46. package/dist/cjs/validate/SymbolValidatorVisitor.js +34 -39
  47. package/dist/cjs/validate/validateScript.js +54 -0
  48. package/dist/cjs/validate.js +5 -4
  49. package/dist/cjs/visitor.js +140 -204
  50. package/dist/esm/BaseVisitor.js +396 -264
  51. package/dist/esm/LexerDiagnosticListener.js +371 -0
  52. package/dist/esm/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
  53. package/dist/esm/annotate/DefaultPostAnnotationCallback.js +122 -0
  54. package/dist/esm/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
  55. package/dist/esm/annotate/utils.js +66 -0
  56. package/dist/esm/antlr/CircuitScriptLexer.js +279 -286
  57. package/dist/esm/antlr/CircuitScriptParser.js +1962 -3522
  58. package/dist/esm/antlr/{CircuitScriptVisitor.js → CircuitScriptParserVisitor.js} +14 -35
  59. package/dist/esm/cache/deserializer.js +30 -0
  60. package/dist/esm/cache/hash.js +4 -0
  61. package/dist/esm/cache/serializer.js +118 -0
  62. package/dist/esm/cache/storage.js +39 -0
  63. package/dist/esm/cache/types.js +1 -0
  64. package/dist/esm/{environment.js → environment/environment.js} +18 -6
  65. package/dist/esm/environment/esm-environment.js +17 -0
  66. package/dist/esm/environment/helpers.js +4 -0
  67. package/dist/esm/execute.js +49 -15
  68. package/dist/esm/globals.js +8 -0
  69. package/dist/esm/helpers.js +5 -474
  70. package/dist/esm/importResolver.js +96 -0
  71. package/dist/esm/index.js +7 -6
  72. package/dist/esm/lexer.js +51 -12
  73. package/dist/esm/main.js +13 -3
  74. package/dist/esm/objects/ClassComponent.js +1 -1
  75. package/dist/esm/objects/ExecutionScope.js +0 -1
  76. package/dist/esm/objects/types.js +21 -1
  77. package/dist/esm/parser.js +19 -5
  78. package/dist/esm/pipeline.js +276 -0
  79. package/dist/esm/regenerate-tests.js +3 -2
  80. package/dist/esm/render/KiCadNetListOutputHandler.js +20 -0
  81. package/dist/esm/render/PaperSizes.js +41 -0
  82. package/dist/esm/{draw_symbols.js → render/draw_symbols.js} +58 -36
  83. package/dist/esm/{export.js → render/export.js} +2 -2
  84. package/dist/esm/{geometry.js → render/geometry.js} +5 -5
  85. package/dist/esm/{graph.js → render/graph.js} +7 -7
  86. package/dist/esm/{layout.js → render/layout.js} +8 -8
  87. package/dist/esm/{render.js → render/render.js} +8 -7
  88. package/dist/esm/rules-check/no-connect-on-connected-pin.js +1 -1
  89. package/dist/esm/rules-check/unconnected-pins.js +1 -1
  90. package/dist/esm/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
  91. package/dist/esm/semantic-tokens/getSemanticTokens.js +51 -0
  92. package/dist/esm/sizing.js +2 -2
  93. package/dist/esm/utils.js +2 -2
  94. package/dist/esm/validate/SymbolValidatorResolveVisitor.js +3 -0
  95. package/dist/esm/validate/SymbolValidatorVisitor.js +36 -41
  96. package/dist/esm/validate/validateScript.js +50 -0
  97. package/dist/esm/validate.js +4 -3
  98. package/dist/esm/visitor.js +142 -206
  99. package/dist/libs/std.cst +15 -19
  100. package/dist/types/BaseVisitor.d.ts +25 -18
  101. package/dist/types/BomGeneration.d.ts +1 -1
  102. package/dist/types/LexerDiagnosticListener.d.ts +85 -0
  103. package/dist/types/{ComponentAnnotater.d.ts → annotate/ComponentAnnotater.d.ts} +1 -1
  104. package/dist/types/annotate/DefaultPostAnnotationCallback.d.ts +7 -0
  105. package/dist/types/{RefdesAnnotationVisitor.d.ts → annotate/RefdesAnnotationVisitor.d.ts} +6 -8
  106. package/dist/types/annotate/utils.d.ts +6 -0
  107. package/dist/types/antlr/CircuitScriptLexer.d.ts +71 -70
  108. package/dist/types/antlr/CircuitScriptParser.d.ts +357 -515
  109. package/dist/types/antlr/{CircuitScriptVisitor.d.ts → CircuitScriptParserVisitor.d.ts} +27 -69
  110. package/dist/types/cache/deserializer.d.ts +5 -0
  111. package/dist/types/cache/hash.d.ts +1 -0
  112. package/dist/types/cache/serializer.d.ts +3 -0
  113. package/dist/types/cache/storage.d.ts +4 -0
  114. package/dist/types/cache/types.d.ts +20 -0
  115. package/dist/types/{environment.d.ts → environment/environment.d.ts} +5 -4
  116. package/dist/types/environment/esm-environment.d.ts +4 -0
  117. package/dist/types/environment/helpers.d.ts +2 -0
  118. package/dist/types/execute.d.ts +3 -2
  119. package/dist/types/globals.d.ts +1 -0
  120. package/dist/types/helpers.d.ts +31 -36
  121. package/dist/types/importResolver.d.ts +4 -0
  122. package/dist/types/index.d.ts +7 -6
  123. package/dist/types/lexer.d.ts +9 -5
  124. package/dist/types/objects/ClassComponent.d.ts +1 -1
  125. package/dist/types/objects/ExecutionScope.d.ts +1 -4
  126. package/dist/types/objects/types.d.ts +16 -2
  127. package/dist/types/parser.d.ts +9 -2
  128. package/dist/types/pipeline.d.ts +9 -0
  129. package/dist/types/render/KiCadNetListOutputHandler.d.ts +10 -0
  130. package/dist/types/render/PaperSizes.d.ts +12 -0
  131. package/dist/types/{draw_symbols.d.ts → render/draw_symbols.d.ts} +4 -4
  132. package/dist/types/{export.d.ts → render/export.d.ts} +1 -1
  133. package/dist/types/{geometry.d.ts → render/geometry.d.ts} +2 -2
  134. package/dist/types/{graph.d.ts → render/graph.d.ts} +6 -6
  135. package/dist/types/{layout.d.ts → render/layout.d.ts} +10 -10
  136. package/dist/types/{render.d.ts → render/render.d.ts} +1 -1
  137. package/dist/types/{SemanticTokenVisitor.d.ts → semantic-tokens/SemanticTokenVisitor.d.ts} +6 -6
  138. package/dist/types/semantic-tokens/getSemanticTokens.d.ts +6 -0
  139. package/dist/types/sizing.d.ts +1 -1
  140. package/dist/types/utils.d.ts +1 -1
  141. package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +3 -0
  142. package/dist/types/validate/SymbolValidatorVisitor.d.ts +8 -8
  143. package/dist/types/validate/validateScript.d.ts +3 -0
  144. package/dist/types/visitor.d.ts +8 -14
  145. package/libs/std.cst +15 -19
  146. package/package.json +3 -6
  147. package/dist/cjs/antlr/CircuitScriptVisitor.js +0 -7
@@ -1,81 +1,61 @@
1
1
  import { AbstractParseTreeVisitor } from "antlr4ng";
2
- export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
2
+ export class CircuitScriptParserVisitor extends AbstractParseTreeVisitor {
3
3
  visitScript;
4
4
  visitExpression;
5
5
  visitFlow_expressions;
6
6
  visitGraph_expressions;
7
- visitGraph_linear_expression;
8
7
  visitExpressions_block;
9
8
  visitPath_block;
10
- visitProperty_set_expr2;
11
- visitAssignment_expr2;
12
9
  visitPin_select_expr;
13
10
  visitComponent_modifier_expr;
14
11
  visitData_expr_with_assignment;
12
+ visitAssignment_expr;
15
13
  visitAdd_component_expr;
16
14
  visitComponent_select_expr;
17
- visitPin_select_expr2;
18
15
  visitAt_component_expr;
19
16
  visitTo_component_expr;
20
- visitAt_to_multiple_expr;
21
- visitAt_to_multiple_line_expr;
22
- visitAt_to_multiple_line_expr_to_pin;
17
+ visitAt_block_header;
23
18
  visitAt_block;
24
19
  visitAt_block_expressions;
25
- visitAt_block_header;
26
20
  visitAt_block_pin_expr;
27
- visitAt_block_pin_expression_simple;
28
- visitAt_block_pin_expression_complex;
29
- visitAssignment_expr;
30
- visitOperator_assignment_expr;
31
21
  visitKeyword_assignment_expr;
32
22
  visitParameters;
33
- visitProperty_set_expr;
34
23
  visitDouble_dot_property_set_expr;
24
+ visitValueExpr;
35
25
  visitArrayExpr;
36
- visitArrayIndexExpr;
37
- visitFunctionCallExpr;
38
26
  visitAdditionExpr;
39
27
  visitMultiplyExpr;
40
28
  visitLogicalOperatorExpr;
41
- visitDataExpr;
29
+ visitCreateExpr;
42
30
  visitUnaryOperatorExpr;
43
- visitValueAtomExpr;
31
+ visitCallableExpr;
44
32
  visitBinaryOperatorExpr;
45
33
  visitRoundedBracketsExpr;
46
- visitBinary_operator;
47
- visitUnary_operator;
48
34
  visitValue_expr;
49
35
  visitFunction_def_expr;
50
36
  visitFunction_expr;
51
37
  visitFunction_args_expr;
52
- visitAtom_expr;
53
- visitTrailer_expr;
54
- visitTrailer_expr2;
55
- visitFunction_call_expr;
56
- visitNet_namespace_expr;
57
38
  visitFunction_return_expr;
39
+ visitNet_namespace_expr;
40
+ visitCallable_expr;
41
+ visitTrailer;
58
42
  visitProperty_block_expr;
59
- visitCreate_component_expr;
43
+ visitProperties_block;
60
44
  visitGraphic_expressions_block;
45
+ visitCreate_expr;
46
+ visitCreate_component_expr;
61
47
  visitCreate_graphic_expr;
62
48
  visitCreate_module_expr;
63
- visitNested_properties_inner;
64
- visitGraphicCommandExpr;
65
49
  visitGraphicForExpr;
50
+ visitGraphicCommandExpr;
66
51
  visitProperty_expr;
67
52
  visitProperty_key_expr;
68
53
  visitNested_properties;
69
54
  visitSingle_line_property;
70
- visitWire_expr_direction_value;
71
- visitWire_expr_direction_only;
72
55
  visitWire_expr;
73
- visitArray_expr;
74
56
  visitPoint_expr;
75
57
  visitImport_simple;
76
- visitImport_all_simple;
77
- visitImport_specific;
78
- visitImport_annotation_expr;
58
+ visitImport_specific_or_all;
79
59
  visitFrame_expr;
80
60
  visitIf_expr;
81
61
  visitIf_inner_expr;
@@ -87,7 +67,6 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
87
67
  visitPart_match_block;
88
68
  visitPart_sub_expr;
89
69
  visitPart_condition_expr;
90
- visitPart_condition_key_only_expr;
91
70
  visitPart_value_expr;
92
71
  visitAnnotation_comment_expr;
93
72
  }
@@ -0,0 +1,30 @@
1
+ import { ImportedLibrary } from '../objects/types.js';
2
+ export function deserializeLibraryScope(ir, name, libraryNamespace, filePathUsed, importHandling, specificImports, importContext, parseAndVisit, enterContext, exitContext, libraryFileHash) {
3
+ const importedLibrary = new ImportedLibrary(name, libraryNamespace, filePathUsed, null, null, importContext, importHandling, specificImports, libraryFileHash);
4
+ ir.functions.forEach(func => {
5
+ const { name, uniqueId } = func;
6
+ const functionEntry = importContext.createFunctionLazyLoaded(importContext.namespace, name, uniqueId);
7
+ functionEntry.lazyLoader = () => {
8
+ importContext.log(`loading lazy function ${name}`);
9
+ enterContext();
10
+ const [line, column, sourceText] = func.sourceText;
11
+ const { tokens, tree } = parseAndVisit(sourceText, line - 1);
12
+ importedLibrary.referencedTokens.push([tokens, tree]);
13
+ exitContext();
14
+ functionEntry.tokens = tokens;
15
+ functionEntry.tree = tree;
16
+ };
17
+ });
18
+ enterContext();
19
+ for (const importStatement of ir.imports) {
20
+ const [line, column, statement] = importStatement;
21
+ parseAndVisit(statement, line - 1);
22
+ }
23
+ for (const block of (ir.topLevel ?? [])) {
24
+ const [line, column, sourceText] = block;
25
+ const { tokens, tree } = parseAndVisit(sourceText, line - 1);
26
+ importedLibrary.referencedTokens.push([tokens, tree]);
27
+ }
28
+ exitContext();
29
+ return importedLibrary;
30
+ }
@@ -0,0 +1,4 @@
1
+ import { createHash } from 'crypto';
2
+ export function computeContentHash(fileContent) {
3
+ return createHash('sha256').update(fileContent, 'utf8').digest('hex');
4
+ }
@@ -0,0 +1,118 @@
1
+ import { CACHE_SCHEMA_VERSION } from './types.js';
2
+ import { CircuitScriptLexer } from '../antlr/CircuitScriptLexer.js';
3
+ import { generateModifiedSourceText } from '../annotate/utils.js';
4
+ export function serializeLibraryScope(importedLib, contentHash) {
5
+ const functions = [];
6
+ const topLevelExpressions = [];
7
+ const scope = importedLib.context.scope;
8
+ const { tokens: libraryTokens, refdesAnnotations } = importedLib;
9
+ const libraryInputStream = libraryTokens.tokenSource.inputStream;
10
+ scope.functions.forEach((entry) => {
11
+ let useSource = '';
12
+ let useTokenLine = 0;
13
+ let useTokenColumn = 0;
14
+ if (libraryTokens !== null && entry.source !== null) {
15
+ const source = entry.source;
16
+ const startIndex = source.start?.tokenIndex ?? 0;
17
+ const stopIndex = source.stop?.tokenIndex ?? -1;
18
+ const contextTokens = libraryTokens.getTokens(startIndex, stopIndex);
19
+ const startToken = source.start;
20
+ const startChar = startToken.start ?? -1;
21
+ const stopChar = getFunctionDefinitionEnding(source, libraryTokens);
22
+ const sourceText = libraryInputStream != null && startChar >= 0 && stopChar >= 0
23
+ ? libraryInputStream.getTextFromRange(startChar, stopChar)
24
+ : libraryTokens.getTextFromContext(source);
25
+ useSource = generateModifiedSourceText(refdesAnnotations, contextTokens, sourceText, startToken.start);
26
+ useTokenLine = startToken.line;
27
+ useTokenColumn = startToken.column;
28
+ }
29
+ functions.push({
30
+ name: entry.name,
31
+ namespace: entry.originalNamespace,
32
+ uniqueId: entry.uniqueId ?? '',
33
+ sourceText: [
34
+ useTokenLine, useTokenColumn, useSource
35
+ ]
36
+ });
37
+ });
38
+ const tree = importedLib.tree;
39
+ if (tree != null) {
40
+ let groupCtx = [];
41
+ let groupStart = null;
42
+ let prevStopLine = null;
43
+ const flushGroup = () => {
44
+ let useSource = '';
45
+ if (groupCtx.length > 0 && groupStart !== null) {
46
+ const startToken = groupCtx[0].start;
47
+ const stopToken = groupCtx[groupCtx.length - 1].stop;
48
+ const startIndex = startToken.tokenIndex ?? 0;
49
+ const stopIndex = stopToken.tokenIndex ?? -1;
50
+ const contextTokens = libraryTokens.getTokens(startIndex, stopIndex);
51
+ const startChar = startToken.start ?? -1;
52
+ const stopChar = stopToken.stop ?? -1;
53
+ const sourceText = libraryInputStream.getTextFromRange(startChar, stopChar);
54
+ useSource = generateModifiedSourceText(refdesAnnotations, contextTokens, sourceText, startToken.start);
55
+ topLevelExpressions.push([
56
+ ...groupStart,
57
+ useSource
58
+ ]);
59
+ }
60
+ groupCtx = [];
61
+ groupStart = null;
62
+ prevStopLine = null;
63
+ };
64
+ for (const exprCtx of tree.expression()) {
65
+ if (exprCtx.function_def_expr() !== null) {
66
+ flushGroup();
67
+ continue;
68
+ }
69
+ if (exprCtx.NEWLINE() !== null) {
70
+ if (groupCtx.length > 0) {
71
+ groupCtx.push(exprCtx);
72
+ }
73
+ continue;
74
+ }
75
+ const startToken = exprCtx.start;
76
+ if (startToken == null)
77
+ continue;
78
+ const currentStartLine = startToken.line;
79
+ if (prevStopLine !== null && currentStartLine > prevStopLine + 1) {
80
+ flushGroup();
81
+ }
82
+ if (groupStart == null) {
83
+ groupStart = [currentStartLine, startToken.column];
84
+ }
85
+ groupCtx.push(exprCtx);
86
+ prevStopLine = exprCtx.stop?.line ?? currentStartLine;
87
+ }
88
+ flushGroup();
89
+ }
90
+ const imports = [];
91
+ for (const [libName, lib] of importedLib.context.scope.libraries) {
92
+ imports.push(lib.importStatement);
93
+ }
94
+ return {
95
+ schemaVersion: CACHE_SCHEMA_VERSION,
96
+ contentHash,
97
+ libraryFilePath: importedLib.libraryFilePath,
98
+ imports,
99
+ functions,
100
+ topLevel: topLevelExpressions,
101
+ };
102
+ }
103
+ function getFunctionDefinitionEnding(source, tokens) {
104
+ let stopChar = source.stop?.stop ?? -1;
105
+ const stopTokenIndex = source.stop?.tokenIndex ?? -1;
106
+ if (stopTokenIndex >= 0) {
107
+ for (let i = stopTokenIndex; i >= 0; i--) {
108
+ const tok = tokens.get(i);
109
+ if (tok.type !== CircuitScriptLexer.NEWLINE &&
110
+ tok.type !== CircuitScriptLexer.DEDENT &&
111
+ tok.type !== CircuitScriptLexer.INDENT) {
112
+ stopChar = tok.stop ?? stopChar;
113
+ break;
114
+ }
115
+ }
116
+ }
117
+ return stopChar;
118
+ }
@@ -0,0 +1,39 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from 'fs';
2
+ import { dirname, basename, join } from 'path';
3
+ import { CACHE_SCHEMA_VERSION } from './types.js';
4
+ export function getCachePath(libFilePath) {
5
+ const dir = dirname(libFilePath);
6
+ const base = basename(libFilePath);
7
+ return join(dir, '.cst.cache', `${base}.json`);
8
+ }
9
+ export function readCache(libFilePath, hash) {
10
+ try {
11
+ const cachePath = getCachePath(libFilePath);
12
+ if (!existsSync(cachePath)) {
13
+ return null;
14
+ }
15
+ const raw = readFileSync(cachePath, 'utf8');
16
+ const ir = JSON.parse(raw);
17
+ if (ir.schemaVersion !== CACHE_SCHEMA_VERSION || ir.contentHash !== hash) {
18
+ return null;
19
+ }
20
+ return ir;
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ export function writeCache(libFilePath, hash, ir) {
27
+ try {
28
+ const cachePath = getCachePath(libFilePath);
29
+ const cacheDir = dirname(cachePath);
30
+ if (!existsSync(cacheDir)) {
31
+ mkdirSync(cacheDir, { recursive: true });
32
+ }
33
+ const tmp = cachePath + '.tmp';
34
+ writeFileSync(tmp, JSON.stringify(ir), 'utf8');
35
+ renameSync(tmp, cachePath);
36
+ }
37
+ catch {
38
+ }
39
+ }
@@ -0,0 +1 @@
1
+ export const CACHE_SCHEMA_VERSION = 3;
@@ -2,8 +2,8 @@ import { registerWindow, SVG } from "@svgdotjs/svg.js";
2
2
  import fs from 'fs';
3
3
  import path from "path";
4
4
  import CryptoJs from "crypto-js";
5
- import { TOOL_VERSION } from "./globals.js";
6
- import { RuntimeExecutionError } from "./utils.js";
5
+ import { TOOL_VERSION } from "../globals.js";
6
+ import { RuntimeExecutionError } from "../utils.js";
7
7
  export class NodeScriptEnvironment {
8
8
  existsSync(pathLike) {
9
9
  return fs.existsSync(pathLike);
@@ -53,14 +53,15 @@ export class NodeScriptEnvironment {
53
53
  return this.useModuleDirectoryPath;
54
54
  }
55
55
  if (typeof __dirname !== 'undefined') {
56
- return __dirname;
56
+ return path.resolve(__dirname + "/../");
57
57
  }
58
58
  const stackLine = new Error().stack?.split('\n')[1];
59
59
  if (stackLine) {
60
60
  const fileMatch = stackLine.match(/\((.+)\:[\d]+\:[\d]+\)/);
61
61
  if (fileMatch) {
62
62
  const filePath = fileMatch[1].replace('file://', '');
63
- return path.dirname(filePath);
63
+ const finalPath = path.resolve(path.dirname(filePath) + "/../");
64
+ return finalPath;
64
65
  }
65
66
  }
66
67
  throw new RuntimeExecutionError("Failed to get current module directory");
@@ -128,7 +129,15 @@ export class NodeScriptEnvironment {
128
129
  return path.resolve(filePath);
129
130
  }
130
131
  getDirPath(filePath) {
131
- return path.dirname(path.resolve(filePath));
132
+ const resolved = path.resolve(filePath);
133
+ try {
134
+ if (fs.statSync(resolved).isDirectory()) {
135
+ return resolved;
136
+ }
137
+ }
138
+ catch {
139
+ }
140
+ return path.dirname(resolved);
132
141
  }
133
142
  setCurrentFile(filePath) {
134
143
  this.currentFile = this.getAbsolutePath(filePath);
@@ -137,7 +146,7 @@ export class NodeScriptEnvironment {
137
146
  getCurrentFile() {
138
147
  return this.currentFile;
139
148
  }
140
- getRelativeToCurrentFolder(filePath) {
149
+ getAbsPathRelativeToCurrentFolder(filePath) {
141
150
  return path.join(this.getDirPath(this.currentFile), filePath);
142
151
  }
143
152
  async exists(path) {
@@ -170,4 +179,7 @@ export class NodeScriptEnvironment {
170
179
  createWriteStream(filePath) {
171
180
  return fs.createWriteStream(filePath);
172
181
  }
182
+ getCurrentDirectory() {
183
+ return process.cwd();
184
+ }
173
185
  }
@@ -0,0 +1,17 @@
1
+ import { config, createSVGWindow } from 'svgdom';
2
+ import { NodeScriptEnvironment } from './environment';
3
+ export class ESMNodeScriptEnvironment extends NodeScriptEnvironment {
4
+ async prepareSVGEnvironmentInternal(fontsPath) {
5
+ try {
6
+ this.globalCreateSVGWindow = createSVGWindow;
7
+ if (fontsPath !== null) {
8
+ await config.setFontDir(fontsPath)
9
+ .setFontFamilyMappings(this.supportedFonts)
10
+ .preloadFonts();
11
+ }
12
+ }
13
+ catch (error) {
14
+ throw new Error(`Failed to load svgdom ESM module: ${error}`);
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,4 @@
1
+ import { ESMNodeScriptEnvironment } from "./esm-environment";
2
+ export function getNewEnvironment() {
3
+ return new ESMNodeScriptEnvironment();
4
+ }
@@ -7,9 +7,9 @@ import { PinId, PortSide } from './objects/PinDefinition.js';
7
7
  import { AnyReference, CFunctionEntry, DeclaredReference, Direction, ImportFunctionHandling, NetTypes } from './objects/types.js';
8
8
  import { Wire } from './objects/Wire.js';
9
9
  import { Frame } from './objects/Frame.js';
10
- import { CalculatePinPositions } from './layout.js';
10
+ import { CalculatePinPositions } from './render/layout.js';
11
11
  import { UnitDimension } from './helpers.js';
12
- import { PlaceHolderCommands, SymbolDrawingCommands } from './draw_symbols.js';
12
+ import { PlaceHolderCommands, SymbolDrawingCommands } from './render/draw_symbols.js';
13
13
  import { getBlockTypeString, RuntimeExecutionError } from './utils.js';
14
14
  export class ExecutionContext {
15
15
  name;
@@ -620,10 +620,36 @@ export class ExecutionContext {
620
620
  return this.scope.breakStack[this.scope.breakStack.length - 1];
621
621
  }
622
622
  createFunction(namespace, functionName, __runFunc, source, uniqueId) {
623
- const functionPath = `${namespace}${functionName}`;
624
- this.scope.functions.set(functionPath, new CFunctionEntry(namespace, functionName, __runFunc, source, uniqueId));
623
+ const functionEntry = new CFunctionEntry(namespace, functionName, __runFunc, source, uniqueId);
624
+ const functionPath = functionEntry.getFunctionPath();
625
+ if (this.scope.functions.has(functionPath)) {
626
+ this.log(`function: ${functionPath} already exists`);
627
+ const existingEntry = this.scope.functions.get(functionPath);
628
+ if (existingEntry.lazyLoaded) {
629
+ this.log(`updating lazy function: ${functionPath}`);
630
+ existingEntry.execute = __runFunc;
631
+ existingEntry.source = source;
632
+ }
633
+ else {
634
+ this.log(`function is already defined: ${functionName}`);
635
+ console.log(`WARNING: function is already defined ${functionName}`);
636
+ }
637
+ }
638
+ else {
639
+ this.scope.functions.set(functionPath, functionEntry);
640
+ this.log(`defined new function: ${functionPath}`);
641
+ }
625
642
  this.__functionCache.set(functionPath, __runFunc);
626
- this.log(`defined new function: ${functionPath}`);
643
+ return functionEntry;
644
+ }
645
+ createFunctionLazyLoaded(namespace, functionName, uniqueId) {
646
+ const functionEntry = new CFunctionEntry(namespace, functionName, null, null, uniqueId);
647
+ const functionPath = functionEntry.getFunctionPath();
648
+ functionEntry.lazyLoaded = true;
649
+ this.scope.functions.set(functionPath, functionEntry);
650
+ this.__functionCache.set(functionPath, null);
651
+ this.log(`defined new function with lazy flag: ${functionPath}`);
652
+ return functionEntry;
627
653
  }
628
654
  hasFunction(functionName) {
629
655
  return this.scope.functions.has(functionName);
@@ -653,11 +679,11 @@ export class ExecutionContext {
653
679
  && library.specifiedImports.indexOf(idName) !== -1)) {
654
680
  const { context: libraryContext } = library;
655
681
  const functionPath = `${libraryContext.namespace}${idName}`;
656
- if (library.context.hasFunction(functionPath)) {
682
+ if (libraryContext.hasFunction(functionPath)) {
657
683
  return new DeclaredReference({
658
684
  found: true,
659
685
  rootValue: library,
660
- value: library.context.getFunction(functionPath),
686
+ value: libraryContext.getFunction(functionPath),
661
687
  type: ReferenceTypes.function,
662
688
  name: idName,
663
689
  trailerIndex: 1,
@@ -764,7 +790,14 @@ export class ExecutionContext {
764
790
  }
765
791
  callFunction(functionReference, functionParams, executionStack, netNamespace) {
766
792
  const functionEntry = functionReference.value;
767
- const { name: functionName, execute: __runFunc } = functionEntry;
793
+ const { name: functionName } = functionEntry;
794
+ let { execute: __runFunc } = functionEntry;
795
+ if (__runFunc === null && functionEntry.lazyLoaded) {
796
+ this.log(`load lazy function: ${functionEntry.getFunctionPath()}`);
797
+ functionEntry.lazyLoader !== null && functionEntry.lazyLoader();
798
+ this.log(`done loading lazy function: ${functionEntry.getFunctionPath()}, replacing execute method`);
799
+ __runFunc = functionEntry.execute;
800
+ }
768
801
  if (__runFunc !== null) {
769
802
  let functionCallIndex = -1;
770
803
  if (!this.scope.functionCounter.has(__runFunc)) {
@@ -946,7 +979,7 @@ export class ExecutionContext {
946
979
  [numeric(1), numeric(0), numeric(0),
947
980
  numeric(0), numeric(0)],
948
981
  new Map([
949
- ["display_pin_id", false]
982
+ ["display_id", false]
950
983
  ]),
951
984
  null
952
985
  ]
@@ -1082,8 +1115,9 @@ export class ExecutionContext {
1082
1115
  if (targetAngle === null) {
1083
1116
  return;
1084
1117
  }
1085
- this.log('set component unit angle from wire, target angle:', targetAngle, ', component unit angle:', targetUnit.angleProp, 'pin angle:', connectedPinPos.angle);
1086
- let useAngle = (targetAngle - connectedPinPos.angle.toNumber()) % 360;
1118
+ const pinAngle = connectedPinPos.angle.toNumber();
1119
+ this.log('set component unit angle from wire, target angle:', targetAngle, ', component unit angle:', targetUnit.angleProp, 'pin angle:', pinAngle);
1120
+ let useAngle = (targetAngle - pinAngle) % 360;
1087
1121
  if (useAngle < 0) {
1088
1122
  useAngle += 360;
1089
1123
  }
@@ -1091,12 +1125,12 @@ export class ExecutionContext {
1091
1125
  targetUnit.setParam(ParamKeys.angle, numeric(90));
1092
1126
  }
1093
1127
  else if (useAngle === 180) {
1094
- if (targetUnit.angleProp === 0 || targetUnit.angleProp === 180) {
1095
- targetUnit.setParam(ParamKeys.flipX, numeric(1));
1096
- }
1097
- else if (targetUnit.angleProp === 90 || targetUnit.angleProp === 270) {
1128
+ if (pinAngle == 90 || pinAngle == 270) {
1098
1129
  targetUnit.setParam(ParamKeys.flipY, numeric(1));
1099
1130
  }
1131
+ else if (pinAngle == 0 || pinAngle == 180) {
1132
+ targetUnit.setParam(ParamKeys.flipX, numeric(1));
1133
+ }
1100
1134
  }
1101
1135
  else if (useAngle === 270) {
1102
1136
  targetUnit.setParam(ParamKeys.angle, numeric(270));
@@ -1,4 +1,5 @@
1
1
  import { numeric } from "./objects/ParamDefinition.js";
2
+ import { PinTypes } from "./objects/PinTypes.js";
2
3
  export const TOOL_VERSION = '0.1.5';
3
4
  export const Delimiter1 = '-';
4
5
  export const DoubleDelimiter1 = `${Delimiter1}${Delimiter1}`;
@@ -131,3 +132,10 @@ export const RenderFlags = {
131
132
  export const SymbolValidatorContext = '_sym';
132
133
  export const TrailerArrayIndex = 'index';
133
134
  export const DefaultComponentUnit = '__default';
135
+ export const PinTypesList = [
136
+ PinTypes.Any,
137
+ PinTypes.Input,
138
+ PinTypes.Output,
139
+ PinTypes.IO,
140
+ PinTypes.Power,
141
+ ];