circuitscript 0.1.29 → 0.1.31

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 (42) hide show
  1. package/dist/cjs/BaseVisitor.js +150 -21
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +241 -236
  3. package/dist/cjs/antlr/CircuitScriptParser.js +568 -431
  4. package/dist/cjs/builtinMethods.js +6 -2
  5. package/dist/cjs/environment.js +4 -0
  6. package/dist/cjs/execute.js +88 -57
  7. package/dist/cjs/globals.js +4 -1
  8. package/dist/cjs/helpers.js +6 -2
  9. package/dist/cjs/objects/ExecutionScope.js +9 -0
  10. package/dist/cjs/objects/types.js +21 -2
  11. package/dist/cjs/parser.js +6 -2
  12. package/dist/cjs/validate/SymbolTable.js +7 -1
  13. package/dist/cjs/validate/SymbolValidatorVisitor.js +54 -7
  14. package/dist/cjs/visitor.js +15 -47
  15. package/dist/esm/BaseVisitor.js +152 -23
  16. package/dist/esm/antlr/CircuitScriptLexer.js +241 -236
  17. package/dist/esm/antlr/CircuitScriptParser.js +567 -429
  18. package/dist/esm/antlr/CircuitScriptVisitor.js +3 -1
  19. package/dist/esm/builtinMethods.js +7 -3
  20. package/dist/esm/environment.js +4 -0
  21. package/dist/esm/execute.js +89 -58
  22. package/dist/esm/globals.js +2 -0
  23. package/dist/esm/helpers.js +6 -2
  24. package/dist/esm/objects/ExecutionScope.js +9 -0
  25. package/dist/esm/objects/types.js +27 -1
  26. package/dist/esm/parser.js +6 -2
  27. package/dist/esm/validate/SymbolTable.js +5 -0
  28. package/dist/esm/validate/SymbolValidatorVisitor.js +53 -6
  29. package/dist/esm/visitor.js +16 -45
  30. package/dist/types/BaseVisitor.d.ts +12 -5
  31. package/dist/types/antlr/CircuitScriptLexer.d.ts +43 -42
  32. package/dist/types/antlr/CircuitScriptParser.d.ts +71 -45
  33. package/dist/types/antlr/CircuitScriptVisitor.d.ts +6 -2
  34. package/dist/types/environment.d.ts +1 -0
  35. package/dist/types/execute.d.ts +2 -2
  36. package/dist/types/globals.d.ts +2 -0
  37. package/dist/types/objects/ExecutionScope.d.ts +3 -1
  38. package/dist/types/objects/types.d.ts +22 -1
  39. package/dist/types/validate/SymbolTable.d.ts +1 -0
  40. package/dist/types/validate/SymbolValidatorVisitor.d.ts +6 -2
  41. package/dist/types/visitor.d.ts +3 -1
  42. package/package.json +4 -1
@@ -72,7 +72,9 @@ export class CircuitScriptVisitor extends AbstractParseTreeVisitor {
72
72
  visitWire_expr;
73
73
  visitArray_expr;
74
74
  visitPoint_expr;
75
- visitImport_expr;
75
+ visitImport_simple;
76
+ visitImport_all_simple;
77
+ visitImport_specific;
76
78
  visitFrame_expr;
77
79
  visitIf_expr;
78
80
  visitIf_inner_expr;
@@ -1,7 +1,8 @@
1
1
  import Big from "big.js";
2
2
  import { numeric, NumericValue } from "./objects/ParamDefinition.js";
3
- import { CFunctionEntry } from "./objects/types.js";
3
+ import { CFunctionEntry, ImportedModule } from "./objects/types.js";
4
4
  import { unwrapValue, resolveToNumericValue, RuntimeExecutionError } from "./utils.js";
5
+ import { BaseNamespace } from "./globals.js";
5
6
  const builtInMethods = [
6
7
  ['enumerate', enumerate],
7
8
  ['toMils', toMils],
@@ -14,7 +15,7 @@ const builtInMethods = [
14
15
  ];
15
16
  export const buildInMethodNamesList = builtInMethods.map(item => item[0]);
16
17
  export function linkBuiltInMethods(context, visitor) {
17
- context.createFunction('print', (params) => {
18
+ context.createFunction(BaseNamespace, 'print', (params) => {
18
19
  const args = getPositionParams(params);
19
20
  const items = args.map(item => {
20
21
  return toString(unwrapValue(item));
@@ -28,7 +29,7 @@ export function linkBuiltInMethods(context, visitor) {
28
29
  });
29
30
  builtInMethods.forEach(([functionName, functionImpl]) => {
30
31
  if (functionImpl !== null) {
31
- context.createFunction(functionName, params => {
32
+ context.createFunction(BaseNamespace, functionName, params => {
32
33
  const args = getPositionParams(params);
33
34
  const functionReturn = functionImpl(...args);
34
35
  return [visitor, functionReturn];
@@ -148,6 +149,9 @@ function toString(obj) {
148
149
  else if (obj instanceof CFunctionEntry) {
149
150
  return obj.toString();
150
151
  }
152
+ else if (obj instanceof ImportedModule) {
153
+ return `[module: ${obj.moduleName}]`;
154
+ }
151
155
  else {
152
156
  if (obj === undefined) {
153
157
  return 'undefined';
@@ -1,6 +1,7 @@
1
1
  import { registerWindow, SVG } from "@svgdotjs/svg.js";
2
2
  import fs from 'fs';
3
3
  import path from "path";
4
+ import CryptoJs from "crypto-js";
4
5
  import { TOOL_VERSION } from "./globals.js";
5
6
  import { RuntimeExecutionError } from "./utils.js";
6
7
  export class NodeScriptEnvironment {
@@ -138,4 +139,7 @@ export class NodeScriptEnvironment {
138
139
  return false;
139
140
  }
140
141
  }
142
+ hashStringSHA256(value) {
143
+ return CryptoJs.SHA256(value).toString();
144
+ }
141
145
  }
@@ -4,7 +4,7 @@ import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './obj
4
4
  import { Net } from './objects/Net.js';
5
5
  import { numeric, NumericValue } from './objects/ParamDefinition.js';
6
6
  import { PinId, PortSide } from './objects/PinDefinition.js';
7
- import { AnyReference, CFunctionEntry, DeclaredReference, Direction, NetTypes } from './objects/types.js';
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
10
  import { CalculatePinPositions } from './layout.js';
@@ -39,7 +39,7 @@ export class ExecutionContext {
39
39
  this.scope.scopeLevel = scopeLevel;
40
40
  this.setupRoot();
41
41
  this.silent = silent;
42
- this.log('create new execution context', this.namespace, this.name, this.scope.scopeLevel);
42
+ this.log(`create new execution context, namespace: ${this.namespace}, name: ${this.name}, level: ${this.scope.scopeLevel}`);
43
43
  this.parentContext = parent;
44
44
  this.warnings = warnings;
45
45
  }
@@ -591,10 +591,11 @@ export class ExecutionContext {
591
591
  getBreakContext() {
592
592
  return this.scope.breakStack[this.scope.breakStack.length - 1];
593
593
  }
594
- createFunction(functionName, __runFunc, source, uniqueId) {
595
- this.scope.functions.set(functionName, new CFunctionEntry(functionName, __runFunc, source, uniqueId));
596
- this.__functionCache.set(functionName, __runFunc);
597
- this.log(`defined new function '${functionName}'`);
594
+ createFunction(namespace, functionName, __runFunc, source, uniqueId) {
595
+ const functionPath = `${namespace}${functionName}`;
596
+ this.scope.functions.set(functionPath, new CFunctionEntry(namespace, functionName, __runFunc, source, uniqueId));
597
+ this.__functionCache.set(functionPath, __runFunc);
598
+ this.log(`defined new function: ${functionPath}`);
598
599
  }
599
600
  hasFunction(functionName) {
600
601
  return this.scope.functions.has(functionName);
@@ -603,32 +604,63 @@ export class ExecutionContext {
603
604
  return this.scope.functions.get(functionName);
604
605
  }
605
606
  resolveVariable(executionStack, idName, trailers = []) {
607
+ this.log('resolve variable name:', idName, 'trailers:', trailers);
606
608
  const reversed = [...executionStack].reverse();
607
609
  for (let i = 0; i < reversed.length; i++) {
608
610
  const context = reversed[i];
609
- if (context.hasFunction(idName)) {
611
+ const functionPath = `${context.namespace}${idName}`;
612
+ if (context.hasFunction(functionPath)) {
610
613
  return new DeclaredReference({
611
614
  found: true,
612
- value: context.getFunction(idName),
615
+ value: context.getFunction(functionPath),
613
616
  type: ReferenceTypes.function,
614
617
  name: idName,
615
618
  });
616
619
  }
617
620
  else {
621
+ const modules = Array.from(context.scope.modules.values());
622
+ for (let j = 0; j < modules.length; j++) {
623
+ const module = modules[j];
624
+ if (module.importHandlingFlag === ImportFunctionHandling.AllMergeIntoNamespace ||
625
+ (module.importHandlingFlag === ImportFunctionHandling.SpecificMergeIntoNamespace
626
+ && module.specifiedImports.indexOf(idName) !== -1)) {
627
+ const moduleContext = module.context;
628
+ const functionPath = `${moduleContext.namespace}${idName}`;
629
+ if (module.context.hasFunction(functionPath)) {
630
+ return new DeclaredReference({
631
+ found: true,
632
+ rootValue: module,
633
+ value: module.context.getFunction(functionPath),
634
+ type: ReferenceTypes.function,
635
+ name: idName,
636
+ trailerIndex: 1,
637
+ trailers: [idName],
638
+ });
639
+ }
640
+ }
641
+ }
642
+ let isModule = false;
643
+ if (context.scope.modules.has(idName)) {
644
+ const module = context.scope.modules.get(idName);
645
+ if (module.importHandlingFlag === ImportFunctionHandling.AllWithNamespace) {
646
+ isModule = true;
647
+ }
648
+ }
618
649
  let isVariable = context.scope.variables.has(idName);
619
650
  let isComponentInstance = context.scope.instances.has(idName);
620
- if (isVariable || isComponentInstance) {
621
- const scopeList = isVariable ? context.scope.variables
622
- : context.scope.instances;
651
+ if (isModule || isVariable || isComponentInstance) {
652
+ const scopeList = isModule ? context.scope.modules :
653
+ (isVariable ? context.scope.variables : context.scope.instances);
623
654
  const useValue = scopeList.get(idName);
624
655
  if (!isComponentInstance && (useValue instanceof ClassComponent)) {
625
656
  isComponentInstance = true;
626
657
  isVariable = false;
627
658
  }
628
- const tmpReference = this.resolveTrailers(isVariable ? ReferenceTypes.variable : ReferenceTypes.instance, useValue, trailers);
659
+ const referenceType = isModule ? ReferenceTypes.module :
660
+ (isVariable ? ReferenceTypes.variable : ReferenceTypes.instance);
661
+ const tmpReference = this.resolveTrailers(referenceType, useValue, trailers);
629
662
  return new DeclaredReference({
630
- type: isVariable ? ReferenceTypes.variable
631
- : ReferenceTypes.instance,
663
+ type: referenceType,
632
664
  found: (tmpReference.value !== undefined),
633
665
  rootValue: tmpReference.rootValue,
634
666
  value: tmpReference.value,
@@ -649,65 +681,63 @@ export class ExecutionContext {
649
681
  if (trailers.length > 0) {
650
682
  rootValue = useValue;
651
683
  const trailersPath = trailers.join(".");
652
- if (type === ReferenceTypes.variable) {
653
- useValue = rootValue;
654
- trailers.forEach(trailerPath => {
655
- useValue = useValue[trailerPath];
656
- });
657
- }
658
- else if (type === ReferenceTypes.instance) {
659
- const tmpComponent = rootValue;
660
- if (tmpComponent.typeProp === ComponentTypes.net) {
661
- const usedNet = this.scope.getNet(tmpComponent, new PinId(1));
662
- if (usedNet) {
663
- const trailerValue = trailers.join(".");
664
- useValue = usedNet.params.get(trailerValue) ?? null;
684
+ switch (type) {
685
+ case ReferenceTypes.variable:
686
+ useValue = rootValue;
687
+ trailers.forEach(trailerPath => {
688
+ useValue = useValue[trailerPath];
689
+ });
690
+ break;
691
+ case ReferenceTypes.instance: {
692
+ const tmpComponent = rootValue;
693
+ if (tmpComponent.typeProp === ComponentTypes.net) {
694
+ const usedNet = this.scope.getNet(tmpComponent, new PinId(1));
695
+ if (usedNet) {
696
+ const trailerValue = trailers.join(".");
697
+ useValue = usedNet.params.get(trailerValue) ?? null;
698
+ }
699
+ }
700
+ else {
701
+ useValue = rootValue
702
+ .parameters.get(trailersPath);
665
703
  }
704
+ break;
666
705
  }
667
- else {
668
- useValue = rootValue
669
- .parameters.get(trailersPath);
706
+ case ReferenceTypes.module: {
707
+ const funcName = trailers[0];
708
+ const module = rootValue;
709
+ const functionPath = `${module.moduleNamespace}${funcName}`;
710
+ if (module.context.hasFunction(functionPath)) {
711
+ const foundFunc = module.context.getFunction(functionPath);
712
+ return new AnyReference({
713
+ found: true,
714
+ type: ReferenceTypes.function,
715
+ rootValue,
716
+ trailers,
717
+ trailerIndex: trailers.length,
718
+ value: foundFunc,
719
+ });
720
+ }
721
+ break;
670
722
  }
671
723
  }
672
724
  }
673
725
  let found = false;
674
- if (rootValue !== undefined && useValue !== undefined) {
726
+ if (useValue !== undefined) {
675
727
  found = true;
676
728
  }
677
729
  return new AnyReference({
678
730
  found,
679
- type: type,
731
+ type,
680
732
  rootValue,
681
733
  trailers,
682
734
  trailerIndex: trailers.length,
683
735
  value: useValue,
684
736
  });
685
737
  }
686
- callFunction(functionName, functionParams, executionStack, netNamespace) {
687
- let __runFunc = null;
688
- if (!this.__functionCache.has(functionName)) {
689
- if (this.hasFunction(functionName)) {
690
- const entry = this.getFunction(functionName);
691
- __runFunc = entry.execute;
692
- }
693
- if (__runFunc === null) {
694
- this.log(`searching for function ${functionName} in upper context`);
695
- const tmpResolveResult = this.resolveVariable(executionStack, functionName);
696
- if (tmpResolveResult.found) {
697
- const entry = tmpResolveResult.value;
698
- __runFunc = entry.execute;
699
- }
700
- else {
701
- throw `Invalid function ${functionName}`;
702
- }
703
- }
704
- this.log('save function to cache:', functionName);
705
- this.__functionCache.set(functionName, __runFunc);
706
- }
707
- else {
708
- this.log('found function in cache:', functionName);
709
- __runFunc = this.__functionCache.get(functionName);
710
- }
738
+ callFunction(functionReference, functionParams, executionStack, netNamespace) {
739
+ const functionEntry = functionReference.value;
740
+ const { name: functionName, execute: __runFunc } = functionEntry;
711
741
  if (__runFunc !== null) {
712
742
  let functionCallIndex = -1;
713
743
  if (!this.scope.functionCounter.has(__runFunc)) {
@@ -725,6 +755,7 @@ export class ExecutionContext {
725
755
  return functionResult;
726
756
  }
727
757
  else {
758
+ this.log(`Invalid function: ${functionName}`);
728
759
  throw `Invalid function '${functionName}'`;
729
760
  }
730
761
  }
@@ -735,7 +766,7 @@ export class ExecutionContext {
735
766
  const tmpNets = childScope.getNets();
736
767
  const mergedInstances = [];
737
768
  for (const [instanceName, component] of tmpInstances) {
738
- const newInstanceName = `${namespace}.${instanceName}`;
769
+ const newInstanceName = namespace !== "" ? `${namespace}.${instanceName}` : instanceName;
739
770
  component.instanceName = newInstanceName;
740
771
  if (component === childScope.componentRoot) {
741
772
  continue;
@@ -2,6 +2,7 @@ import { numeric } from "./objects/ParamDefinition.js";
2
2
  export const TOOL_VERSION = '0.1.5';
3
3
  export const Delimiter1 = '-';
4
4
  export const DoubleDelimiter1 = `${Delimiter1}${Delimiter1}`;
5
+ export const BaseNamespace = `${DoubleDelimiter1}.`;
5
6
  export var GlobalNames;
6
7
  (function (GlobalNames) {
7
8
  GlobalNames["__root"] = "--root";
@@ -93,6 +94,7 @@ export var ReferenceTypes;
93
94
  ReferenceTypes["variable"] = "variable";
94
95
  ReferenceTypes["instance"] = "instance";
95
96
  ReferenceTypes["pinType"] = "pinType";
97
+ ReferenceTypes["module"] = "module";
96
98
  ReferenceTypes["unknown"] = "unknown";
97
99
  })(ReferenceTypes || (ReferenceTypes = {}));
98
100
  export var BlockTypes;
@@ -206,9 +206,13 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
206
206
  environment.setCurrentFile(inputPath);
207
207
  const visitor = new ParserVisitor(true, onErrorHandler, environment);
208
208
  visitor.onImportFile = async (visitor, filePath, fileData) => {
209
- const { hasError, hasParseError } = await parseFileWithVisitor(visitor, fileData);
209
+ const { hasError, hasParseError, throwError } = await parseFileWithVisitor(visitor, fileData);
210
210
  if (hasError || hasParseError) {
211
- throw new ParseError(`Error parsing imported file: ${filePath}`, undefined, undefined, filePath);
211
+ let importErrorMsg = "";
212
+ if (throwError) {
213
+ importErrorMsg = ": " + throwError.message;
214
+ }
215
+ throw new ParseError(`Error parsing imported file: ${filePath}${importErrorMsg}`, undefined, undefined, filePath);
212
216
  }
213
217
  return { hasError, hasParseError };
214
218
  };
@@ -9,6 +9,7 @@ export class ExecutionScope {
9
9
  functionCounter = new Map();
10
10
  variables = new Map();
11
11
  symbols = new Map();
12
+ modules = new Map();
12
13
  blockStack = new Map();
13
14
  contextStack = [];
14
15
  onPropertyHandler = [];
@@ -168,6 +169,14 @@ export class ExecutionScope {
168
169
  getInstances() {
169
170
  return Array.from(this.instances.values());
170
171
  }
172
+ copyTo(scope) {
173
+ this.functions.forEach((value, key) => {
174
+ scope.functions.set(key, value);
175
+ });
176
+ this.variables.forEach((value, key) => {
177
+ scope.variables.set(key, value);
178
+ });
179
+ }
171
180
  }
172
181
  export var SequenceAction;
173
182
  (function (SequenceAction) {
@@ -2,11 +2,15 @@ import { ReferenceTypes } from '../globals.js';
2
2
  import { RuntimeExecutionError } from '../utils.js';
3
3
  export class CFunctionEntry {
4
4
  name;
5
+ namespace;
6
+ originalNamespace;
5
7
  execute;
6
8
  uniqueId;
7
9
  source;
8
- constructor(name, execute, source, uniqueId) {
10
+ constructor(namespace, name, execute, source, uniqueId) {
9
11
  this.name = name;
12
+ this.namespace = namespace;
13
+ this.originalNamespace = namespace;
10
14
  this.execute = execute;
11
15
  this.uniqueId = uniqueId;
12
16
  this.source = source;
@@ -124,3 +128,25 @@ export var NetTypes;
124
128
  NetTypes["Any"] = "any";
125
129
  NetTypes["Source"] = "source";
126
130
  })(NetTypes || (NetTypes = {}));
131
+ export class ImportedModule {
132
+ moduleName;
133
+ context;
134
+ importHandlingFlag;
135
+ specifiedImports;
136
+ moduleNamespace;
137
+ moduleFilePath;
138
+ constructor(moduleName, moduleNamespace, moduleFilePath, context, flag, specifiedImports) {
139
+ this.moduleName = moduleName;
140
+ this.moduleNamespace = moduleNamespace;
141
+ this.moduleFilePath = moduleFilePath;
142
+ this.context = context;
143
+ this.importHandlingFlag = flag;
144
+ this.specifiedImports = specifiedImports;
145
+ }
146
+ }
147
+ export var ImportFunctionHandling;
148
+ (function (ImportFunctionHandling) {
149
+ ImportFunctionHandling["AllWithNamespace"] = "all-with-namespace";
150
+ ImportFunctionHandling["AllMergeIntoNamespace"] = "all-merge-into-namespace";
151
+ ImportFunctionHandling["SpecificMergeIntoNamespace"] = "specific-merge-into-namespace";
152
+ })(ImportFunctionHandling || (ImportFunctionHandling = {}));
@@ -19,6 +19,8 @@ export async function parseFileWithVisitor(visitor, data) {
19
19
  parser.addErrorListener(parserErrorListener);
20
20
  const tree = parser.script();
21
21
  let throwError;
22
+ let hasError = false;
23
+ let hasParseError = false;
22
24
  try {
23
25
  await visitor.visitAsync(tree);
24
26
  }
@@ -31,13 +33,15 @@ export async function parseFileWithVisitor(visitor, data) {
31
33
  throwError = error;
32
34
  }
33
35
  }
36
+ hasError = true;
37
+ hasParseError = true;
34
38
  }
35
39
  const parserTimeTaken = parserTimer.lap();
36
40
  return {
37
41
  tree, parser,
38
42
  tokens,
39
- hasParseError: false,
40
- hasError: false,
43
+ hasParseError,
44
+ hasError,
41
45
  parserTimeTaken,
42
46
  lexerTimeTaken,
43
47
  throwError
@@ -88,3 +88,8 @@ export class SymbolTable {
88
88
  }
89
89
  }
90
90
  }
91
+ export function cloneSymbol(symbol) {
92
+ return {
93
+ ...symbol
94
+ };
95
+ }
@@ -1,8 +1,10 @@
1
+ import { Import_specificContext } from "../antlr/CircuitScriptParser.js";
1
2
  import { buildInMethodNamesList } from "../builtinMethods.js";
2
- import { ParseSymbolType } from "../objects/types.js";
3
+ import { ImportFunctionHandling, ParseSymbolType } from "../objects/types.js";
4
+ import { cloneSymbol } from "./SymbolTable.js";
3
5
  import { SymbolTable } from "./SymbolTable.js";
4
6
  import { BaseVisitor } from "../BaseVisitor.js";
5
- import { SymbolValidatorContext } from "../globals.js";
7
+ import { BaseNamespace, SymbolValidatorContext } from "../globals.js";
6
8
  export class SymbolValidatorVisitor extends BaseVisitor {
7
9
  symbolTable = new SymbolTable();
8
10
  filePathStack = [];
@@ -62,13 +64,58 @@ export class SymbolValidatorVisitor extends BaseVisitor {
62
64
  setSymbols(symbolTable) {
63
65
  this.symbolTable = symbolTable;
64
66
  }
65
- visitImport_expr = (ctx) => {
66
- const ID = ctx.ID().toString();
67
- const { pathExists } = this.handleImportFile(ID, false, ctx);
67
+ async importCommon(ctx, handling) {
68
+ const specifiedImports = [];
69
+ if (ctx instanceof Import_specificContext) {
70
+ const tmpImports = ctx._funcNames.map(item => {
71
+ return item.text;
72
+ });
73
+ specifiedImports.push(...tmpImports);
74
+ }
75
+ const id = ctx._moduleName.text;
76
+ const { pathExists, importedModule } = await this.handleImportFile(id, handling, true, ctx, specifiedImports);
68
77
  if (!pathExists) {
69
- this.symbolTable.addUndefined(this.getCurrentFile(), this.getExecutor(), ID, ctx.ID().getSymbol());
78
+ this.symbolTable.addUndefined(this.getCurrentFile(), this.getExecutor(), id, ctx._moduleName);
79
+ }
80
+ else {
81
+ this.applyModuleImports(importedModule);
70
82
  }
83
+ }
84
+ visitImport_simple = async (ctx) => {
85
+ await this.importCommon(ctx, ImportFunctionHandling.AllWithNamespace);
86
+ };
87
+ visitImport_all_simple = async (ctx) => {
88
+ await this.importCommon(ctx, ImportFunctionHandling.AllMergeIntoNamespace);
89
+ };
90
+ visitImport_specific = async (ctx) => {
91
+ await this.importCommon(ctx, ImportFunctionHandling.SpecificMergeIntoNamespace);
71
92
  };
93
+ applyModuleImports(module) {
94
+ const { importHandlingFlag: importHandling, specifiedImports } = module;
95
+ const addedSymbols = [];
96
+ const executor = this.getExecutor();
97
+ const symbolTable = this.symbolTable.getSymbols();
98
+ symbolTable.forEach((value, key) => {
99
+ if (value.type === ParseSymbolType.Function) {
100
+ const definedSymbol = value;
101
+ if (definedSymbol.fileName === module.moduleFilePath) {
102
+ const addSymbolToNamespace = importHandling === ImportFunctionHandling.AllMergeIntoNamespace
103
+ || (importHandling === ImportFunctionHandling.SpecificMergeIntoNamespace
104
+ && specifiedImports.indexOf(definedSymbol.id) !== -1);
105
+ if (addSymbolToNamespace) {
106
+ const funcPath = `${BaseNamespace}${definedSymbol.id}`;
107
+ const tmpSymbol = cloneSymbol(value);
108
+ tmpSymbol.context = executor;
109
+ addedSymbols.push([funcPath, tmpSymbol]);
110
+ }
111
+ }
112
+ }
113
+ });
114
+ addedSymbols.forEach(item => {
115
+ const [key, value] = item;
116
+ symbolTable.set(key, value);
117
+ });
118
+ }
72
119
  visitAssignment_expr = (ctx) => {
73
120
  const ctxDataExpr = ctx.data_expr();
74
121
  this.visit(ctxDataExpr);
@@ -13,6 +13,16 @@ import { FrameParamKeys } from './objects/Frame.js';
13
13
  import { ComponentAnnotater } from './ComponentAnnotater.js';
14
14
  import { applyPartConditions, extractPartConditions, flattenConditionNodes } from './ComponentMatchConditions.js';
15
15
  export class ParserVisitor extends BaseVisitor {
16
+ constructor(silent = false, onErrorHandler = null, environment) {
17
+ super(silent, onErrorHandler, environment);
18
+ if (environment) {
19
+ this.log('-- Environment --');
20
+ this.log('Module directory: ' + environment.getModuleDirectory());
21
+ this.log('Default libs path: ' + environment.getDefaultLibsPath());
22
+ this.log('Current file: ' + environment.getCurrentFile());
23
+ this.log('-----------------');
24
+ }
25
+ }
16
26
  componentCreationIndex = 0;
17
27
  creationCtx = new Map();
18
28
  visitKeyword_assignment_expr = (ctx) => {
@@ -685,10 +695,8 @@ export class ParserVisitor extends BaseVisitor {
685
695
  + component.instanceName
686
696
  + Delimiter1 + component.moduleCounter;
687
697
  const tmpNamespace = this.getNetNamespace(netNamespace, "+/" + component.instanceName + Delimiter1 + component.moduleCounter);
688
- const newExecutor = this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
698
+ this.enterNewChildContext(executionStack, executor, executionContextName, { netNamespace: tmpNamespace }, [], []);
689
699
  component.moduleCounter += 1;
690
- newExecutor.resolveNet = this.createNetResolver(executionStack);
691
- newExecutor.resolveComponentPinNet = this.createComponentPinNetResolver(executionStack);
692
700
  this.visit(component.moduleContainsExpressions);
693
701
  const executionContext = executionStack.pop();
694
702
  component.moduleExecutionContext = executionContext;
@@ -886,7 +894,7 @@ export class ParserVisitor extends BaseVisitor {
886
894
  visitFunction_def_expr = (ctx) => {
887
895
  const functionName = ctx.ID().getText();
888
896
  const uniqueFunctionID = '__._' + ctx.start.line + '_'
889
- + ctx.start.column + '_' + functionName + '_' + ctx.getText();
897
+ + ctx.start.column + '_' + functionName + '_' + this.environment.hashStringSHA256(ctx.getText());
890
898
  let funcDefinedParameters = [];
891
899
  const ctxFunctionArgsExpr = ctx.function_args_expr();
892
900
  if (ctxFunctionArgsExpr) {
@@ -898,54 +906,17 @@ export class ParserVisitor extends BaseVisitor {
898
906
  const resolveComponentPinNet = this.createComponentPinNetResolver(this.executionStack);
899
907
  const __runFunc = (passedInParameters, options) => {
900
908
  const executor = this.getExecutor();
901
- const parentBreakContext = executor.getParentBreakContext();
902
- executor.addBreakContext(ctx);
903
- let useIndex = -1;
904
- if (parentBreakContext === null) {
905
- useIndex = options.functionCallIndex;
906
- }
907
- else {
908
- const parentEntry = executor.indexedStack.get(parentBreakContext);
909
- const { funcCallIndex } = parentEntry;
910
- if (!funcCallIndex.has(ctx)) {
911
- funcCallIndex.set(ctx, 0);
912
- useIndex = 0;
913
- }
914
- else {
915
- useIndex = funcCallIndex.get(ctx) + 1;
916
- funcCallIndex.set(ctx, useIndex);
917
- }
918
- }
919
- executor.setBreakContextIndex(useIndex);
920
909
  const functionCounterIndex = functionCounter['counter'];
921
- const executionContextName = `${functionName}-${functionCounterIndex}`;
922
- const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
923
910
  functionCounter['counter'] += 1;
911
+ const executionContextName = `${functionName}-${functionCounterIndex}`;
912
+ const newExecutor = this.handleEnterContext(executor, executionStack, executionContextName, ctx, options, funcDefinedParameters, passedInParameters);
924
913
  newExecutor.resolveNet = resolveNet;
925
914
  newExecutor.resolveComponentPinNet = resolveComponentPinNet;
926
915
  const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
927
- const lastExecution = executionStack.pop();
928
- const nextLastExecution = executionStack[executionStack.length - 1];
929
- const mergedComponents = nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
930
- const scope = this.getScope();
931
- const indexedStack = [];
932
- if (scope.breakStack.length > 0) {
933
- const executor = this.getExecutor();
934
- scope.breakStack.forEach(stackCtx => {
935
- const entry = executor.indexedStack.get(stackCtx);
936
- const { index } = entry;
937
- indexedStack.push([stackCtx, index]);
938
- });
939
- mergedComponents.forEach(component => {
940
- component.ctxReferences.forEach(ref => {
941
- ref.indexedStack = [...indexedStack, ...ref.indexedStack];
942
- });
943
- });
944
- }
945
- executor.popBreakContext();
916
+ const lastExecution = this.handlePopContext(executor, executionStack, executionContextName);
946
917
  return [lastExecution, returnValue];
947
918
  };
948
- this.getExecutor().createFunction(functionName, __runFunc, ctx, uniqueFunctionID);
919
+ this.getExecutor().createFunction(this.getExecutor().namespace, functionName, __runFunc, ctx, uniqueFunctionID);
949
920
  };
950
921
  visitPin_select_expr2 = (ctx) => {
951
922
  const ctxStringValue = ctx.STRING_VALUE();