tova 0.2.9 → 0.3.1

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/src/parser/ast.js CHANGED
@@ -77,9 +77,10 @@ export class LetDestructure {
77
77
  }
78
78
 
79
79
  export class FunctionDeclaration {
80
- constructor(name, params, body, returnType, loc, isAsync = false) {
80
+ constructor(name, params, body, returnType, loc, isAsync = false, typeParams = []) {
81
81
  this.type = 'FunctionDeclaration';
82
82
  this.name = name;
83
+ this.typeParams = typeParams; // Array of type parameter names (generics)
83
84
  this.params = params; // Array of Parameter nodes
84
85
  this.body = body; // BlockStatement or Expression (implicit return)
85
86
  this.returnType = returnType; // optional type annotation
@@ -198,21 +199,34 @@ export class IfStatement {
198
199
  }
199
200
 
200
201
  export class ForStatement {
201
- constructor(variable, iterable, body, elseBody, loc) {
202
+ constructor(variable, iterable, body, elseBody, loc, guard = null, label = null, isAsync = false) {
202
203
  this.type = 'ForStatement';
203
204
  this.variable = variable; // Identifier or destructure pattern
204
205
  this.iterable = iterable; // Expression
205
206
  this.body = body; // BlockStatement
206
207
  this.elseBody = elseBody; // BlockStatement or null (for-else)
208
+ this.guard = guard; // Expression or null (when guard)
209
+ this.label = label; // string or null (for named loops)
210
+ this.isAsync = isAsync; // true for `async for x in stream`
207
211
  this.loc = loc;
208
212
  }
209
213
  }
210
214
 
211
215
  export class WhileStatement {
212
- constructor(condition, body, loc) {
216
+ constructor(condition, body, loc, label = null) {
213
217
  this.type = 'WhileStatement';
214
218
  this.condition = condition;
215
219
  this.body = body;
220
+ this.label = label; // string or null (for named loops)
221
+ this.loc = loc;
222
+ }
223
+ }
224
+
225
+ export class LoopStatement {
226
+ constructor(body, label, loc) {
227
+ this.type = 'LoopStatement';
228
+ this.body = body; // BlockStatement
229
+ this.label = label; // string or null (for named loops)
216
230
  this.loc = loc;
217
231
  }
218
232
  }
@@ -240,15 +254,17 @@ export class TryCatchStatement {
240
254
  }
241
255
 
242
256
  export class BreakStatement {
243
- constructor(loc) {
257
+ constructor(loc, label = null) {
244
258
  this.type = 'BreakStatement';
259
+ this.label = label; // string or null (for named break)
245
260
  this.loc = loc;
246
261
  }
247
262
  }
248
263
 
249
264
  export class ContinueStatement {
250
- constructor(loc) {
265
+ constructor(loc, label = null) {
251
266
  this.type = 'ContinueStatement';
267
+ this.label = label; // string or null (for named continue)
252
268
  this.loc = loc;
253
269
  }
254
270
  }
@@ -521,6 +537,16 @@ export class DictComprehension {
521
537
  }
522
538
  }
523
539
 
540
+ export class IsExpression {
541
+ constructor(value, typeName, negated, loc) {
542
+ this.type = 'IsExpression';
543
+ this.value = value;
544
+ this.typeName = typeName; // string: "String", "Int", "Nil", etc.
545
+ this.negated = negated; // true for "is not"
546
+ this.loc = loc;
547
+ }
548
+ }
549
+
524
550
  export class MembershipExpression {
525
551
  constructor(value, collection, negated, loc) {
526
552
  this.type = 'MembershipExpression';
@@ -630,368 +656,49 @@ export class RangePattern {
630
656
  }
631
657
 
632
658
  // ============================================================
633
- // Client-specific nodes
659
+ // Client-specific nodes (lazy-loaded from client-ast.js, re-exported for backward compat)
634
660
  // ============================================================
635
661
 
636
- export class StateDeclaration {
637
- constructor(name, typeAnnotation, initialValue, loc) {
638
- this.type = 'StateDeclaration';
639
- this.name = name;
640
- this.typeAnnotation = typeAnnotation;
641
- this.initialValue = initialValue;
642
- this.loc = loc;
643
- }
644
- }
645
-
646
- export class ComputedDeclaration {
647
- constructor(name, expression, loc) {
648
- this.type = 'ComputedDeclaration';
649
- this.name = name;
650
- this.expression = expression;
651
- this.loc = loc;
652
- }
653
- }
654
-
655
- export class EffectDeclaration {
656
- constructor(body, loc) {
657
- this.type = 'EffectDeclaration';
658
- this.body = body;
659
- this.loc = loc;
660
- }
661
- }
662
-
663
- export class ComponentDeclaration {
664
- constructor(name, params, body, loc) {
665
- this.type = 'ComponentDeclaration';
666
- this.name = name;
667
- this.params = params;
668
- this.body = body; // Array of JSX elements and statements
669
- this.loc = loc;
670
- }
671
- }
672
-
673
- export class ComponentStyleBlock {
674
- constructor(css, loc) {
675
- this.type = 'ComponentStyleBlock';
676
- this.css = css; // raw CSS string
677
- this.loc = loc;
678
- }
679
- }
680
-
681
- export class StoreDeclaration {
682
- constructor(name, body, loc) {
683
- this.type = 'StoreDeclaration';
684
- this.name = name; // e.g. "TodoStore"
685
- this.body = body; // Array of StateDeclaration, ComputedDeclaration, FunctionDeclaration
686
- this.loc = loc;
687
- }
688
- }
662
+ export {
663
+ StateDeclaration, ComputedDeclaration, EffectDeclaration,
664
+ ComponentDeclaration, ComponentStyleBlock, StoreDeclaration,
665
+ JSXElement, JSXAttribute, JSXSpreadAttribute, JSXFragment,
666
+ JSXText, JSXExpression, JSXFor, JSXIf,
667
+ } from './client-ast.js';
689
668
 
690
669
  // ============================================================
691
- // JSX-like nodes
670
+ // Server-specific nodes (lazy-loaded from server-ast.js, re-exported for backward compat)
692
671
  // ============================================================
693
672
 
694
- export class JSXElement {
695
- constructor(tag, attributes, children, selfClosing, loc) {
696
- this.type = 'JSXElement';
697
- this.tag = tag;
698
- this.attributes = attributes; // Array of JSXAttribute
699
- this.children = children; // Array of JSXElement, JSXText, JSXExpression
700
- this.selfClosing = selfClosing;
701
- this.loc = loc;
702
- }
703
- }
704
-
705
- export class JSXAttribute {
706
- constructor(name, value, loc) {
707
- this.type = 'JSXAttribute';
708
- this.name = name; // string (e.g., "class", "on:click")
709
- this.value = value; // Expression or string
710
- this.loc = loc;
711
- }
712
- }
713
-
714
- export class JSXSpreadAttribute {
715
- constructor(expression, loc) {
716
- this.type = 'JSXSpreadAttribute';
717
- this.expression = expression;
718
- this.loc = loc;
719
- }
720
- }
721
-
722
- export class JSXText {
723
- constructor(value, loc) {
724
- this.type = 'JSXText';
725
- this.value = value;
726
- this.loc = loc;
727
- }
728
- }
729
-
730
- export class JSXExpression {
731
- constructor(expression, loc) {
732
- this.type = 'JSXExpression';
733
- this.expression = expression;
734
- this.loc = loc;
735
- }
736
- }
737
-
738
- export class JSXFor {
739
- constructor(variable, iterable, body, loc, keyExpr = null) {
740
- this.type = 'JSXFor';
741
- this.variable = variable;
742
- this.iterable = iterable;
743
- this.body = body;
744
- this.keyExpr = keyExpr; // optional key expression for keyed reconciliation
745
- this.loc = loc;
746
- }
747
- }
748
-
749
- export class JSXIf {
750
- constructor(condition, consequent, alternate, loc, alternates = []) {
751
- this.type = 'JSXIf';
752
- this.condition = condition;
753
- this.consequent = consequent;
754
- this.alternates = alternates; // Array of { condition, body } for elif chains
755
- this.alternate = alternate; // else body (or null)
756
- this.loc = loc;
757
- }
758
- }
759
-
760
- // ============================================================
761
- // Server-specific nodes
762
- // ============================================================
763
-
764
- export class RouteDeclaration {
765
- constructor(method, path, handler, loc, decorators = []) {
766
- this.type = 'RouteDeclaration';
767
- this.method = method; // GET, POST, PUT, DELETE, PATCH
768
- this.path = path; // string literal
769
- this.handler = handler; // Identifier or FunctionDeclaration
770
- this.decorators = decorators; // Array of { name, args } for "with auth, role("admin")"
771
- this.loc = loc;
772
- }
773
- }
774
-
775
- export class MiddlewareDeclaration {
776
- constructor(name, params, body, loc) {
777
- this.type = 'MiddlewareDeclaration';
778
- this.name = name;
779
- this.params = params; // Array of Parameter nodes (req, next)
780
- this.body = body; // BlockStatement
781
- this.loc = loc;
782
- }
783
- }
784
-
785
- export class HealthCheckDeclaration {
786
- constructor(path, loc) {
787
- this.type = 'HealthCheckDeclaration';
788
- this.path = path; // string literal, e.g. "/health"
789
- this.loc = loc;
790
- }
791
- }
792
-
793
- export class CorsDeclaration {
794
- constructor(config, loc) {
795
- this.type = 'CorsDeclaration';
796
- this.config = config; // { origins: ArrayLiteral, methods: ArrayLiteral, headers: ArrayLiteral }
797
- this.loc = loc;
798
- }
799
- }
800
-
801
- export class ErrorHandlerDeclaration {
802
- constructor(params, body, loc) {
803
- this.type = 'ErrorHandlerDeclaration';
804
- this.params = params; // Array of Parameter nodes (err, req)
805
- this.body = body; // BlockStatement
806
- this.loc = loc;
807
- }
808
- }
809
-
810
- export class WebSocketDeclaration {
811
- constructor(handlers, loc, config = null) {
812
- this.type = 'WebSocketDeclaration';
813
- this.handlers = handlers; // { on_open, on_message, on_close, on_error } — each is { params, body } or null
814
- this.config = config; // { auth: expression } or null
815
- this.loc = loc;
816
- }
817
- }
818
-
819
- export class StaticDeclaration {
820
- constructor(path, dir, loc, fallback = null) {
821
- this.type = 'StaticDeclaration';
822
- this.path = path; // URL prefix, e.g. "/public"
823
- this.dir = dir; // directory path, e.g. "./public"
824
- this.fallback = fallback; // fallback file, e.g. "index.html"
825
- this.loc = loc;
826
- }
827
- }
828
-
829
- export class DiscoverDeclaration {
830
- constructor(peerName, urlExpression, loc, config = null) {
831
- this.type = 'DiscoverDeclaration';
832
- this.peerName = peerName; // string — the peer server name
833
- this.urlExpression = urlExpression; // Expression — the URL
834
- this.config = config; // { threshold, timeout } or null
835
- this.loc = loc;
836
- }
837
- }
838
-
839
- export class AuthDeclaration {
840
- constructor(config, loc) {
841
- this.type = 'AuthDeclaration';
842
- this.config = config; // { type, secret, ... } object config
843
- this.loc = loc;
844
- }
845
- }
846
-
847
- export class MaxBodyDeclaration {
848
- constructor(limit, loc) {
849
- this.type = 'MaxBodyDeclaration';
850
- this.limit = limit; // Expression — max body size in bytes
851
- this.loc = loc;
852
- }
853
- }
854
-
855
- export class RouteGroupDeclaration {
856
- constructor(prefix, body, loc) {
857
- this.type = 'RouteGroupDeclaration';
858
- this.prefix = prefix; // string — URL prefix, e.g. "/api/v1"
859
- this.body = body; // Array of server statements
860
- this.loc = loc;
861
- }
862
- }
673
+ export {
674
+ RouteDeclaration, MiddlewareDeclaration, HealthCheckDeclaration,
675
+ CorsDeclaration, ErrorHandlerDeclaration, WebSocketDeclaration,
676
+ StaticDeclaration, DiscoverDeclaration, AuthDeclaration,
677
+ MaxBodyDeclaration, RouteGroupDeclaration, RateLimitDeclaration,
678
+ LifecycleHookDeclaration, SubscribeDeclaration, EnvDeclaration,
679
+ ScheduleDeclaration, UploadDeclaration, SessionDeclaration,
680
+ DbDeclaration, TlsDeclaration, CompressionDeclaration,
681
+ BackgroundJobDeclaration, CacheDeclaration, SseDeclaration,
682
+ ModelDeclaration, AiConfigDeclaration,
683
+ } from './server-ast.js';
863
684
 
864
- export class RateLimitDeclaration {
865
- constructor(config, loc) {
866
- this.type = 'RateLimitDeclaration';
867
- this.config = config;
868
- this.loc = loc;
869
- }
870
- }
871
-
872
- export class LifecycleHookDeclaration {
873
- constructor(hook, params, body, loc) {
874
- this.type = 'LifecycleHookDeclaration';
875
- this.hook = hook; // "start" or "stop"
876
- this.params = params;
877
- this.body = body;
878
- this.loc = loc;
879
- }
880
- }
881
-
882
- export class SubscribeDeclaration {
883
- constructor(event, params, body, loc) {
884
- this.type = 'SubscribeDeclaration';
885
- this.event = event; // string — event name
886
- this.params = params;
887
- this.body = body;
888
- this.loc = loc;
889
- }
890
- }
891
-
892
- export class EnvDeclaration {
893
- constructor(name, typeAnnotation, defaultValue, loc) {
894
- this.type = 'EnvDeclaration';
895
- this.name = name;
896
- this.typeAnnotation = typeAnnotation;
897
- this.defaultValue = defaultValue;
898
- this.loc = loc;
899
- }
900
- }
901
-
902
- export class ScheduleDeclaration {
903
- constructor(pattern, name, params, body, loc) {
904
- this.type = 'ScheduleDeclaration';
905
- this.pattern = pattern; // string — interval or cron pattern
906
- this.name = name; // optional function name
907
- this.params = params;
908
- this.body = body;
909
- this.loc = loc;
910
- }
911
- }
912
-
913
- export class UploadDeclaration {
914
- constructor(config, loc) {
915
- this.type = 'UploadDeclaration';
916
- this.config = config; // { max_size, allowed_types, ... }
917
- this.loc = loc;
918
- }
919
- }
920
-
921
- export class SessionDeclaration {
922
- constructor(config, loc) {
923
- this.type = 'SessionDeclaration';
924
- this.config = config; // { secret, max_age, cookie_name, ... }
925
- this.loc = loc;
926
- }
927
- }
928
-
929
- export class DbDeclaration {
930
- constructor(config, loc) {
931
- this.type = 'DbDeclaration';
932
- this.config = config; // { path, wal, ... }
933
- this.loc = loc;
934
- }
935
- }
936
-
937
- export class TlsDeclaration {
938
- constructor(config, loc) {
939
- this.type = 'TlsDeclaration';
940
- this.config = config; // { cert, key, ... }
941
- this.loc = loc;
942
- }
943
- }
944
-
945
- export class CompressionDeclaration {
946
- constructor(config, loc) {
947
- this.type = 'CompressionDeclaration';
948
- this.config = config; // { enabled, min_size, ... }
949
- this.loc = loc;
950
- }
951
- }
952
-
953
- export class BackgroundJobDeclaration {
954
- constructor(name, params, body, loc) {
955
- this.type = 'BackgroundJobDeclaration';
956
- this.name = name;
957
- this.params = params;
958
- this.body = body;
959
- this.loc = loc;
960
- }
961
- }
962
-
963
- export class CacheDeclaration {
964
- constructor(config, loc) {
965
- this.type = 'CacheDeclaration';
966
- this.config = config; // { max_age, stale_while_revalidate, ... }
967
- this.loc = loc;
968
- }
969
- }
970
-
971
- export class SseDeclaration {
972
- constructor(path, params, body, loc) {
973
- this.type = 'SseDeclaration';
974
- this.path = path; // string — SSE endpoint path
975
- this.params = params; // Array of Parameter nodes
976
- this.body = body; // BlockStatement
977
- this.loc = loc;
978
- }
979
- }
980
-
981
- export class ModelDeclaration {
982
- constructor(name, config, loc) {
983
- this.type = 'ModelDeclaration';
984
- this.name = name; // string — type name to generate CRUD for
985
- this.config = config; // { table, timestamps, ... } or null
685
+ export class TestBlock {
686
+ constructor(name, body, loc, options = {}) {
687
+ this.type = 'TestBlock';
688
+ this.name = name; // optional string name
689
+ this.body = body; // Array of statements
690
+ this.timeout = options.timeout || null; // optional timeout in ms
691
+ this.beforeEach = options.beforeEach || null; // Array of statements or null
692
+ this.afterEach = options.afterEach || null; // Array of statements or null
986
693
  this.loc = loc;
987
694
  }
988
695
  }
989
696
 
990
- export class TestBlock {
697
+ export class BenchBlock {
991
698
  constructor(name, body, loc) {
992
- this.type = 'TestBlock';
699
+ this.type = 'BenchBlock';
993
700
  this.name = name; // optional string name
994
- this.body = body; // Array of statements
701
+ this.body = body; // Array of statements (expressions to benchmark)
995
702
  this.loc = loc;
996
703
  }
997
704
  }
@@ -1041,6 +748,14 @@ export class FunctionTypeAnnotation {
1041
748
  }
1042
749
  }
1043
750
 
751
+ export class UnionTypeAnnotation {
752
+ constructor(members, loc) {
753
+ this.type = 'UnionTypeAnnotation';
754
+ this.members = members; // Array of TypeAnnotation nodes
755
+ this.loc = loc;
756
+ }
757
+ }
758
+
1044
759
  // ============================================================
1045
760
  // Impl blocks
1046
761
  // ============================================================
@@ -1073,9 +788,10 @@ export class TraitDeclaration {
1073
788
  // ============================================================
1074
789
 
1075
790
  export class TypeAlias {
1076
- constructor(name, typeExpr, loc) {
791
+ constructor(name, typeParams, typeExpr, loc) {
1077
792
  this.type = 'TypeAlias';
1078
793
  this.name = name;
794
+ this.typeParams = typeParams; // Array of type parameter names (for generics)
1079
795
  this.typeExpr = typeExpr; // TypeAnnotation
1080
796
  this.loc = loc;
1081
797
  }
@@ -1085,6 +801,16 @@ export class TypeAlias {
1085
801
  // Defer statement
1086
802
  // ============================================================
1087
803
 
804
+ export class WithStatement {
805
+ constructor(expression, name, body, loc) {
806
+ this.type = 'WithStatement';
807
+ this.expression = expression; // resource expression
808
+ this.name = name; // binding name (string)
809
+ this.body = body; // BlockStatement
810
+ this.loc = loc;
811
+ }
812
+ }
813
+
1088
814
  export class DeferStatement {
1089
815
  constructor(body, loc) {
1090
816
  this.type = 'DeferStatement';
@@ -1212,19 +938,6 @@ export class RefreshPolicy {
1212
938
  }
1213
939
  }
1214
940
 
1215
- // ============================================================
1216
- // AI configuration
1217
- // ============================================================
1218
-
1219
- export class AiConfigDeclaration {
1220
- constructor(name, config, loc) {
1221
- this.type = 'AiConfigDeclaration';
1222
- this.name = name; // optional string name (null for default)
1223
- this.config = config; // key-value config object
1224
- this.loc = loc;
1225
- }
1226
- }
1227
-
1228
941
  // ============================================================
1229
942
  // Refinement types
1230
943
  // ============================================================
@@ -0,0 +1,138 @@
1
+ // Client-specific AST Node definitions for the Tova language
2
+ // Extracted from ast.js for lazy loading — only loaded when client { } blocks are used.
3
+
4
+ // ============================================================
5
+ // Client-specific nodes
6
+ // ============================================================
7
+
8
+ export class StateDeclaration {
9
+ constructor(name, typeAnnotation, initialValue, loc) {
10
+ this.type = 'StateDeclaration';
11
+ this.name = name;
12
+ this.typeAnnotation = typeAnnotation;
13
+ this.initialValue = initialValue;
14
+ this.loc = loc;
15
+ }
16
+ }
17
+
18
+ export class ComputedDeclaration {
19
+ constructor(name, expression, loc) {
20
+ this.type = 'ComputedDeclaration';
21
+ this.name = name;
22
+ this.expression = expression;
23
+ this.loc = loc;
24
+ }
25
+ }
26
+
27
+ export class EffectDeclaration {
28
+ constructor(body, loc) {
29
+ this.type = 'EffectDeclaration';
30
+ this.body = body;
31
+ this.loc = loc;
32
+ }
33
+ }
34
+
35
+ export class ComponentDeclaration {
36
+ constructor(name, params, body, loc) {
37
+ this.type = 'ComponentDeclaration';
38
+ this.name = name;
39
+ this.params = params;
40
+ this.body = body; // Array of JSX elements and statements
41
+ this.loc = loc;
42
+ }
43
+ }
44
+
45
+ export class ComponentStyleBlock {
46
+ constructor(css, loc) {
47
+ this.type = 'ComponentStyleBlock';
48
+ this.css = css; // raw CSS string
49
+ this.loc = loc;
50
+ }
51
+ }
52
+
53
+ export class StoreDeclaration {
54
+ constructor(name, body, loc) {
55
+ this.type = 'StoreDeclaration';
56
+ this.name = name; // e.g. "TodoStore"
57
+ this.body = body; // Array of StateDeclaration, ComputedDeclaration, FunctionDeclaration
58
+ this.loc = loc;
59
+ }
60
+ }
61
+
62
+ // ============================================================
63
+ // JSX-like nodes
64
+ // ============================================================
65
+
66
+ export class JSXElement {
67
+ constructor(tag, attributes, children, selfClosing, loc) {
68
+ this.type = 'JSXElement';
69
+ this.tag = tag;
70
+ this.attributes = attributes; // Array of JSXAttribute
71
+ this.children = children; // Array of JSXElement, JSXText, JSXExpression
72
+ this.selfClosing = selfClosing;
73
+ this.loc = loc;
74
+ }
75
+ }
76
+
77
+ export class JSXAttribute {
78
+ constructor(name, value, loc) {
79
+ this.type = 'JSXAttribute';
80
+ this.name = name; // string (e.g., "class", "on:click")
81
+ this.value = value; // Expression or string
82
+ this.loc = loc;
83
+ }
84
+ }
85
+
86
+ export class JSXSpreadAttribute {
87
+ constructor(expression, loc) {
88
+ this.type = 'JSXSpreadAttribute';
89
+ this.expression = expression;
90
+ this.loc = loc;
91
+ }
92
+ }
93
+
94
+ export class JSXFragment {
95
+ constructor(children, loc) {
96
+ this.type = 'JSXFragment';
97
+ this.children = children; // Array of JSXElement, JSXText, JSXExpression, etc.
98
+ this.loc = loc;
99
+ }
100
+ }
101
+
102
+ export class JSXText {
103
+ constructor(value, loc) {
104
+ this.type = 'JSXText';
105
+ this.value = value;
106
+ this.loc = loc;
107
+ }
108
+ }
109
+
110
+ export class JSXExpression {
111
+ constructor(expression, loc) {
112
+ this.type = 'JSXExpression';
113
+ this.expression = expression;
114
+ this.loc = loc;
115
+ }
116
+ }
117
+
118
+ export class JSXFor {
119
+ constructor(variable, iterable, body, loc, keyExpr = null) {
120
+ this.type = 'JSXFor';
121
+ this.variable = variable;
122
+ this.iterable = iterable;
123
+ this.body = body;
124
+ this.keyExpr = keyExpr; // optional key expression for keyed reconciliation
125
+ this.loc = loc;
126
+ }
127
+ }
128
+
129
+ export class JSXIf {
130
+ constructor(condition, consequent, alternate, loc, alternates = []) {
131
+ this.type = 'JSXIf';
132
+ this.condition = condition;
133
+ this.consequent = consequent;
134
+ this.alternates = alternates; // Array of { condition, body } for elif chains
135
+ this.alternate = alternate; // else body (or null)
136
+ this.loc = loc;
137
+ }
138
+ }