@hoox-sh/pynets 0.2.0 → 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.
- package/CHANGELOG.md +56 -0
- package/README.md +21 -12
- package/dist/browser.js +89 -84
- package/dist/index.js +21011 -12972
- package/package.json +1 -1
- package/src/ast/builder.ts +235 -12
- package/src/ast/nodes.ts +114 -4
- package/src/ast/unparse.ts +192 -17
- package/src/cli/rich.ts +1 -1
- package/src/generated/PinescriptLexer.interp +5 -1
- package/src/generated/PinescriptLexer.tokens +97 -95
- package/src/generated/PinescriptLexer.ts +512 -502
- package/src/generated/PinescriptParser.interp +8 -1
- package/src/generated/PinescriptParser.tokens +97 -95
- package/src/generated/PinescriptParser.ts +1907 -1287
- package/src/generated/PinescriptParserVisitor.ts +36 -1
- package/src/index.ts +1 -0
- package/src/runtime/array.ts +238 -68
- package/src/runtime/compile/collections.ts +191 -34
- package/src/runtime/compile/draw.ts +609 -19
- package/src/runtime/compile/emit.ts +346 -9
- package/src/runtime/compile/emit_call.ts +737 -44
- package/src/runtime/compile/runtime.ts +82 -2
- package/src/runtime/compile/strategy.ts +339 -6
- package/src/runtime/compile/types.ts +2 -0
- package/src/runtime/drawings.ts +405 -8
- package/src/runtime/interpret.ts +2352 -277
- package/src/runtime/matrix.ts +371 -42
- package/src/runtime/strategy.ts +695 -33
- package/src/runtime/ta.ts +1046 -20
- package/src/runtime/timeframe.ts +199 -0
package/package.json
CHANGED
package/src/ast/builder.ts
CHANGED
|
@@ -13,8 +13,15 @@ import {
|
|
|
13
13
|
type Additive_opContext,
|
|
14
14
|
type Argument_definitionContext,
|
|
15
15
|
type Argument_listContext,
|
|
16
|
+
type Assignment_target_attributeContext,
|
|
17
|
+
type Assignment_target_subscriptContext,
|
|
16
18
|
type Attributed_type_nameContext,
|
|
19
|
+
type Augassign_opContext,
|
|
20
|
+
type Bitwise_and_expressionContext,
|
|
21
|
+
type Bitwise_or_expressionContext,
|
|
22
|
+
type Bitwise_xor_expressionContext,
|
|
17
23
|
type Break_statementContext,
|
|
24
|
+
type Compound_augassignmentContext,
|
|
18
25
|
type Compound_name_initializationContext,
|
|
19
26
|
type Compound_reassignmentContext,
|
|
20
27
|
type Compound_tuple_initializationContext,
|
|
@@ -66,13 +73,16 @@ import {
|
|
|
66
73
|
type Primary_expression_callContext,
|
|
67
74
|
type Primary_expression_subscriptContext,
|
|
68
75
|
type Not_equal_trailing_pairContext,
|
|
76
|
+
type Once_structureContext,
|
|
69
77
|
type Parameter_definitionContext,
|
|
70
78
|
type Parameter_listContext,
|
|
79
|
+
type Simple_augassignmentContext,
|
|
71
80
|
type Simple_name_initializationContext,
|
|
72
81
|
type Simple_reassignmentContext,
|
|
73
82
|
type Simple_tuple_initializationContext,
|
|
74
83
|
type Structure_expressionContext,
|
|
75
84
|
type Structure_statementContext,
|
|
85
|
+
type Switch_caseContext,
|
|
76
86
|
type Switch_casesContext,
|
|
77
87
|
type Switch_default_caseContext,
|
|
78
88
|
type Switch_pattern_caseContext,
|
|
@@ -80,8 +90,13 @@ import {
|
|
|
80
90
|
type Trailing_structure_statementsContext,
|
|
81
91
|
type Tuple_declarationContext,
|
|
82
92
|
type Tuple_expressionContext,
|
|
93
|
+
type Template_spec_suffixContext,
|
|
94
|
+
type Type_argument_listContext,
|
|
83
95
|
type Type_declarationContext,
|
|
96
|
+
type Type_qualifierContext,
|
|
84
97
|
type Type_specificationContext,
|
|
98
|
+
type Shift_expressionContext,
|
|
99
|
+
type Shift_opContext,
|
|
85
100
|
type Simple_statementsContext,
|
|
86
101
|
type Start_expressionContext,
|
|
87
102
|
type Start_scriptContext,
|
|
@@ -97,11 +112,17 @@ import {
|
|
|
97
112
|
import {
|
|
98
113
|
Add,
|
|
99
114
|
And,
|
|
115
|
+
BitAnd,
|
|
116
|
+
BitOr,
|
|
117
|
+
BitXor,
|
|
118
|
+
Const,
|
|
100
119
|
Div,
|
|
101
120
|
Eq,
|
|
102
121
|
Gt,
|
|
103
122
|
GtE,
|
|
123
|
+
Input,
|
|
104
124
|
Invert,
|
|
125
|
+
LShift,
|
|
105
126
|
Lt,
|
|
106
127
|
LtE,
|
|
107
128
|
NotEq,
|
|
@@ -110,6 +131,9 @@ import {
|
|
|
110
131
|
Mult,
|
|
111
132
|
NotOp,
|
|
112
133
|
Or,
|
|
134
|
+
RShift,
|
|
135
|
+
Series,
|
|
136
|
+
Simple,
|
|
113
137
|
Store,
|
|
114
138
|
Sub,
|
|
115
139
|
UAdd,
|
|
@@ -119,6 +143,7 @@ import {
|
|
|
119
143
|
arg,
|
|
120
144
|
assign,
|
|
121
145
|
attribute,
|
|
146
|
+
augAssign,
|
|
122
147
|
binOp,
|
|
123
148
|
boolOp,
|
|
124
149
|
breakStmt,
|
|
@@ -137,9 +162,12 @@ import {
|
|
|
137
162
|
ifExpr,
|
|
138
163
|
importStmt,
|
|
139
164
|
name,
|
|
165
|
+
onceExpr,
|
|
140
166
|
param,
|
|
167
|
+
qualify,
|
|
141
168
|
reAssign,
|
|
142
169
|
script,
|
|
170
|
+
specialize,
|
|
143
171
|
subscript,
|
|
144
172
|
switchExpr,
|
|
145
173
|
tupleExpr,
|
|
@@ -157,6 +185,7 @@ import {
|
|
|
157
185
|
type operator,
|
|
158
186
|
type Param,
|
|
159
187
|
type stmt,
|
|
188
|
+
type type_qual,
|
|
160
189
|
type unary_op,
|
|
161
190
|
} from "./nodes.ts";
|
|
162
191
|
|
|
@@ -354,6 +383,64 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
354
383
|
return this.visit(exprs[0]);
|
|
355
384
|
};
|
|
356
385
|
|
|
386
|
+
visitBitwise_or_expression = (ctx: Bitwise_or_expressionContext): unknown => {
|
|
387
|
+
if (hasTerminal(ctx.PIPE())) {
|
|
388
|
+
const node = binOp(
|
|
389
|
+
this.visit(ctx.bitwise_or_expression()) as expr,
|
|
390
|
+
BitOr,
|
|
391
|
+
this.visit(ctx.bitwise_xor_expression()) as expr,
|
|
392
|
+
);
|
|
393
|
+
loc(node, ctx);
|
|
394
|
+
return node;
|
|
395
|
+
}
|
|
396
|
+
return this.visit(ctx.bitwise_xor_expression());
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
visitBitwise_xor_expression = (ctx: Bitwise_xor_expressionContext): unknown => {
|
|
400
|
+
if (hasTerminal(ctx.CARET())) {
|
|
401
|
+
const node = binOp(
|
|
402
|
+
this.visit(ctx.bitwise_xor_expression()) as expr,
|
|
403
|
+
BitXor,
|
|
404
|
+
this.visit(ctx.bitwise_and_expression()) as expr,
|
|
405
|
+
);
|
|
406
|
+
loc(node, ctx);
|
|
407
|
+
return node;
|
|
408
|
+
}
|
|
409
|
+
return this.visit(ctx.bitwise_and_expression());
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
visitBitwise_and_expression = (ctx: Bitwise_and_expressionContext): unknown => {
|
|
413
|
+
if (hasTerminal(ctx.AMP())) {
|
|
414
|
+
const node = binOp(
|
|
415
|
+
this.visit(ctx.bitwise_and_expression()) as expr,
|
|
416
|
+
BitAnd,
|
|
417
|
+
this.visit(ctx.equality_expression()) as expr,
|
|
418
|
+
);
|
|
419
|
+
loc(node, ctx);
|
|
420
|
+
return node;
|
|
421
|
+
}
|
|
422
|
+
return this.visit(ctx.equality_expression());
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
visitShift_op = (ctx: Shift_opContext): unknown => {
|
|
426
|
+
if (hasTerminal(ctx.LSHIFT())) return LShift;
|
|
427
|
+
if (hasTerminal(ctx.RSHIFT())) return RShift;
|
|
428
|
+
return LShift;
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
visitShift_expression = (ctx: Shift_expressionContext): unknown => {
|
|
432
|
+
if (isRuleCtx(ctx.shift_op())) {
|
|
433
|
+
const node = binOp(
|
|
434
|
+
this.visit(ctx.shift_expression()) as expr,
|
|
435
|
+
this.visit(ctx.shift_op()) as operator,
|
|
436
|
+
this.visit(ctx.additive_expression()) as expr,
|
|
437
|
+
);
|
|
438
|
+
loc(node, ctx);
|
|
439
|
+
return node;
|
|
440
|
+
}
|
|
441
|
+
return this.visit(ctx.additive_expression());
|
|
442
|
+
};
|
|
443
|
+
|
|
357
444
|
visitAdditive_expression = (ctx: Additive_expressionContext): unknown => {
|
|
358
445
|
if (ctx.additive_op()) {
|
|
359
446
|
const node = binOp(
|
|
@@ -414,7 +501,23 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
414
501
|
};
|
|
415
502
|
|
|
416
503
|
visitPrimary_expression_call = (ctx: Primary_expression_callContext): unknown => {
|
|
417
|
-
|
|
504
|
+
let func = this.visit(ctx.primary_expression()) as expr;
|
|
505
|
+
const spec = ctx.template_spec_suffix();
|
|
506
|
+
if (isRuleCtx(spec)) {
|
|
507
|
+
const specArgs = (this.visit(spec) as expr | null | undefined) ?? null;
|
|
508
|
+
const specNode = specialize(func, specArgs);
|
|
509
|
+
specNode.lineno = func.lineno;
|
|
510
|
+
specNode.col_offset = func.col_offset;
|
|
511
|
+
if (specArgs) {
|
|
512
|
+
specNode.end_lineno = specArgs.end_lineno ?? null;
|
|
513
|
+
specNode.end_col_offset = specArgs.end_col_offset ?? null;
|
|
514
|
+
} else {
|
|
515
|
+
loc(specNode, spec);
|
|
516
|
+
specNode.lineno = func.lineno;
|
|
517
|
+
specNode.col_offset = func.col_offset;
|
|
518
|
+
}
|
|
519
|
+
func = specNode;
|
|
520
|
+
}
|
|
418
521
|
const argsCtx = ctx.argument_list();
|
|
419
522
|
const args = isRuleCtx(argsCtx) ? asArgList(this.visit(argsCtx)) : [];
|
|
420
523
|
const node = call(func, args);
|
|
@@ -529,16 +632,59 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
529
632
|
|
|
530
633
|
visitType_specification = (ctx: Type_specificationContext): unknown => {
|
|
531
634
|
let typeSpec = this.visit(ctx.attributed_type_name()) as expr;
|
|
532
|
-
|
|
635
|
+
const tempSpec = ctx.template_spec_suffix();
|
|
636
|
+
if (isRuleCtx(tempSpec)) {
|
|
637
|
+
const args = (this.visit(tempSpec) as expr | null | undefined) ?? null;
|
|
638
|
+
const node = specialize(typeSpec, args);
|
|
639
|
+
loc(node, tempSpec);
|
|
640
|
+
node.lineno = typeSpec.lineno;
|
|
641
|
+
node.col_offset = typeSpec.col_offset;
|
|
642
|
+
typeSpec = node;
|
|
643
|
+
}
|
|
644
|
+
const arraySuffix = ctx.array_type_suffix();
|
|
645
|
+
if (isRuleCtx(arraySuffix)) {
|
|
533
646
|
const node = subscript(typeSpec, null, Load);
|
|
534
|
-
loc(node,
|
|
647
|
+
loc(node, arraySuffix);
|
|
535
648
|
node.lineno = typeSpec.lineno;
|
|
536
649
|
node.col_offset = typeSpec.col_offset;
|
|
537
650
|
typeSpec = node;
|
|
538
651
|
}
|
|
652
|
+
const typeQual = ctx.type_qualifier();
|
|
653
|
+
if (isRuleCtx(typeQual)) {
|
|
654
|
+
const qualifier = this.visit(typeQual) as type_qual | undefined;
|
|
655
|
+
if (qualifier) {
|
|
656
|
+
const node = qualify(qualifier, typeSpec);
|
|
657
|
+
loc(node, typeQual);
|
|
658
|
+
node.end_lineno = typeSpec.end_lineno ?? null;
|
|
659
|
+
node.end_col_offset = typeSpec.end_col_offset ?? null;
|
|
660
|
+
typeSpec = node;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
539
663
|
return typeSpec;
|
|
540
664
|
};
|
|
541
665
|
|
|
666
|
+
visitType_qualifier = (ctx: Type_qualifierContext): unknown => {
|
|
667
|
+
if (hasTerminal(ctx.CONST())) return Const;
|
|
668
|
+
if (hasTerminal(ctx.INPUT())) return Input;
|
|
669
|
+
if (hasTerminal(ctx.SIMPLE())) return Simple;
|
|
670
|
+
if (hasTerminal(ctx.SERIES())) return Series;
|
|
671
|
+
return undefined;
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
visitTemplate_spec_suffix = (ctx: Template_spec_suffixContext): unknown => {
|
|
675
|
+
const argsCtx = ctx.type_argument_list();
|
|
676
|
+
if (!isRuleCtx(argsCtx)) return null;
|
|
677
|
+
return this.visit(argsCtx);
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
visitType_argument_list = (ctx: Type_argument_listContext): unknown => {
|
|
681
|
+
const args = (ctx.type_specification_list() ?? []).map((a) => this.visit(a) as expr);
|
|
682
|
+
if (args.length === 1) return args[0];
|
|
683
|
+
const node = tupleExpr(args, Load);
|
|
684
|
+
loc(node, ctx);
|
|
685
|
+
return node;
|
|
686
|
+
};
|
|
687
|
+
|
|
542
688
|
visitAttributed_type_name = (ctx: Attributed_type_nameContext): unknown => {
|
|
543
689
|
const names = (ctx.name_load_list() ?? []).map((n) => this.visit(n) as Name);
|
|
544
690
|
if (names.length === 0) return undefined;
|
|
@@ -589,7 +735,7 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
589
735
|
};
|
|
590
736
|
|
|
591
737
|
visitStructure_expression = (ctx: Structure_expressionContext): unknown => {
|
|
592
|
-
return this.visit(ctx.
|
|
738
|
+
return this.visit(ctx.value_structure());
|
|
593
739
|
};
|
|
594
740
|
|
|
595
741
|
visitTrailing_structure_statements = (ctx: Trailing_structure_statementsContext): unknown => {
|
|
@@ -616,14 +762,66 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
616
762
|
return node;
|
|
617
763
|
};
|
|
618
764
|
|
|
619
|
-
|
|
765
|
+
visitSimple_augassignment = (ctx: Simple_augassignmentContext): unknown => {
|
|
620
766
|
const target = setStoreCtx(this.visit(ctx.primary_expression()) as expr);
|
|
767
|
+
const op = this.visit(ctx.augassign_op()) as operator;
|
|
768
|
+
const value = this.visit(ctx.expression()) as expr;
|
|
769
|
+
const node = augAssign(target, op, value);
|
|
770
|
+
loc(node, ctx);
|
|
771
|
+
return node;
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
visitCompound_augassignment = (ctx: Compound_augassignmentContext): unknown => {
|
|
775
|
+
const target = setStoreCtx(this.visit(ctx.primary_expression()) as expr);
|
|
776
|
+
const op = this.visit(ctx.augassign_op()) as operator;
|
|
777
|
+
const value = this.visit(ctx.structure_expression()) as expr;
|
|
778
|
+
const node = augAssign(target, op, value);
|
|
779
|
+
loc(node, ctx);
|
|
780
|
+
return node;
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
visitAugassign_op = (ctx: Augassign_opContext): unknown => {
|
|
784
|
+
if (hasTerminal(ctx.STAREQUAL())) return Mult;
|
|
785
|
+
if (hasTerminal(ctx.SLASHEQUAL())) return Div;
|
|
786
|
+
if (hasTerminal(ctx.PERCENTEQUAL())) return Mod;
|
|
787
|
+
if (hasTerminal(ctx.PLUSEQUAL())) return Add;
|
|
788
|
+
if (hasTerminal(ctx.MINEQUAL())) return Sub;
|
|
789
|
+
return Add;
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
visitSimple_reassignment = (ctx: Simple_reassignmentContext): unknown => {
|
|
793
|
+
const attr = ctx.assignment_target_attribute();
|
|
794
|
+
const sub = ctx.assignment_target_subscript();
|
|
795
|
+
let target: expr;
|
|
796
|
+
if (isRuleCtx(attr)) {
|
|
797
|
+
target = this.visit(attr) as expr;
|
|
798
|
+
} else if (isRuleCtx(sub)) {
|
|
799
|
+
target = this.visit(sub) as expr;
|
|
800
|
+
} else {
|
|
801
|
+
target = setStoreCtx(this.visit(ctx.primary_expression()) as expr);
|
|
802
|
+
}
|
|
621
803
|
const value = this.visit(ctx.expression()) as expr;
|
|
622
804
|
const node = reAssign(target, value);
|
|
623
805
|
loc(node, ctx);
|
|
624
806
|
return node;
|
|
625
807
|
};
|
|
626
808
|
|
|
809
|
+
visitAssignment_target_attribute = (ctx: Assignment_target_attributeContext): unknown => {
|
|
810
|
+
const value = this.visit(ctx.primary_expression()) as expr;
|
|
811
|
+
const n = this.visit(ctx.name_store()) as ReturnType<typeof name>;
|
|
812
|
+
const node = attribute(value, n.id, Store);
|
|
813
|
+
loc(node, ctx);
|
|
814
|
+
return node;
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
visitAssignment_target_subscript = (ctx: Assignment_target_subscriptContext): unknown => {
|
|
818
|
+
const value = this.visit(ctx.primary_expression()) as expr;
|
|
819
|
+
const items = this.visit(ctx.subscript_slice()) as expr;
|
|
820
|
+
const node = subscript(value, items, Store);
|
|
821
|
+
loc(node, ctx);
|
|
822
|
+
return node;
|
|
823
|
+
};
|
|
824
|
+
|
|
627
825
|
visitVariable_declaration = (ctx: Variable_declarationContext): unknown => {
|
|
628
826
|
const target = this.visit(ctx.name_store()) as expr;
|
|
629
827
|
const typeCtx = ctx.type_specification();
|
|
@@ -654,7 +852,9 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
654
852
|
const args = isRuleCtx(argsCtx) ? asParamList(this.visit(argsCtx)) : [];
|
|
655
853
|
const body = asStmtList(this.visit(ctx.local_block()));
|
|
656
854
|
const exported = hasTerminal(ctx.EXPORT()) ? 1 : 0;
|
|
657
|
-
const
|
|
855
|
+
const retCtx = ctx.type_specification();
|
|
856
|
+
const returns = isRuleCtx(retCtx) ? ((this.visit(retCtx) as expr | undefined) ?? null) : null;
|
|
857
|
+
const node = functionDef(fname, args, body, 0, exported, [], returns);
|
|
658
858
|
loc(node, ctx);
|
|
659
859
|
return node;
|
|
660
860
|
};
|
|
@@ -682,7 +882,9 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
682
882
|
const args = isRuleCtx(argsCtx) ? asParamList(this.visit(argsCtx)) : [];
|
|
683
883
|
const body = asStmtList(this.visit(ctx.local_block()));
|
|
684
884
|
const exported = hasTerminal(ctx.EXPORT()) ? 1 : 0;
|
|
685
|
-
const
|
|
885
|
+
const retCtx = ctx.type_specification();
|
|
886
|
+
const returns = isRuleCtx(retCtx) ? ((this.visit(retCtx) as expr | undefined) ?? null) : null;
|
|
887
|
+
const node = functionDef(fname, args, body, 1, exported, [], returns);
|
|
686
888
|
loc(node, ctx);
|
|
687
889
|
return node;
|
|
688
890
|
};
|
|
@@ -810,6 +1012,15 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
810
1012
|
return node;
|
|
811
1013
|
};
|
|
812
1014
|
|
|
1015
|
+
visitOnce_structure = (ctx: Once_structureContext): unknown => {
|
|
1016
|
+
const testCtx = ctx.expression();
|
|
1017
|
+
const test = isRuleCtx(testCtx) ? ((this.visit(testCtx) as expr | undefined) ?? null) : null;
|
|
1018
|
+
const body = asStmtList(this.visit(ctx.local_block()));
|
|
1019
|
+
const node = onceExpr(test, body);
|
|
1020
|
+
loc(node, ctx);
|
|
1021
|
+
return node;
|
|
1022
|
+
};
|
|
1023
|
+
|
|
813
1024
|
visitSwitch_structure = (ctx: Switch_structureContext): unknown => {
|
|
814
1025
|
const cases = asCaseList(this.visit(ctx.switch_cases()));
|
|
815
1026
|
const subjectCtx = ctx.expression();
|
|
@@ -822,15 +1033,27 @@ export class PinescriptASTBuilder extends PinescriptParserVisitor<unknown> {
|
|
|
822
1033
|
};
|
|
823
1034
|
|
|
824
1035
|
visitSwitch_cases = (ctx: Switch_casesContext): unknown => {
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
1036
|
+
return (ctx.switch_case_list() ?? []).map((c) => this.visit(c));
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
visitSwitch_case = (ctx: Switch_caseContext): unknown => {
|
|
1040
|
+
const patternCase = ctx.switch_pattern_case();
|
|
1041
|
+
if (isRuleCtx(patternCase)) return this.visit(patternCase);
|
|
1042
|
+
return this.visit(ctx.switch_default_case());
|
|
829
1043
|
};
|
|
830
1044
|
|
|
831
1045
|
visitSwitch_pattern_case = (ctx: Switch_pattern_caseContext): unknown => {
|
|
832
1046
|
const body = asStmtList(this.visit(ctx.local_block()));
|
|
833
|
-
const
|
|
1047
|
+
const patsCtx = ctx.switch_patterns();
|
|
1048
|
+
const exprs = isRuleCtx(patsCtx)
|
|
1049
|
+
? (patsCtx.expression_list() ?? []).map((e) => this.visit(e) as expr)
|
|
1050
|
+
: [];
|
|
1051
|
+
let pattern: expr | null = null;
|
|
1052
|
+
if (exprs.length === 1) pattern = exprs[0]!;
|
|
1053
|
+
else if (exprs.length > 1) {
|
|
1054
|
+
pattern = tupleExpr(exprs, Load);
|
|
1055
|
+
loc(pattern, patsCtx);
|
|
1056
|
+
}
|
|
834
1057
|
const node = caseNode(body, pattern);
|
|
835
1058
|
loc(node, ctx);
|
|
836
1059
|
return node;
|
package/src/ast/nodes.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type ASTKind =
|
|
|
10
10
|
| "Expr"
|
|
11
11
|
| "Assign"
|
|
12
12
|
| "ReAssign"
|
|
13
|
+
| "AugAssign"
|
|
13
14
|
| "FunctionDef"
|
|
14
15
|
| "TypeDef"
|
|
15
16
|
| "EnumDef"
|
|
@@ -30,8 +31,11 @@ export type ASTKind =
|
|
|
30
31
|
| "ForIn"
|
|
31
32
|
| "While"
|
|
32
33
|
| "Switch"
|
|
34
|
+
| "Once"
|
|
33
35
|
| "Case"
|
|
34
36
|
| "BoolOp"
|
|
37
|
+
| "Qualify"
|
|
38
|
+
| "Specialize"
|
|
35
39
|
| "And"
|
|
36
40
|
| "Or"
|
|
37
41
|
| "Break"
|
|
@@ -50,12 +54,21 @@ export type ASTKind =
|
|
|
50
54
|
| "Mult"
|
|
51
55
|
| "Div"
|
|
52
56
|
| "Mod"
|
|
57
|
+
| "BitAnd"
|
|
58
|
+
| "BitOr"
|
|
59
|
+
| "BitXor"
|
|
60
|
+
| "LShift"
|
|
61
|
+
| "RShift"
|
|
53
62
|
| "UAdd"
|
|
54
63
|
| "USub"
|
|
55
64
|
| "Not"
|
|
56
65
|
| "Invert"
|
|
57
66
|
| "Var"
|
|
58
|
-
| "VarIp"
|
|
67
|
+
| "VarIp"
|
|
68
|
+
| "Const"
|
|
69
|
+
| "Input"
|
|
70
|
+
| "Simple"
|
|
71
|
+
| "Series";
|
|
59
72
|
|
|
60
73
|
export interface AST {
|
|
61
74
|
readonly kind: ASTKind;
|
|
@@ -97,6 +110,13 @@ export interface ReAssign extends AST {
|
|
|
97
110
|
value: expr;
|
|
98
111
|
}
|
|
99
112
|
|
|
113
|
+
export interface AugAssign extends AST {
|
|
114
|
+
kind: "AugAssign";
|
|
115
|
+
target: expr;
|
|
116
|
+
op: operator;
|
|
117
|
+
value: expr;
|
|
118
|
+
}
|
|
119
|
+
|
|
100
120
|
export interface Var extends AST {
|
|
101
121
|
kind: "Var";
|
|
102
122
|
}
|
|
@@ -107,6 +127,20 @@ export interface VarIp extends AST {
|
|
|
107
127
|
|
|
108
128
|
export type decl_mode = Var | VarIp;
|
|
109
129
|
|
|
130
|
+
export interface Const extends AST {
|
|
131
|
+
kind: "Const";
|
|
132
|
+
}
|
|
133
|
+
export interface Input extends AST {
|
|
134
|
+
kind: "Input";
|
|
135
|
+
}
|
|
136
|
+
export interface Simple extends AST {
|
|
137
|
+
kind: "Simple";
|
|
138
|
+
}
|
|
139
|
+
export interface Series extends AST {
|
|
140
|
+
kind: "Series";
|
|
141
|
+
}
|
|
142
|
+
export type type_qual = Const | Input | Simple | Series;
|
|
143
|
+
|
|
110
144
|
export interface Import extends AST {
|
|
111
145
|
kind: "Import";
|
|
112
146
|
namespace: string;
|
|
@@ -115,13 +149,25 @@ export interface Import extends AST {
|
|
|
115
149
|
alias: string | null;
|
|
116
150
|
}
|
|
117
151
|
|
|
118
|
-
export type stmt =
|
|
152
|
+
export type stmt =
|
|
153
|
+
| Expr
|
|
154
|
+
| Assign
|
|
155
|
+
| ReAssign
|
|
156
|
+
| AugAssign
|
|
157
|
+
| FunctionDef
|
|
158
|
+
| TypeDef
|
|
159
|
+
| EnumDef
|
|
160
|
+
| Import
|
|
161
|
+
| Break
|
|
162
|
+
| Continue;
|
|
119
163
|
|
|
120
164
|
export interface FunctionDef extends AST {
|
|
121
165
|
kind: "FunctionDef";
|
|
122
166
|
name: string;
|
|
123
167
|
args: Param[];
|
|
124
168
|
body: stmt[];
|
|
169
|
+
/** Return type spec (`int ilog2(...)`), not a value. Engines must not eval it. */
|
|
170
|
+
returns: expr | null;
|
|
125
171
|
method: number | null;
|
|
126
172
|
export: number | null;
|
|
127
173
|
annotations: string[];
|
|
@@ -256,6 +302,12 @@ export interface Switch extends AST {
|
|
|
256
302
|
subject: expr | null;
|
|
257
303
|
}
|
|
258
304
|
|
|
305
|
+
export interface Once extends AST {
|
|
306
|
+
kind: "Once";
|
|
307
|
+
test: expr | null;
|
|
308
|
+
body: stmt[];
|
|
309
|
+
}
|
|
310
|
+
|
|
259
311
|
export interface Case extends AST {
|
|
260
312
|
kind: "Case";
|
|
261
313
|
body: stmt[];
|
|
@@ -292,7 +344,11 @@ export type expr =
|
|
|
292
344
|
| ForIn
|
|
293
345
|
| While
|
|
294
346
|
| Switch
|
|
295
|
-
|
|
|
347
|
+
| Once
|
|
348
|
+
| BoolOp
|
|
349
|
+
| Qualify
|
|
350
|
+
| Specialize
|
|
351
|
+
| AugAssign;
|
|
296
352
|
|
|
297
353
|
export interface Load extends AST {
|
|
298
354
|
kind: "Load";
|
|
@@ -316,7 +372,34 @@ export interface Div extends AST {
|
|
|
316
372
|
export interface Mod extends AST {
|
|
317
373
|
kind: "Mod";
|
|
318
374
|
}
|
|
319
|
-
export
|
|
375
|
+
export interface BitAnd extends AST {
|
|
376
|
+
kind: "BitAnd";
|
|
377
|
+
}
|
|
378
|
+
export interface BitOr extends AST {
|
|
379
|
+
kind: "BitOr";
|
|
380
|
+
}
|
|
381
|
+
export interface BitXor extends AST {
|
|
382
|
+
kind: "BitXor";
|
|
383
|
+
}
|
|
384
|
+
export interface LShift extends AST {
|
|
385
|
+
kind: "LShift";
|
|
386
|
+
}
|
|
387
|
+
export interface RShift extends AST {
|
|
388
|
+
kind: "RShift";
|
|
389
|
+
}
|
|
390
|
+
export type operator = Add | Sub | Mult | Div | Mod | BitAnd | BitOr | BitXor | LShift | RShift;
|
|
391
|
+
|
|
392
|
+
export interface Qualify extends AST {
|
|
393
|
+
kind: "Qualify";
|
|
394
|
+
qualifier: type_qual;
|
|
395
|
+
value: expr;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export interface Specialize extends AST {
|
|
399
|
+
kind: "Specialize";
|
|
400
|
+
value: expr;
|
|
401
|
+
args: expr | null;
|
|
402
|
+
}
|
|
320
403
|
|
|
321
404
|
export interface UAdd extends AST {
|
|
322
405
|
kind: "UAdd";
|
|
@@ -369,6 +452,15 @@ export const Sub: Sub = { kind: "Sub" };
|
|
|
369
452
|
export const Mult: Mult = { kind: "Mult" };
|
|
370
453
|
export const Div: Div = { kind: "Div" };
|
|
371
454
|
export const Mod: Mod = { kind: "Mod" };
|
|
455
|
+
export const BitAnd: BitAnd = { kind: "BitAnd" };
|
|
456
|
+
export const BitOr: BitOr = { kind: "BitOr" };
|
|
457
|
+
export const BitXor: BitXor = { kind: "BitXor" };
|
|
458
|
+
export const LShift: LShift = { kind: "LShift" };
|
|
459
|
+
export const RShift: RShift = { kind: "RShift" };
|
|
460
|
+
export const Const: Const = { kind: "Const" };
|
|
461
|
+
export const Input: Input = { kind: "Input" };
|
|
462
|
+
export const Simple: Simple = { kind: "Simple" };
|
|
463
|
+
export const Series: Series = { kind: "Series" };
|
|
372
464
|
export const UAdd: UAdd = { kind: "UAdd" };
|
|
373
465
|
export const USub: USub = { kind: "USub" };
|
|
374
466
|
export const NotOp: Not = { kind: "Not" };
|
|
@@ -449,6 +541,18 @@ export function reAssign(target: expr, value: expr): ReAssign {
|
|
|
449
541
|
return { kind: "ReAssign", target, value };
|
|
450
542
|
}
|
|
451
543
|
|
|
544
|
+
export function augAssign(target: expr, op: operator, value: expr): AugAssign {
|
|
545
|
+
return { kind: "AugAssign", target, op, value };
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export function qualify(qualifier: type_qual, value: expr): Qualify {
|
|
549
|
+
return { kind: "Qualify", qualifier, value };
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export function specialize(value: expr, args: expr | null = null): Specialize {
|
|
553
|
+
return { kind: "Specialize", value, args };
|
|
554
|
+
}
|
|
555
|
+
|
|
452
556
|
export function functionDef(
|
|
453
557
|
name: string,
|
|
454
558
|
args: Param[] = [],
|
|
@@ -456,12 +560,14 @@ export function functionDef(
|
|
|
456
560
|
method: number | null = null,
|
|
457
561
|
exported: number | null = null,
|
|
458
562
|
annotations: string[] = [],
|
|
563
|
+
returns: expr | null = null,
|
|
459
564
|
): FunctionDef {
|
|
460
565
|
return {
|
|
461
566
|
kind: "FunctionDef",
|
|
462
567
|
name,
|
|
463
568
|
args,
|
|
464
569
|
body,
|
|
570
|
+
returns,
|
|
465
571
|
method,
|
|
466
572
|
export: exported,
|
|
467
573
|
annotations,
|
|
@@ -548,6 +654,10 @@ export function caseNode(body: stmt[] = [], pattern: expr | null = null): Case {
|
|
|
548
654
|
return { kind: "Case", body, pattern };
|
|
549
655
|
}
|
|
550
656
|
|
|
657
|
+
export function onceExpr(test: expr | null = null, body: stmt[] = []): Once {
|
|
658
|
+
return { kind: "Once", test, body };
|
|
659
|
+
}
|
|
660
|
+
|
|
551
661
|
export function boolOp(op: bool_op, values: expr[] = []): BoolOp {
|
|
552
662
|
return { kind: "BoolOp", op, values };
|
|
553
663
|
}
|