circuitscript 0.1.28 → 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 (45) hide show
  1. package/dist/cjs/BaseVisitor.js +155 -17
  2. package/dist/cjs/SemanticTokenVisitor.js +6 -0
  3. package/dist/cjs/antlr/CircuitScriptLexer.js +241 -236
  4. package/dist/cjs/antlr/CircuitScriptParser.js +568 -431
  5. package/dist/cjs/builtinMethods.js +6 -2
  6. package/dist/cjs/environment.js +21 -0
  7. package/dist/cjs/execute.js +90 -59
  8. package/dist/cjs/globals.js +4 -1
  9. package/dist/cjs/helpers.js +9 -4
  10. package/dist/cjs/objects/ExecutionScope.js +9 -0
  11. package/dist/cjs/objects/types.js +21 -2
  12. package/dist/cjs/parser.js +6 -2
  13. package/dist/cjs/validate/SymbolTable.js +7 -1
  14. package/dist/cjs/validate/SymbolValidatorVisitor.js +54 -7
  15. package/dist/cjs/visitor.js +15 -47
  16. package/dist/esm/BaseVisitor.js +157 -19
  17. package/dist/esm/SemanticTokenVisitor.js +6 -0
  18. package/dist/esm/antlr/CircuitScriptLexer.js +241 -236
  19. package/dist/esm/antlr/CircuitScriptParser.js +567 -429
  20. package/dist/esm/antlr/CircuitScriptVisitor.js +3 -1
  21. package/dist/esm/builtinMethods.js +7 -3
  22. package/dist/esm/environment.js +21 -0
  23. package/dist/esm/execute.js +91 -60
  24. package/dist/esm/globals.js +2 -0
  25. package/dist/esm/helpers.js +9 -4
  26. package/dist/esm/objects/ExecutionScope.js +9 -0
  27. package/dist/esm/objects/types.js +27 -1
  28. package/dist/esm/parser.js +6 -2
  29. package/dist/esm/validate/SymbolTable.js +5 -0
  30. package/dist/esm/validate/SymbolValidatorVisitor.js +53 -6
  31. package/dist/esm/visitor.js +16 -45
  32. package/dist/types/BaseVisitor.d.ts +12 -5
  33. package/dist/types/SemanticTokenVisitor.d.ts +2 -1
  34. package/dist/types/antlr/CircuitScriptLexer.d.ts +43 -42
  35. package/dist/types/antlr/CircuitScriptParser.d.ts +71 -45
  36. package/dist/types/antlr/CircuitScriptVisitor.d.ts +6 -2
  37. package/dist/types/environment.d.ts +7 -0
  38. package/dist/types/execute.d.ts +2 -2
  39. package/dist/types/globals.d.ts +2 -0
  40. package/dist/types/objects/ExecutionScope.d.ts +3 -1
  41. package/dist/types/objects/types.d.ts +22 -1
  42. package/dist/types/validate/SymbolTable.d.ts +1 -0
  43. package/dist/types/validate/SymbolValidatorVisitor.d.ts +6 -2
  44. package/dist/types/visitor.d.ts +3 -1
  45. package/package.json +4 -1
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseVisitor = void 0;
4
4
  const big_js_1 = require("big.js");
5
+ const CircuitScriptParser_js_1 = require("./antlr/CircuitScriptParser.js");
5
6
  const CircuitScriptVisitor_js_1 = require("./antlr/CircuitScriptVisitor.js");
6
7
  const execute_js_1 = require("./execute.js");
7
8
  const logger_js_1 = require("./logger.js");
@@ -18,10 +19,10 @@ const PinDefinition_js_1 = require("./objects/PinDefinition.js");
18
19
  class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
19
20
  constructor(silent = false, onErrorHandler = null, environment) {
20
21
  super();
21
- this.indentLevel = 0;
22
22
  this.silent = false;
23
23
  this.printStream = [];
24
24
  this.printToConsole = true;
25
+ this.allowParseImports = false;
25
26
  this.acceptedDirections = [types_js_1.Direction.Up, types_js_1.Direction.Down,
26
27
  types_js_1.Direction.Right, types_js_1.Direction.Left];
27
28
  this.resultData = new Map;
@@ -41,17 +42,25 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
41
42
  };
42
43
  this.visitScript = async (ctx) => {
43
44
  this.log('===', 'start', '===');
44
- const imports = ctx.import_expr();
45
- for (let i = 0; i < imports.length; i++) {
46
- const ctxImport = imports[i];
47
- const ID = ctxImport.ID().toString();
48
- await this.handleImportFile(ID, true, ctxImport);
45
+ this.allowParseImports = true;
46
+ for (const ctxImport of ctx.import_expr()) {
47
+ await this.visit(ctxImport);
49
48
  }
49
+ this.allowParseImports = false;
50
50
  const result = this.runExpressions(this.getExecutor(), ctx.expression());
51
51
  this.setResult(ctx, result);
52
52
  this.getExecutor().closeOpenPathBlocks();
53
53
  this.log('===', 'end', '===');
54
54
  };
55
+ this.visitImport_simple = async (ctx) => {
56
+ await this.importCommon(ctx, types_js_1.ImportFunctionHandling.AllWithNamespace);
57
+ };
58
+ this.visitImport_all_simple = async (ctx) => {
59
+ await this.importCommon(ctx, types_js_1.ImportFunctionHandling.AllMergeIntoNamespace);
60
+ };
61
+ this.visitImport_specific = async (ctx) => {
62
+ await this.importCommon(ctx, types_js_1.ImportFunctionHandling.SpecificMergeIntoNamespace);
63
+ };
55
64
  this.visitAssignment_expr = (ctx) => {
56
65
  const ctxAtom = ctx.atom_expr();
57
66
  const ctxFuncCallRef = ctx.function_call_expr();
@@ -427,10 +436,11 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
427
436
  const innerResult = this.getResult(ctxDataExpr);
428
437
  this.setResult(ctx, innerResult);
429
438
  };
439
+ this.silent = silent;
430
440
  this.logger = new logger_js_1.Logger();
431
441
  this.onErrorHandler = onErrorHandler;
432
442
  this.environment = environment;
433
- this.startingContext = new execute_js_1.ExecutionContext(globals_js_1.DoubleDelimiter1, `${globals_js_1.DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, this.warnings, null);
443
+ this.startingContext = new execute_js_1.ExecutionContext(globals_js_1.DoubleDelimiter1, globals_js_1.BaseNamespace, '/', 0, 0, silent, this.logger, this.warnings, null);
434
444
  const scope = this.startingContext.scope;
435
445
  scope.sequence.push([
436
446
  ExecutionScope_js_1.SequenceAction.At, scope.componentRoot, scope.currentPin
@@ -492,8 +502,9 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
492
502
  };
493
503
  }
494
504
  log(...params) {
495
- const indentOutput = ''.padStart(this.indentLevel * 4, ' ');
496
- const indentLevelText = this.indentLevel.toString().padStart(3, ' ');
505
+ const indentLevel = this.getScope().scopeLevel;
506
+ const indentOutput = ''.padStart(indentLevel * 4, ' ');
507
+ const indentLevelText = indentLevel.toString().padStart(3, ' ');
497
508
  const args = ['[' + indentLevelText + ']', indentOutput, ...params];
498
509
  this.logger.add(args.join(' '));
499
510
  if (!this.silent) {
@@ -507,6 +518,17 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
507
518
  const result = await ctx.accept(this);
508
519
  return result;
509
520
  }
521
+ async importCommon(ctx, handling) {
522
+ const specificImports = [];
523
+ if (ctx instanceof CircuitScriptParser_js_1.Import_specificContext) {
524
+ const tmpSpecificImports = ctx._funcNames.map(item => {
525
+ return item.text;
526
+ });
527
+ specificImports.push(...tmpSpecificImports);
528
+ }
529
+ const id = ctx._moduleName.text;
530
+ await this.handleImportFile(id, handling, true, ctx, specificImports);
531
+ }
510
532
  getReference(ctx) {
511
533
  const atomStr = ctx.getText();
512
534
  if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
@@ -532,7 +554,8 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
532
554
  let currentReference = executor.resolveVariable(this.executionStack, atomId);
533
555
  if (ctx.trailer_expr().length > 0) {
534
556
  if (!currentReference.found) {
535
- this.throwWithContext(ctx, "Unknown function name: " + atomId);
557
+ this.log(`could not resolve function: ${atomId}`);
558
+ this.throwWithContext(ctx, "could not resolve function: " + atomId);
536
559
  }
537
560
  currentReference.trailers = [];
538
561
  ctx.trailer_expr().forEach(item => {
@@ -549,7 +572,24 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
549
572
  }
550
573
  const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
551
574
  try {
552
- const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
575
+ const isModuleFunction = currentReference.rootValue
576
+ && currentReference.rootValue instanceof types_js_1.ImportedModule;
577
+ if (isModuleFunction) {
578
+ this.log('create new module context');
579
+ const importedModule = currentReference.rootValue;
580
+ const importedModuleContext = importedModule.context;
581
+ const newExecutor = this.handleEnterContext(this.getExecutor(), this.executionStack, importedModuleContext.name, ctx, {
582
+ netNamespace: executor.netNamespace,
583
+ namespace: importedModule.moduleNamespace
584
+ }, [], [], false);
585
+ this.log('copy module context scope');
586
+ importedModuleContext.scope.copyTo(newExecutor.scope);
587
+ }
588
+ const [, functionResult] = executor.callFunction(currentReference, parameters, this.executionStack, useNetNamespace);
589
+ if (isModuleFunction) {
590
+ this.log('pop module context scope');
591
+ this.handlePopContext(this.getExecutor(), this.executionStack, "", false);
592
+ }
553
593
  if ((0, utils_js_1.isReference)(functionResult)) {
554
594
  currentReference = functionResult;
555
595
  }
@@ -576,6 +616,54 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
576
616
  }
577
617
  this.setResult(ctx, currentReference);
578
618
  }
619
+ handleEnterContext(executor, executionStack, contextName, ctx, options, funcDefinedParameters, passedInParameters, isBreakContext = true) {
620
+ if (isBreakContext) {
621
+ const parentBreakContext = executor.getParentBreakContext();
622
+ executor.addBreakContext(ctx);
623
+ let useIndex = -1;
624
+ if (parentBreakContext === null) {
625
+ useIndex = options.functionCallIndex;
626
+ }
627
+ else {
628
+ const parentEntry = executor.indexedStack.get(parentBreakContext);
629
+ const { funcCallIndex } = parentEntry;
630
+ if (!funcCallIndex.has(ctx)) {
631
+ funcCallIndex.set(ctx, 0);
632
+ useIndex = 0;
633
+ }
634
+ else {
635
+ useIndex = funcCallIndex.get(ctx) + 1;
636
+ funcCallIndex.set(ctx, useIndex);
637
+ }
638
+ }
639
+ executor.setBreakContextIndex(useIndex);
640
+ }
641
+ return this.enterNewChildContext(executionStack, executor, contextName, options, funcDefinedParameters, passedInParameters);
642
+ }
643
+ handlePopContext(executor, executionStack, namespaceExtension, isBreakContext = true) {
644
+ const poppedContext = executionStack.pop();
645
+ const nextLastExecution = executionStack[executionStack.length - 1];
646
+ const mergedComponents = nextLastExecution.mergeScope(poppedContext.scope, namespaceExtension);
647
+ if (isBreakContext) {
648
+ const scope = this.getScope();
649
+ const indexedStack = [];
650
+ if (scope.breakStack.length > 0) {
651
+ const executor = this.getExecutor();
652
+ scope.breakStack.forEach(stackCtx => {
653
+ const entry = executor.indexedStack.get(stackCtx);
654
+ const { index } = entry;
655
+ indexedStack.push([stackCtx, index]);
656
+ });
657
+ mergedComponents.forEach(component => {
658
+ component.ctxReferences.forEach(ref => {
659
+ ref.indexedStack = [...indexedStack, ...ref.indexedStack];
660
+ });
661
+ });
662
+ }
663
+ executor.popBreakContext();
664
+ }
665
+ return poppedContext;
666
+ }
579
667
  setResult(ctx, value) {
580
668
  this.resultData.set(ctx, value);
581
669
  }
@@ -607,18 +695,40 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
607
695
  this.visit(ctx);
608
696
  return this.getResult(ctx);
609
697
  }
610
- async handleImportFile(name, throwErrors = true, ctx = null) {
698
+ async handleImportFile(name, importHandling, throwErrors = true, ctx = null, specificImports = []) {
611
699
  name = name.trim();
612
700
  const importAlready = this.importedFiles.find(item => {
613
701
  return item.id === name;
614
702
  });
615
703
  if (importAlready) {
704
+ const tmpImportedModule = importAlready.importedModule;
705
+ const alreadyImportedFlag = tmpImportedModule.importHandlingFlag;
706
+ const isMergedNamespace = alreadyImportedFlag === types_js_1.ImportFunctionHandling.AllMergeIntoNamespace
707
+ || alreadyImportedFlag === types_js_1.ImportFunctionHandling.SpecificMergeIntoNamespace;
708
+ const invalidImportCondition1 = alreadyImportedFlag === types_js_1.ImportFunctionHandling.AllWithNamespace &&
709
+ importHandling !== types_js_1.ImportFunctionHandling.AllWithNamespace;
710
+ const invalidImportCondition2 = alreadyImportedFlag !== types_js_1.ImportFunctionHandling.AllWithNamespace &&
711
+ importHandling === types_js_1.ImportFunctionHandling.AllWithNamespace;
712
+ if (invalidImportCondition1 || invalidImportCondition2) {
713
+ throw new utils_js_2.RuntimeExecutionError(`Namespace import and wildcard/specific imports cannot be mixed: ${name}`, ctx);
714
+ }
715
+ if (isMergedNamespace) {
716
+ if (alreadyImportedFlag === types_js_1.ImportFunctionHandling.AllMergeIntoNamespace) {
717
+ }
718
+ else if (alreadyImportedFlag === types_js_1.ImportFunctionHandling.SpecificMergeIntoNamespace && importHandling === types_js_1.ImportFunctionHandling.AllMergeIntoNamespace) {
719
+ tmpImportedModule.specifiedImports = [];
720
+ tmpImportedModule.importHandlingFlag = types_js_1.ImportFunctionHandling.AllMergeIntoNamespace;
721
+ }
722
+ else if (alreadyImportedFlag === types_js_1.ImportFunctionHandling.SpecificMergeIntoNamespace && importHandling === types_js_1.ImportFunctionHandling.SpecificMergeIntoNamespace) {
723
+ tmpImportedModule.specifiedImports.push(...specificImports);
724
+ }
725
+ }
616
726
  return importAlready;
617
727
  }
618
728
  let hasError = false;
619
729
  let hasParseError = false;
620
730
  let pathExists = false;
621
- const tmpFilePath = this.environment.getRelativeToModule(name + ".cst");
731
+ const tmpFilePath = this.environment.getRelativeToCurrentFolder(name + ".cst");
622
732
  this.log('importing path:', tmpFilePath);
623
733
  let fileData = null;
624
734
  let filePathUsed = null;
@@ -628,30 +738,54 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
628
738
  pathExists = true;
629
739
  }
630
740
  catch (err) {
741
+ this.log('failed to read file');
631
742
  pathExists = false;
632
743
  }
744
+ let importedModule;
633
745
  if (!pathExists) {
634
746
  try {
635
747
  const tmpFilePath2 = this.environment.getRelativeToDefaultLibs(name + ".cst");
748
+ this.log('checking default libs: ' + tmpFilePath2);
636
749
  filePathUsed = tmpFilePath2;
637
750
  fileData = await this.environment.readFile(tmpFilePath2, { encoding: 'utf8' });
638
751
  pathExists = true;
639
752
  }
640
753
  catch (err) {
754
+ this.log('failed to read file');
641
755
  pathExists = false;
642
756
  }
643
757
  }
644
758
  try {
645
- if (pathExists) {
759
+ if (pathExists && filePathUsed) {
646
760
  this.log('done reading imported file data');
761
+ const executionStack = this.executionStack;
762
+ const executor = this.getExecutor();
763
+ const executionContextName = name;
764
+ const netNamespace = executor.netNamespace;
765
+ const moduleNamespace = `${globals_js_1.BaseNamespace}${name}.`;
766
+ this.enterNewChildContext(executionStack, executor, executionContextName, {
767
+ netNamespace,
768
+ namespace: moduleNamespace,
769
+ }, [], []);
647
770
  const importResult = await this.onImportFile(this, filePathUsed, fileData, this.onErrorHandler);
648
771
  hasError = importResult.hasError;
649
772
  hasParseError = importResult.hasParseError;
773
+ const importContext = executionStack.pop();
774
+ this.log(`import handling flag: ${importHandling}`);
775
+ importedModule = new types_js_1.ImportedModule(name, moduleNamespace, filePathUsed, importContext, importHandling, specificImports);
776
+ if (specificImports.length > 0) {
777
+ this.log('specific import: ' + specificImports.join(', '));
778
+ }
779
+ const scope = this.getScope();
780
+ scope.modules.set(name, importedModule);
781
+ importedModule.context.scope.modules.forEach((module, key) => {
782
+ scope.modules.set(key, module);
783
+ });
650
784
  }
651
785
  }
652
786
  catch (err) {
653
787
  if (ctx != null) {
654
- throw new utils_js_2.RuntimeExecutionError("An error occurred while importing file", ctx);
788
+ throw err;
655
789
  }
656
790
  else {
657
791
  this.log('An error occurred while importing file:', err.message);
@@ -674,6 +808,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
674
808
  hasError,
675
809
  hasParseError,
676
810
  pathExists,
811
+ importedModule: importedModule
677
812
  };
678
813
  this.importedFiles.push(newImportedFile);
679
814
  return newImportedFile;
@@ -761,14 +896,17 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
761
896
  return object.getParam(paramName);
762
897
  }
763
898
  enterNewChildContext(executionStack, parentContext, executionContextName, options, funcDefinedParameters, passedInParameters) {
764
- const { netNamespace = "" } = options;
899
+ const { netNamespace = "", namespace = null, } = options;
765
900
  const currentExecutionContext = executionStack[executionStack.length - 1];
766
901
  const executionLevel = currentExecutionContext.executionLevel;
767
- const executionContextNamespace = currentExecutionContext.namespace
902
+ const executionContextNamespace = namespace ?? currentExecutionContext.namespace
768
903
  + executionContextName + ".";
769
904
  const newExecutor = new execute_js_1.ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.scopeLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger, currentExecutionContext.warnings, parentContext);
770
905
  executionStack.push(newExecutor);
771
906
  this.setupDefinedParameters(funcDefinedParameters, passedInParameters, newExecutor);
907
+ newExecutor.resolveNet = this.createNetResolver(executionStack);
908
+ newExecutor.resolveComponentPinNet =
909
+ this.createComponentPinNetResolver(executionStack);
772
910
  return newExecutor;
773
911
  }
774
912
  prepareStringValue(value) {
@@ -107,6 +107,10 @@ class SemanticTokensVisitor extends BaseVisitor_js_1.BaseVisitor {
107
107
  this.addSemanticToken(ctx.ID(0), [], 'variable');
108
108
  }
109
109
  };
110
+ this.visitOperator_assignment_expr = (ctx) => {
111
+ this.visit(ctx.atom_expr());
112
+ this.visit(ctx.data_expr());
113
+ };
110
114
  this.visitImport_expr = (ctx) => {
111
115
  this.addSemanticToken(ctx.ID(), [], 'namespace');
112
116
  };
@@ -114,6 +118,8 @@ class SemanticTokensVisitor extends BaseVisitor_js_1.BaseVisitor {
114
118
  ctx.ID().forEach(item => {
115
119
  this.addSemanticToken(item, [], 'variable');
116
120
  });
121
+ this.visit(ctx.data_expr());
122
+ this.visit(ctx.expressions_block());
117
123
  };
118
124
  this.visitAnnotation_comment_expr = (ctx) => {
119
125
  this.addSemanticToken(ctx.ANNOTATION_START(), [], 'comment');