circuitscript 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/parseScripts.ts +106 -1
- package/__tests__/renderData/script7.cst +26 -0
- package/__tests__/renderData/script7.cst.svg +1 -0
- package/__tests__/renderData/script8.cst +37 -0
- package/__tests__/renderData/script8.cst.svg +1 -0
- package/__tests__/testParse.ts +5 -2
- package/__tests__/testRender.ts +3 -1
- package/build/src/antlr/CircuitScriptLexer.js +159 -154
- package/build/src/antlr/CircuitScriptParser.js +722 -632
- package/build/src/antlr/CircuitScriptVisitor.js +2 -2
- package/build/src/execute.js +87 -45
- package/build/src/globals.js +7 -5
- package/build/src/objects/ExecutionScope.js +1 -1
- package/build/src/visitor.js +46 -30
- package/package.json +1 -1
- package/src/antlr/CircuitScript.g4 +9 -8
- package/src/antlr/CircuitScriptLexer.ts +159 -154
- package/src/antlr/CircuitScriptParser.ts +719 -629
- package/src/antlr/CircuitScriptVisitor.ts +6 -6
- package/src/execute.ts +113 -56
- package/src/globals.ts +5 -3
- package/src/objects/ExecutionScope.ts +1 -1
- package/src/visitor.ts +58 -42
|
@@ -7,8 +7,8 @@ import {ParseTreeVisitor} from 'antlr4';
|
|
|
7
7
|
|
|
8
8
|
import { ScriptContext } from "./CircuitScriptParser";
|
|
9
9
|
import { ExpressionContext } from "./CircuitScriptParser";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { Path_blocksContext } from "./CircuitScriptParser";
|
|
11
|
+
import { Path_block_innerContext } from "./CircuitScriptParser";
|
|
12
12
|
import { Property_set_expr2Context } from "./CircuitScriptParser";
|
|
13
13
|
import { Assignment_expr2Context } from "./CircuitScriptParser";
|
|
14
14
|
import { Data_expr_with_assignmentContext } from "./CircuitScriptParser";
|
|
@@ -82,17 +82,17 @@ export default class CircuitScriptVisitor<Result> extends ParseTreeVisitor<Resul
|
|
|
82
82
|
*/
|
|
83
83
|
visitExpression?: (ctx: ExpressionContext) => Result;
|
|
84
84
|
/**
|
|
85
|
-
* Visit a parse tree produced by `CircuitScriptParser.
|
|
85
|
+
* Visit a parse tree produced by `CircuitScriptParser.path_blocks`.
|
|
86
86
|
* @param ctx the parse tree
|
|
87
87
|
* @return the visitor result
|
|
88
88
|
*/
|
|
89
|
-
|
|
89
|
+
visitPath_blocks?: (ctx: Path_blocksContext) => Result;
|
|
90
90
|
/**
|
|
91
|
-
* Visit a parse tree produced by `CircuitScriptParser.
|
|
91
|
+
* Visit a parse tree produced by `CircuitScriptParser.path_block_inner`.
|
|
92
92
|
* @param ctx the parse tree
|
|
93
93
|
* @return the visitor result
|
|
94
94
|
*/
|
|
95
|
-
|
|
95
|
+
visitPath_block_inner?: (ctx: Path_block_innerContext) => Result;
|
|
96
96
|
/**
|
|
97
97
|
* Visit a parse tree produced by `CircuitScriptParser.property_set_expr2`.
|
|
98
98
|
* @param ctx the parse tree
|
package/src/execute.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockTypes, ComponentTypes, GlobalNames, NoNetText, ParamKeys, ReferenceTypes } from './globals.js';
|
|
2
2
|
import { ClassComponent } from './objects/ClassComponent.js';
|
|
3
3
|
import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.js';
|
|
4
4
|
import { Net } from './objects/Net.js';
|
|
@@ -26,7 +26,7 @@ export class ExecutionContext {
|
|
|
26
26
|
|
|
27
27
|
scope: ExecutionScope;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
tmpPointId = 0; // Counter for points created within the context
|
|
30
30
|
|
|
31
31
|
resolveNet: (name: string, netNamespace:string) => ({
|
|
32
32
|
found: boolean, net?: Net
|
|
@@ -536,33 +536,42 @@ export class ExecutionContext {
|
|
|
536
536
|
return clonedComponent;
|
|
537
537
|
}
|
|
538
538
|
|
|
539
|
-
|
|
540
|
-
// Create object to track all the inner
|
|
541
|
-
// the
|
|
539
|
+
enterBlocks(blockType: BlockTypes): void {
|
|
540
|
+
// Create object to track all the inner blocks of
|
|
541
|
+
// the block group
|
|
542
542
|
|
|
543
|
-
|
|
544
|
-
|
|
543
|
+
if (blockType === BlockTypes.Point) {
|
|
544
|
+
this.addPoint(`_point.${this.name}.${this.tmpPointId}`, false);
|
|
545
|
+
this.tmpPointId += 1;
|
|
546
|
+
} else if (blockType === BlockTypes.Parallel) {
|
|
547
|
+
this.addPoint(`_parallel.${this.name}.${this.tmpPointId}`, false);
|
|
548
|
+
this.tmpPointId += 1;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
this.scope.blockStack.set(this.scope.indentLevel, {
|
|
552
|
+
// Tracks the position when the block is entered
|
|
545
553
|
entered_at: [
|
|
546
554
|
this.scope.currentComponent,
|
|
547
555
|
this.scope.currentPin,
|
|
548
556
|
this.scope.currentWireId],
|
|
549
|
-
|
|
557
|
+
inner_blocks: new Map<number, any>(),
|
|
550
558
|
current_index: null,
|
|
551
|
-
type:
|
|
559
|
+
type: blockType,
|
|
552
560
|
});
|
|
553
561
|
|
|
554
|
-
this.print('enter
|
|
562
|
+
this.print('enter blocks');
|
|
555
563
|
}
|
|
556
564
|
|
|
557
|
-
|
|
558
|
-
const stackRef = this.scope.
|
|
565
|
+
exitBlocks(): void {
|
|
566
|
+
const stackRef = this.scope.blockStack.get(
|
|
559
567
|
this.scope.indentLevel,
|
|
560
568
|
);
|
|
561
569
|
|
|
562
|
-
const { type:
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
570
|
+
const { type: blockType } = stackRef;
|
|
571
|
+
|
|
572
|
+
if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
|
|
573
|
+
// Move to the end location of the first block
|
|
574
|
+
const { final_point: finalPoint } = stackRef;
|
|
566
575
|
const [component, pin, wireId] = finalPoint;
|
|
567
576
|
|
|
568
577
|
this.scope.currentComponent = component;
|
|
@@ -574,88 +583,136 @@ export class ExecutionContext {
|
|
|
574
583
|
SequenceAction.WireJump, wireId, 1
|
|
575
584
|
]);
|
|
576
585
|
}
|
|
586
|
+
} else if (blockType === BlockTypes.Point) {
|
|
587
|
+
const { entered_at: [component, pin,] } =
|
|
588
|
+
stackRef;
|
|
589
|
+
|
|
590
|
+
// Preblock location should be a created point without any wires
|
|
591
|
+
this.atComponent(component, pin, { addSequence: true });
|
|
577
592
|
}
|
|
578
593
|
|
|
579
|
-
this.print('exit
|
|
594
|
+
this.print('exit blocks');
|
|
580
595
|
}
|
|
581
596
|
|
|
582
|
-
|
|
583
|
-
// Current net before any
|
|
584
|
-
const stackRef = this.scope.
|
|
585
|
-
stackRef['
|
|
597
|
+
enterBlock(blockIndex: number): void {
|
|
598
|
+
// Current net before any blocks is already stored in enterBlocks()
|
|
599
|
+
const stackRef = this.scope.blockStack.get(this.scope.indentLevel);
|
|
600
|
+
stackRef['block_index'] = blockIndex;
|
|
586
601
|
|
|
587
|
-
const { type:
|
|
602
|
+
const { type: blockType } = stackRef;
|
|
588
603
|
|
|
589
|
-
// Setup the state for the inner
|
|
590
|
-
stackRef['
|
|
604
|
+
// Setup the state for the inner block at the given index
|
|
605
|
+
stackRef['inner_blocks'].set(blockIndex, {
|
|
591
606
|
last_net: null,
|
|
592
607
|
ignore_last_net: false,
|
|
593
608
|
});
|
|
594
609
|
|
|
595
|
-
if (
|
|
596
|
-
// Clear current component, pin, wire before entering the
|
|
610
|
+
if (blockType === BlockTypes.Join || blockType === BlockTypes.Point) {
|
|
611
|
+
// Clear current component, pin, wire before entering the block
|
|
597
612
|
this.scope.currentComponent = null;
|
|
598
613
|
this.scope.currentPin = null;
|
|
599
614
|
this.scope.currentWireId = -1;
|
|
615
|
+
} else if (blockType === BlockTypes.Parallel) {
|
|
616
|
+
// Move to starting point of the parallel blocks
|
|
617
|
+
const { entered_at: [component, pin,] } = stackRef;
|
|
618
|
+
this.atComponent(component, pin, { addSequence: true });
|
|
600
619
|
}
|
|
601
620
|
|
|
602
|
-
this.print(`enter inner
|
|
621
|
+
this.print(`enter inner block of type (${blockType}) >>>`);
|
|
603
622
|
|
|
604
623
|
this.scope.indentLevel += 1;
|
|
605
624
|
}
|
|
606
625
|
|
|
607
|
-
|
|
608
|
-
const stackRef = this.scope.
|
|
609
|
-
const { type:
|
|
626
|
+
exitBlock(blockIndex: number): void {
|
|
627
|
+
const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1);
|
|
628
|
+
const { type: blockType } = stackRef;
|
|
629
|
+
|
|
610
630
|
// Save the last net reference
|
|
611
|
-
const
|
|
612
|
-
|
|
631
|
+
const blockIndexRef = stackRef['inner_blocks'].get(blockIndex);
|
|
632
|
+
blockIndexRef['last_net'] = [
|
|
613
633
|
this.scope.currentComponent,
|
|
614
634
|
this.scope.currentPin,
|
|
615
635
|
this.scope.currentWireId
|
|
616
636
|
];
|
|
617
637
|
|
|
618
|
-
stackRef['
|
|
638
|
+
stackRef['block_index'] = null;
|
|
639
|
+
this.scope.indentLevel -= 1;
|
|
619
640
|
|
|
620
|
-
|
|
621
|
-
const [preBranchComponent, preBranchPin, preBranchWireId] =
|
|
622
|
-
stackRef['entered_at'];
|
|
641
|
+
this.print('exit inner block <<<');
|
|
623
642
|
|
|
624
|
-
|
|
643
|
+
if (blockType === BlockTypes.Branch) {
|
|
625
644
|
|
|
626
|
-
|
|
645
|
+
// Restore the latest entry in the branch stack
|
|
646
|
+
const { entered_at: [component, pin, wireId] } =
|
|
647
|
+
stackRef;
|
|
627
648
|
|
|
628
|
-
if (branchType === BranchType.Branch) {
|
|
629
649
|
// Do not duplicate any net symbol since this is a branch
|
|
630
|
-
this.atComponent(
|
|
650
|
+
this.atComponent(component, pin, { addSequence: true });
|
|
631
651
|
|
|
632
|
-
if (
|
|
652
|
+
if (wireId !== -1) {
|
|
633
653
|
// If previous node is a wire, then jump to END of wire
|
|
634
|
-
this.scope.sequence.push([SequenceAction.WireJump,
|
|
654
|
+
this.scope.sequence.push([SequenceAction.WireJump, wireId, 1]);
|
|
635
655
|
}
|
|
636
|
-
} else if (
|
|
637
|
-
if (
|
|
638
|
-
// First join
|
|
656
|
+
} else if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
|
|
657
|
+
if (blockIndex === 0) {
|
|
658
|
+
// First join block will determine the final join location
|
|
639
659
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
this
|
|
660
|
+
const pointIdName = (blockType === BlockTypes.Join) ? '_join' : '_parallel';
|
|
661
|
+
|
|
662
|
+
// Add point to current location, start with _join keyword to
|
|
663
|
+
// indicate that this is a point for join keyword
|
|
664
|
+
this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
|
|
665
|
+
this.tmpPointId += 1;
|
|
644
666
|
|
|
645
|
-
stackRef['
|
|
667
|
+
stackRef['final_point'] = [
|
|
646
668
|
this.scope.currentComponent,
|
|
647
669
|
this.scope.currentPin,
|
|
648
670
|
this.scope.currentWireId
|
|
649
671
|
];
|
|
650
672
|
|
|
651
673
|
} else {
|
|
652
|
-
const {
|
|
653
|
-
const [
|
|
674
|
+
const { final_point: finalPoint } = stackRef;
|
|
675
|
+
const [component, pin,] = finalPoint;
|
|
654
676
|
|
|
655
677
|
// Link the current component to the join component and join pin
|
|
656
|
-
this.toComponent(
|
|
678
|
+
this.toComponent(component, pin, { addSequence: true });
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
atPointBlock(): void {
|
|
684
|
+
const [component, pin,] = this.getPointBlockLocation();
|
|
685
|
+
this.atComponent(component, pin, {
|
|
686
|
+
addSequence: true
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
toPointBlock(): void {
|
|
691
|
+
// Point has been specifically created for block, wireId should be -1
|
|
692
|
+
const [component, pin,] = this.getPointBlockLocation();
|
|
693
|
+
this.toComponent(component, pin, {
|
|
694
|
+
addSequence: true
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
getPointBlockLocation(): [component: ClassComponent, pin: number, wireId: number] {
|
|
699
|
+
// Returns the position at the nearest `point:` block, searches within
|
|
700
|
+
// previous block stacks
|
|
701
|
+
this.print('get block point');
|
|
702
|
+
|
|
703
|
+
for (let i = 0; i < this.scope.indentLevel; i++) {
|
|
704
|
+
const stackRef = this.scope.blockStack.get(this.scope.indentLevel - 1 - i);
|
|
705
|
+
const { entered_at } = stackRef;
|
|
706
|
+
const component: ClassComponent = entered_at[0];
|
|
707
|
+
|
|
708
|
+
if (component.instanceName.startsWith('_point.')) {
|
|
709
|
+
return entered_at;
|
|
657
710
|
}
|
|
658
711
|
}
|
|
712
|
+
|
|
713
|
+
this.print('did not find block point');
|
|
714
|
+
|
|
715
|
+
return null;
|
|
659
716
|
}
|
|
660
717
|
|
|
661
718
|
breakBranch(): void {
|
|
@@ -663,12 +720,12 @@ export class ExecutionContext {
|
|
|
663
720
|
// Mark that the branch stack at the current indent level
|
|
664
721
|
// should be ignored
|
|
665
722
|
|
|
666
|
-
const branchesInfo = this.scope.
|
|
723
|
+
const branchesInfo = this.scope.blockStack.get(
|
|
667
724
|
this.scope.indentLevel - 1,
|
|
668
725
|
);
|
|
669
|
-
const branchIndex = branchesInfo['
|
|
726
|
+
const branchIndex = branchesInfo['block_index'];
|
|
670
727
|
|
|
671
|
-
const branchIndexRef = branchesInfo['
|
|
728
|
+
const branchIndexRef = branchesInfo['inner_blocks'].get(branchIndex);
|
|
672
729
|
branchIndexRef['ignore_last_net'] = true;
|
|
673
730
|
}
|
|
674
731
|
|
package/src/globals.ts
CHANGED
|
@@ -59,7 +59,9 @@ export enum ReferenceTypes {
|
|
|
59
59
|
instance = 'instance',
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export enum
|
|
63
|
-
Branch = 1,
|
|
64
|
-
Join = 2,
|
|
62
|
+
export enum BlockTypes {
|
|
63
|
+
Branch = 1, // split off circuit paths, same starting insertion point
|
|
64
|
+
Join = 2, // join circuit paths, same ending insertion point
|
|
65
|
+
Parallel = 3, // same starting and ending points for the circuit paths
|
|
66
|
+
Point = 4, // to this point
|
|
65
67
|
}
|
package/src/visitor.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
Atom_exprContext,
|
|
16
16
|
BinaryOperatorExprContext,
|
|
17
17
|
Blank_exprContext,
|
|
18
|
-
|
|
18
|
+
Path_blocksContext,
|
|
19
19
|
Component_select_exprContext,
|
|
20
20
|
Create_component_exprContext,
|
|
21
21
|
Create_graphic_exprContext,
|
|
@@ -59,10 +59,10 @@ import {
|
|
|
59
59
|
import { PinDefinition, PinIdType } from './objects/PinDefinition.js';
|
|
60
60
|
import { PinTypes } from './objects/PinTypes.js';
|
|
61
61
|
import { ExecutionScope } from './objects/ExecutionScope.js';
|
|
62
|
-
import {
|
|
62
|
+
import { CFunctionOptions, CallableParameter, ComplexType, ComponentPin,
|
|
63
63
|
ComponentPinNet, FunctionDefinedParameter, ReferenceType, UndeclaredReference, ValueType } from './objects/types.js';
|
|
64
64
|
import { Logger } from './logger.js';
|
|
65
|
-
import {
|
|
65
|
+
import { BlockTypes, ComponentTypes, NoNetText } from './globals.js';
|
|
66
66
|
import { Net } from './objects/Net.js';
|
|
67
67
|
import { SubExpressionCommand, SymbolDrawingCommands } from './draw_symbols.js';
|
|
68
68
|
import { parseFileWithVisitor } from './parser.js';
|
|
@@ -303,36 +303,48 @@ export class MainVisitor extends ParseTreeVisitor<any> {
|
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
visitAt_component_expr(ctx: At_component_exprContext): ComponentPin {
|
|
306
|
-
|
|
306
|
+
if (ctx.Point()) {
|
|
307
|
+
this.getExecutor().atPointBlock();
|
|
307
308
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
309
|
+
} else {
|
|
310
|
+
const [component, pin] = this.visit(ctx.component_select_expr());
|
|
311
|
+
|
|
312
|
+
const currentPoint = this.getExecutor().atComponent(component, pin, {
|
|
313
|
+
addSequence: true,
|
|
314
|
+
cloneNetComponent: true
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (ctx.ID()) {
|
|
318
|
+
// If there is ID specified, then it can only be for the
|
|
319
|
+
// component orientation.
|
|
320
|
+
this.setComponentOrientation(currentPoint[0],
|
|
321
|
+
currentPoint[1], ctx.ID().getText())
|
|
322
|
+
}
|
|
318
323
|
}
|
|
319
|
-
|
|
320
|
-
return
|
|
324
|
+
|
|
325
|
+
return this.getExecutor().getCurrentPoint();
|
|
321
326
|
}
|
|
322
327
|
|
|
323
|
-
visitTo_component_expr(ctx: To_component_exprContext): ComponentPin
|
|
328
|
+
visitTo_component_expr(ctx: To_component_exprContext): ComponentPin {
|
|
324
329
|
let currentPoint: ComponentPin;
|
|
325
|
-
ctx.component_select_expr_list().forEach((item) => {
|
|
326
|
-
const [component, pin] = this.visit(item);
|
|
327
|
-
currentPoint = this.getExecutor().toComponent(component, pin, {
|
|
328
|
-
addSequence: true, cloneNetComponent: true});
|
|
329
|
-
});
|
|
330
330
|
|
|
331
|
-
if (ctx.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
331
|
+
if (ctx.Point()) {
|
|
332
|
+
this.getExecutor().toPointBlock();
|
|
333
|
+
|
|
334
|
+
} else {
|
|
335
|
+
ctx.component_select_expr_list().forEach((item) => {
|
|
336
|
+
const [component, pin] = this.visit(item);
|
|
337
|
+
currentPoint = this.getExecutor().toComponent(component, pin, {
|
|
338
|
+
addSequence: true, cloneNetComponent: true
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
if (ctx.ID()) {
|
|
343
|
+
// If there is ID specified, then it can only be for the
|
|
344
|
+
// component orientation.
|
|
345
|
+
this.setComponentOrientation(currentPoint[0],
|
|
346
|
+
currentPoint[1], ctx.ID().getText())
|
|
347
|
+
}
|
|
336
348
|
}
|
|
337
349
|
|
|
338
350
|
return this.getExecutor().getCurrentPoint();
|
|
@@ -352,30 +364,34 @@ export class MainVisitor extends ParseTreeVisitor<any> {
|
|
|
352
364
|
}
|
|
353
365
|
}
|
|
354
366
|
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
let
|
|
358
|
-
|
|
359
|
-
if (
|
|
360
|
-
const
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
} else if (
|
|
364
|
-
|
|
367
|
+
visitPath_blocks(ctx: Path_blocksContext): ComponentPin {
|
|
368
|
+
const blocks = ctx.path_block_inner_list();
|
|
369
|
+
let blockType = BlockTypes.Branch;
|
|
370
|
+
|
|
371
|
+
if (blocks.length > 0){
|
|
372
|
+
const firstBlock = blocks[0];
|
|
373
|
+
if (firstBlock.Branch()){
|
|
374
|
+
blockType = BlockTypes.Branch
|
|
375
|
+
} else if (firstBlock.Join()){
|
|
376
|
+
blockType = BlockTypes.Join;
|
|
377
|
+
} else if (firstBlock.Parallel()){
|
|
378
|
+
blockType = BlockTypes.Parallel;
|
|
379
|
+
} else if (firstBlock.Point()){
|
|
380
|
+
blockType = BlockTypes.Point;
|
|
365
381
|
}
|
|
366
382
|
}
|
|
367
383
|
|
|
368
|
-
this.getExecutor().
|
|
384
|
+
this.getExecutor().enterBlocks(blockType);
|
|
369
385
|
|
|
370
|
-
|
|
371
|
-
this.getExecutor().
|
|
386
|
+
blocks.forEach((branch, index) => {
|
|
387
|
+
this.getExecutor().enterBlock(index);
|
|
372
388
|
|
|
373
389
|
this.visit(branch);
|
|
374
390
|
|
|
375
|
-
this.getExecutor().
|
|
391
|
+
this.getExecutor().exitBlock(index);
|
|
376
392
|
});
|
|
377
393
|
|
|
378
|
-
this.getExecutor().
|
|
394
|
+
this.getExecutor().exitBlocks();
|
|
379
395
|
return this.getExecutor().getCurrentPoint();
|
|
380
396
|
}
|
|
381
397
|
|