novac 2.0.1 → 2.2.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.
Files changed (161) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1574 -597
  3. package/bin/novac +468 -171
  4. package/bin/nvc +522 -0
  5. package/bin/nvml +78 -17
  6. package/demo.nv +0 -0
  7. package/demo_builtins.nv +0 -0
  8. package/demo_http.nv +0 -0
  9. package/examples/bf.nv +69 -0
  10. package/examples/math.nv +21 -0
  11. package/kits/birdAPI/kitdef.js +954 -0
  12. package/kits/kitRNG/kitdef.js +740 -0
  13. package/kits/kitSSH/kitdef.js +1272 -0
  14. package/kits/kitadb/kitdef.js +606 -0
  15. package/kits/kitai/kitdef.js +2185 -0
  16. package/kits/kitansi/kitdef.js +1402 -0
  17. package/kits/kitcanvas/kitdef.js +914 -0
  18. package/kits/kitclippy/kitdef.js +925 -0
  19. package/kits/kitformat/kitdef.js +1485 -0
  20. package/kits/kitgps/kitdef.js +1862 -0
  21. package/kits/kitlibproc/kitdef.js +3 -2
  22. package/kits/kitmatrix/ex.js +19 -0
  23. package/kits/kitmatrix/kitdef.js +960 -0
  24. package/kits/kitmorse/kitdef.js +229 -0
  25. package/kits/kitmpatch/kitdef.js +906 -0
  26. package/kits/kitnet/kitdef.js +1401 -0
  27. package/kits/kitnovacweb/README.md +1416 -143
  28. package/kits/kitnovacweb/kitdef.js +92 -2
  29. package/kits/kitnovacweb/nvml/executor.js +578 -176
  30. package/kits/kitnovacweb/nvml/index.js +2 -2
  31. package/kits/kitnovacweb/nvml/lexer.js +72 -69
  32. package/kits/kitnovacweb/nvml/parser.js +328 -159
  33. package/kits/kitnovacweb/nvml/renderer.js +770 -270
  34. package/kits/kitparse/kitdef.js +1688 -0
  35. package/kits/kitproto/kitdef.js +613 -0
  36. package/kits/kitqr/kitdef.js +637 -0
  37. package/kits/kitregex++/kitdef.js +1353 -0
  38. package/kits/kitrequire/kitdef.js +1599 -0
  39. package/kits/kitx11/kitdef.js +1 -0
  40. package/kits/kitx11/kitx11.js +2472 -0
  41. package/kits/kitx11/kitx11_conn.js +948 -0
  42. package/kits/kitx11/kitx11_worker.js +121 -0
  43. package/kits/libtea/kitdef.js +2691 -0
  44. package/kits/libterm/ex.js +285 -0
  45. package/kits/libterm/kitdef.js +1927 -0
  46. package/novac/LICENSE +21 -0
  47. package/novac/README.md +1823 -0
  48. package/novac/bin/novac +950 -0
  49. package/novac/bin/nvc +522 -0
  50. package/novac/bin/nvml +542 -0
  51. package/novac/demo.nv +245 -0
  52. package/novac/demo_builtins.nv +209 -0
  53. package/novac/demo_http.nv +62 -0
  54. package/novac/examples/bf.nv +69 -0
  55. package/novac/examples/math.nv +21 -0
  56. package/novac/kits/kitai/kitdef.js +2185 -0
  57. package/novac/kits/kitansi/kitdef.js +1402 -0
  58. package/novac/kits/kitformat/kitdef.js +1485 -0
  59. package/novac/kits/kitgps/kitdef.js +1862 -0
  60. package/novac/kits/kitlibfs/kitdef.js +231 -0
  61. package/{examples/example-project/nova_modules → novac/kits}/kitlibproc/kitdef.js +3 -2
  62. package/novac/kits/kitmatrix/ex.js +19 -0
  63. package/novac/kits/kitmatrix/kitdef.js +960 -0
  64. package/novac/kits/kitmpatch/kitdef.js +906 -0
  65. package/novac/kits/kitnovacweb/README.md +1572 -0
  66. package/novac/kits/kitnovacweb/demo.nv +12 -0
  67. package/novac/kits/kitnovacweb/demo.nvml +71 -0
  68. package/novac/kits/kitnovacweb/index.nova +12 -0
  69. package/novac/kits/kitnovacweb/kitdef.js +692 -0
  70. package/novac/kits/kitnovacweb/nova.kit.json +8 -0
  71. package/novac/kits/kitnovacweb/nvml/executor.js +739 -0
  72. package/novac/kits/kitnovacweb/nvml/index.js +67 -0
  73. package/novac/kits/kitnovacweb/nvml/lexer.js +263 -0
  74. package/novac/kits/kitnovacweb/nvml/parser.js +508 -0
  75. package/novac/kits/kitnovacweb/nvml/renderer.js +924 -0
  76. package/novac/kits/kitparse/kitdef.js +1688 -0
  77. package/novac/kits/kitregex++/kitdef.js +1353 -0
  78. package/novac/kits/kitrequire/kitdef.js +1599 -0
  79. package/novac/kits/kitx11/kitdef.js +1 -0
  80. package/novac/kits/kitx11/kitx11.js +2472 -0
  81. package/novac/kits/kitx11/kitx11_conn.js +948 -0
  82. package/novac/kits/kitx11/kitx11_worker.js +121 -0
  83. package/novac/kits/libtea/tf.js +2691 -0
  84. package/novac/kits/libterm/ex.js +285 -0
  85. package/novac/kits/libterm/kitdef.js +1927 -0
  86. package/novac/node_modules/chalk/license +9 -0
  87. package/novac/node_modules/chalk/package.json +83 -0
  88. package/novac/node_modules/chalk/readme.md +297 -0
  89. package/novac/node_modules/chalk/source/index.d.ts +325 -0
  90. package/novac/node_modules/chalk/source/index.js +225 -0
  91. package/novac/node_modules/chalk/source/utilities.js +33 -0
  92. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
  93. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
  94. package/novac/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
  95. package/novac/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
  96. package/novac/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
  97. package/novac/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
  98. package/novac/node_modules/commander/LICENSE +22 -0
  99. package/novac/node_modules/commander/Readme.md +1176 -0
  100. package/novac/node_modules/commander/esm.mjs +16 -0
  101. package/novac/node_modules/commander/index.js +24 -0
  102. package/novac/node_modules/commander/lib/argument.js +150 -0
  103. package/novac/node_modules/commander/lib/command.js +2777 -0
  104. package/novac/node_modules/commander/lib/error.js +39 -0
  105. package/novac/node_modules/commander/lib/help.js +747 -0
  106. package/novac/node_modules/commander/lib/option.js +380 -0
  107. package/novac/node_modules/commander/lib/suggestSimilar.js +101 -0
  108. package/novac/node_modules/commander/package-support.json +19 -0
  109. package/novac/node_modules/commander/package.json +82 -0
  110. package/novac/node_modules/commander/typings/esm.d.mts +3 -0
  111. package/novac/node_modules/commander/typings/index.d.ts +1113 -0
  112. package/novac/node_modules/node-addon-api/LICENSE.md +9 -0
  113. package/novac/node_modules/node-addon-api/README.md +95 -0
  114. package/novac/node_modules/node-addon-api/common.gypi +21 -0
  115. package/novac/node_modules/node-addon-api/except.gypi +25 -0
  116. package/novac/node_modules/node-addon-api/index.js +14 -0
  117. package/novac/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
  118. package/novac/node_modules/node-addon-api/napi-inl.h +7165 -0
  119. package/novac/node_modules/node-addon-api/napi.h +3364 -0
  120. package/novac/node_modules/node-addon-api/node_addon_api.gyp +42 -0
  121. package/novac/node_modules/node-addon-api/node_api.gyp +9 -0
  122. package/novac/node_modules/node-addon-api/noexcept.gypi +26 -0
  123. package/novac/node_modules/node-addon-api/package-support.json +21 -0
  124. package/novac/node_modules/node-addon-api/package.json +480 -0
  125. package/novac/node_modules/node-addon-api/tools/README.md +73 -0
  126. package/novac/node_modules/node-addon-api/tools/check-napi.js +99 -0
  127. package/novac/node_modules/node-addon-api/tools/clang-format.js +71 -0
  128. package/novac/node_modules/node-addon-api/tools/conversion.js +301 -0
  129. package/novac/node_modules/serialize-javascript/LICENSE +27 -0
  130. package/novac/node_modules/serialize-javascript/README.md +149 -0
  131. package/novac/node_modules/serialize-javascript/index.js +297 -0
  132. package/novac/node_modules/serialize-javascript/package.json +33 -0
  133. package/novac/package.json +27 -0
  134. package/novac/scripts/update-bin.js +24 -0
  135. package/novac/src/core/bstd.js +1035 -0
  136. package/novac/src/core/config.js +155 -0
  137. package/novac/src/core/describe.js +187 -0
  138. package/novac/src/core/emitter.js +499 -0
  139. package/novac/src/core/error.js +86 -0
  140. package/novac/src/core/executor.js +5606 -0
  141. package/novac/src/core/formatter.js +686 -0
  142. package/novac/src/core/lexer.js +1026 -0
  143. package/novac/src/core/nova_builtins.js +717 -0
  144. package/novac/src/core/nova_thread_worker.js +166 -0
  145. package/novac/src/core/parser.js +2181 -0
  146. package/novac/src/core/types.js +112 -0
  147. package/novac/src/index.js +28 -0
  148. package/novac/src/runtime/stdlib.js +244 -0
  149. package/package.json +6 -3
  150. package/scripts/update-bin.js +0 -0
  151. package/src/core/bstd.js +838 -362
  152. package/src/core/executor.js +2578 -170
  153. package/src/core/lexer.js +502 -54
  154. package/src/core/nova_builtins.js +21 -3
  155. package/src/core/parser.js +413 -72
  156. package/src/core/types.js +30 -2
  157. package/src/index.js +0 -0
  158. package/examples/example-project/README.md +0 -3
  159. package/examples/example-project/src/main.nova +0 -3
  160. package/src/core/environment.js +0 -0
  161. /package/{examples/example-project/bin/example-project.nv → novac/node_modules/node-addon-api/nothing.c} +0 -0
package/novac/demo.nv ADDED
@@ -0,0 +1,245 @@
1
+ /! Nova Language v2 — Feature Showcase
2
+ let tcc
3
+ on "nv:tick" (ps) {tcc++}
4
+ // ── F-Strings ──
5
+ let name = "Nova";
6
+ core.print(f"Welcome to {name} v2!");
7
+ core.print(f"2^10 = {2**10}");
8
+
9
+ // ── Structs ──
10
+ struct Vec2 {
11
+ x: int = 0,
12
+ y: int = 0
13
+ }
14
+ let pos = Vec2({ x: 3, y: 4 });
15
+ core.print(f"pos = ({pos.x}, {pos.y})");
16
+ core.print(f"typeOf pos = {typeOf(pos)}");
17
+
18
+ // ── Enums ──
19
+ enum Status { Active, Inactive, Pending }
20
+ let st = Status.Active;
21
+ core.print(f"status = {st.__variant__}");
22
+
23
+ // ── Interfaces ──
24
+ interface Serializable { serialize() }
25
+ let doc = { serialize() { give "doc-json"; } };
26
+ let isSer = satisfies(doc, "Serializable");
27
+ core.print(f"satisfies Serializable: {isSer}");
28
+
29
+ // ── Pattern matching with range patterns ──
30
+ let score = 85;
31
+ match (score) {
32
+ when 90..100 { core.print("A grade"); }
33
+ when 80..89 { core.print("B grade"); }
34
+ when 70..79 { core.print("C grade"); }
35
+ default { core.print("Below C"); }
36
+ }
37
+
38
+ // ── Pipe operator ──
39
+ func double(x) => { give x * 2; }
40
+ func addOne(x) => { give x + 1; }
41
+ let piped = 5 |> double |> addOne;
42
+ core.print(f"5 |> double |> addOne = {piped}");
43
+
44
+ // ── Each loop with index ──
45
+ let total = 0;
46
+ each n, i of [10, 20, 30, 40] {
47
+ total += n;
48
+ }
49
+ core.print(f"each total = {total}");
50
+
51
+ // ── Events ──
52
+ let tickCount = 0;
53
+ on "a" (count) {
54
+ tickCount += 1;
55
+ }
56
+ emit "a", 1;
57
+ emit "a", 2;
58
+ core.print(f"ticks received = {tickCount}");
59
+
60
+ // ── Where scoping ──
61
+ where (base = 100, taxRate = 0.15) {
62
+ let tax = base * taxRate;
63
+ print(f"tax = {tax}");
64
+ }
65
+
66
+ // ── Array methods ──
67
+ let nums = [5, 3, 8, 1, 9, 2];
68
+ let evens = nums.filter(x => x % 2 == 0);
69
+ let doubled = nums.map(x => x * 2);
70
+ let sum = nums.reduce((acc, x) => acc + x, 0);
71
+ core.print(f"evens = {evens.join(", ")}");
72
+ core.print(f"doubled = {doubled.join(", ")}");
73
+ core.print(f"sum = {sum}");
74
+ core.print(f"sorted = {nums.sort().join(", ")}");
75
+
76
+ // ── Optional chaining ──
77
+ let user = { profile: { email: "a@b.com" } };
78
+ let email = user?.profile?.email;
79
+ let phone = user?.profile?.phone ?? "N/A";
80
+ core.print(f"email = {email}");
81
+ core.print(f"phone = {phone}");
82
+
83
+ // ── Spread / rest params ──
84
+ func stats(...ns) => {
85
+ let lo = ns.reduce((a, x) => a < x ? a : x);
86
+ let hi = ns.reduce((a, x) => a > x ? a : x);
87
+ give { min: lo, max: hi };
88
+ }
89
+ let st2 = stats(3, 7, 1, 9, 4);
90
+ core.print(f"min={st2.min} max={st2.max}");
91
+
92
+ // ── Nullish / logical assignment ──
93
+ let maybe = null;
94
+ maybe ??= "default";
95
+ core.print(f"nullish assign = {maybe}");
96
+
97
+ // ── Classes with inheritance ──
98
+ class Shape {
99
+ color: "black"
100
+ describe() { core.print(f"Shape ({this.color})"); }
101
+ }
102
+ class Circle extends Shape {
103
+ radius: 5
104
+ area() { give 3.14159 * this.radius * this.radius; }
105
+ describe() {
106
+ print(f"Circle r={this.radius} color={this.color}");
107
+ }
108
+ }
109
+ let c = Circle();
110
+ c.color = "red";
111
+ c.describe();
112
+ core.print(f"circle area = {c.area()}");
113
+
114
+ // ── Switch / case ──
115
+ let day = 3;
116
+ switch (day) {
117
+ case 1: core.print("Mon"); break;
118
+ case 2: core.print("Tue"); break;
119
+ case 3: core.print("Wed"); break;
120
+ default: core.print("Other"); break;
121
+ }
122
+
123
+ // ── Bitwise + range operators ──
124
+ core.print(f"6 & 3 = {6 & 3}");
125
+ core.print(f"6 | 3 = {6 | 3}");
126
+ core.print(f"2**10 = {2**10}");
127
+ core.print(f"5 in 1..10 = {5 in 1..10}");
128
+
129
+ // ── Assert ──
130
+ assert 2 + 2 == 4, "math broken";
131
+ assert typeof "x" == "string", "typeof broken";
132
+ core.print("all assertions passed");
133
+
134
+ // ── Preprocessor ──
135
+ #define LANG Nova
136
+ #define VER 2
137
+ core.print(f"Language: {LANG} v{VER}");
138
+
139
+ /! ── Nova Classic features demo ──
140
+
141
+ // foreach loop
142
+ let scores = { alice: 95, bob: 82, carol: 71 };
143
+ foreach(scores)(name, val) {
144
+ core.print(f" {name}: {val}");
145
+ }
146
+
147
+ // temp binding
148
+ let config = "production";
149
+ temp config = "test" => {
150
+ core.print(f"in temp scope: {config}");
151
+ }
152
+ core.print(f"after temp: {config}");
153
+
154
+ // keep (set-once)
155
+ keep serverPort = 8080;
156
+ keep serverPort = 9999;
157
+ core.print(f"port stays: {serverPort}");
158
+
159
+ // macro
160
+ macro VERSION = 2;
161
+ core.print(f"Nova v{VERSION}");
162
+
163
+ // addto
164
+ let evtLog = [];
165
+ addto evtLog "startup";
166
+ addto evtLog "ready";
167
+ core.print(f"log has {evtLog.length} entries");
168
+
169
+ // lambda
170
+ lambda square = x => x * x;
171
+ core.print(f"square(7) = {square(7)}");
172
+
173
+ // compose (fn pipeline with >>)
174
+ func trim(s) => { give s; }
175
+ func shout(s) => { give f"{s}!"; }
176
+ compose announce = trim >> shout;
177
+ core.print(announce("hello"));
178
+
179
+ // partial application
180
+ func multiply(a, b) => { give a * b; }
181
+ partial triple = multiply(3);
182
+ core.print(f"triple(7) = {triple(7)}");
183
+
184
+ // backup / retrieve
185
+ let userSession = "user_abc";
186
+ backup userSession = userSession;
187
+ let userSession = "guest";
188
+ retrieve userSession;
189
+ core.print(f"restored: {userSession}");
190
+
191
+ // Nova Classic infix operators
192
+ core.print(f"7 xor 7 = {7 xor 7}");
193
+ core.print(f"true nand true = {true nand true}");
194
+ let _numtype = "number"; core.print(f"42 istypeof number = {42 istypeof _numtype}");
195
+ let _hw = "hello"; let _pat = "hel"; core.print(f"hello matches hel = {_hw matches _pat}");
196
+
197
+ // set operations
198
+ let a = [1, 2, 3, 4];
199
+ let b = [3, 4, 5, 6];
200
+ core.print(f"intersect: {a intersect b}");
201
+ core.print(f"union: {a union b}");
202
+ core.print(f"diff: {a diff_arr b}");
203
+
204
+ // zip
205
+ let pairs = [1, 2, 3] zip ["a", "b", "c"];
206
+ core.print(f"zip[0]: {pairs[0][0]}-{pairs[0][1]}");
207
+
208
+ // numeric operators
209
+ core.print(f"8 avg 12 = {8 avg 12}");
210
+ core.print(f"gcd 12 8 = {12 gcd 8}");
211
+ core.print(f"lcm 4 6 = {4 lcm 6}");
212
+
213
+ // rate casts (typed casting)
214
+ core.print(f"rate(3.7) int = {rate(3.7) int}");
215
+ core.print(f"rate(300) u8 = {rate(300) u8}");
216
+ let _s = "hi"; core.print(f"rate(hi) char = {rate(_s) char}");
217
+
218
+ // classify
219
+ core.print(f"classify 42 as int = {classify 42 as int}");
220
+ core.print(f"classify type of 42 = {classify 42}");
221
+
222
+ // QAEs — query assertions / predicates
223
+ core.print(f"qae.prime(17) = {qae.prime(17)}");
224
+ let _rc="racecar"; core.print(f"qae.palindrome(racecar) = {qae.palindrome(_rc)}");
225
+ core.print(f"qae.even(8) = {qae.even(8)}");
226
+ core.print(f"qae.ascending([1,2,3]) = {qae.ascending([1,2,3])}");
227
+
228
+ // novaRegex — semantic regex
229
+ let emailRegex = novaRegex("<email>"); let _em = "a@b.com";
230
+ core.print(f"email match: {emailRegex.test(_em)}");
231
+
232
+ // step operator (range with step)
233
+ let evens = 0..10 step 2;
234
+ core.print(f"evens[0..3]: {evens[0]} {evens[1]} {evens[2]}");
235
+
236
+ // extend (object merge)
237
+ let base = { name: "Nova", version: 2 };
238
+ let ext = { stable: true };
239
+ let merged = base extend ext;
240
+ core.print(f"merged.stable = {merged.stable}");
241
+
242
+ // describe annotation
243
+ describe "Nova v2 feature showcase complete";
244
+ core.print("-- demo end --");
245
+ print('Total ticks: ' + tcc)
@@ -0,0 +1,209 @@
1
+ /! Nova Built-in Objects + Unified Registry Demo
2
+
3
+ core.print("=== Unified nova Registry ===");
4
+
5
+ macro APP_NAME = NovaDemoApp;
6
+ macro BUILD = 2;
7
+ core.print(f"App: {nova.getMacro('APP_NAME')} build {nova.getMacro('BUILD')}");
8
+ core.print(f"Nova version: {nova.version}");
9
+
10
+ describe "Built-ins showcase";
11
+ core.print(f"descriptions: {nova.descriptions[0]}");
12
+
13
+ struct Config { host: string = "localhost", port: int = 8080 }
14
+ core.print(f"registered structs: {nova.types.structs[0]}");
15
+
16
+ let evResult = nova.eval("10 * 5 + 2");
17
+ core.print(f"nova.eval result: {evResult}");
18
+
19
+ core.print("\n=== ForLoop ===");
20
+ let squares = ForLoop({ from: 1, to: 5 }).map(i => i * i).collect();
21
+ core.print(f"squares: {squares.join(', ')}");
22
+
23
+ let evens = ForLoop({ from: 0, to: 20, step: 2 }).toArray();
24
+ core.print(f"evens[0..4]: {evens[0]} {evens[1]} {evens[2]} {evens[3]} {evens[4]}");
25
+
26
+ let sumResult = 0;
27
+ ForLoop({ from: 1, to: 100 }).do(i => { sumResult += i; }).run();
28
+ core.print(f"sum 1..100 = {sumResult}");
29
+
30
+ core.print("\n=== Pipeline ===");
31
+ let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
32
+ let processed = Pipeline(data)
33
+ .filter(x => x % 2 == 0)
34
+ .map(x => x * x)
35
+ .take(4)
36
+ .collect();
37
+ core.print(f"pipeline result: {processed.join(', ')}");
38
+
39
+ let total = Pipeline([1, 2, 3, 4, 5]).reduce((acc, x) => acc + x, 0);
40
+ core.print(f"pipeline reduce: {total}");
41
+
42
+ core.print("\n=== IfBlock ===");
43
+ let score = 87;
44
+ let grade = IfBlock({ cond: score >= 90, then: () => "A" })
45
+ .elseIf(score >= 80, () => "B")
46
+ .elseIf(score >= 70, () => "C")
47
+ .else(() => "F")
48
+ .run();
49
+ core.print(f"grade for {score}: {grade}");
50
+
51
+ core.print("\n=== MatchBlock ===");
52
+ let status = MatchBlock(404)
53
+ .when(200, () => "OK")
54
+ .when(404, () => "Not Found")
55
+ .when(500, () => "Server Error")
56
+ .default(() => "Unknown")
57
+ .run();
58
+ core.print(f"HTTP 404 = {status}");
59
+
60
+ let rangeMatch = MatchBlock(75)
61
+ .when(90..100, x => "A")
62
+ .when(80..89, x => "B")
63
+ .when(70..79, x => "C")
64
+ .default(x => "F")
65
+ .run();
66
+ core.print(f"range match 75: {rangeMatch}");
67
+
68
+ core.print("\n=== TryCatch ===");
69
+ let caught = "";
70
+ TryCatch()
71
+ .try(() => { throw "oops"; })
72
+ .catch(e => { caught = e; })
73
+ .finally(() => core.print("finally ran"))
74
+ .run();
75
+ core.print(f"caught: {caught}");
76
+
77
+ core.print("\n=== Data Structures ===");
78
+ let stk = Stack();
79
+ stk.push(10); stk.push(20); stk.push(30);
80
+ core.print(f"Stack: push 10,20,30 → pop={stk.pop()} peek={stk.peek()}");
81
+
82
+ let que = Queue();
83
+ que.enqueue("first"); que.enqueue("second"); que.enqueue("third");
84
+ core.print(f"Queue: dequeue={que.dequeue()} size={que.size}");
85
+
86
+ let ll = LinkedList();
87
+ ll.push("a").push("b").push("c");
88
+ core.print(f"LinkedList size={ll.size} shift={ll.shift()} remaining={ll.size}");
89
+
90
+ let cnt = Counter(0);
91
+ cnt.increment(5); cnt.decrement(2); cnt.clamp(0, 10);
92
+ core.print(f"Counter: {cnt.value}");
93
+
94
+ core.print("\n=== State Machine ===");
95
+ let sm = State("idle");
96
+ sm.add("idle", "start", "running")
97
+ .add("running", "pause", "paused")
98
+ .add("paused", "resume","running")
99
+ .add("running", "done", "idle");
100
+ sm.onEnter("running", s => core.print(f" → entered {s}"));
101
+ sm.onExit("idle", s => core.print(f" ← leaving {s}"));
102
+ sm.dispatch("start");
103
+ sm.dispatch("pause");
104
+ sm.dispatch("resume");
105
+ sm.dispatch("done");
106
+ core.print(f"Final state: {sm.current}");
107
+ core.print(f"History: {sm.history.join(' → ')}");
108
+
109
+ core.print("\n=== Observable + Signal ===");
110
+ let obs = Observable(0);
111
+ let obsLog = [];
112
+ obs.subscribe(v => { addto obsLog v; });
113
+ obs.value = 10;
114
+ obs.value = 20;
115
+ obs.value = 30;
116
+ core.print(f"Observable changes: {obsLog.join(', ')}");
117
+
118
+ let sig = Signal(1);
119
+ let doubled = sig.derive(x => x * 2);
120
+ let quad = doubled.derive(x => x * 2);
121
+ core.print(f"Signal chain: {sig.value} → {doubled.value} → {quad.value}");
122
+ sig.value = 5;
123
+ core.print(f"After sig=5: {sig.value} → {doubled.value} → {quad.value}");
124
+
125
+ core.print("\n=== Validator ===");
126
+ let numV = Validator().required().type("number").min(0).max(100);
127
+ let r1 = numV.validate(50);
128
+ let r2 = numV.validate(-5);
129
+ let r3 = numV.validate(null);
130
+ core.print(f"validate(50): valid={r1.valid}");
131
+ core.print(f"validate(-5): valid={r2.valid} errors={r2.errors[0]}");
132
+ core.print(f"validate(null): valid={r3.valid} errors={r3.errors[0]}");
133
+
134
+ let emailV = Validator().email();
135
+ core.print(f"email ok: {emailV.validate('a@b.com').valid}");
136
+ core.print(f"email bad: {emailV.validate('notanemail').valid}");
137
+
138
+ core.print("\n=== DataStream ===");
139
+ let stream = DataStream([5, 3, 8, 1, 9, 2, 7, 4, 6]);
140
+ let top3 = stream.filter(x => x > 3).sort().reverse().take(3).collect();
141
+ core.print(f"top 3 > 3: {top3.join(', ')}");
142
+
143
+ let distinct = DataStream([1, 2, 2, 3, 3, 3, 4]).distinct().collect();
144
+ core.print(f"distinct: {distinct.join(', ')}");
145
+
146
+ core.print("\n=== Memo ===");
147
+ let calls = 0;
148
+ let expensiveFn = x => { calls++; give x * x * x; };
149
+ let memoFib = Memo(expensiveFn);
150
+ memoFib.call(5); memoFib.call(5); memoFib.call(5);
151
+ memoFib.call(3); memoFib.call(3);
152
+ core.print(f"Memo: 5 calls deduped to {calls} actual runs");
153
+ core.print(f"Stats: {memoFib.stats.hits} hits, {memoFib.stats.misses} misses");
154
+
155
+ core.print("\n=== Lazy ===");
156
+ let computed = false;
157
+ let lazy = Lazy(() => { computed = true; give "expensive result"; });
158
+ core.print(f"Before access: computed={computed}");
159
+ core.print(f"Value: {lazy.value}");
160
+ core.print(f"After access: computed={computed}");
161
+ core.print(f"Value again (cached): {lazy.value}");
162
+
163
+ core.print("\n=== Router ===");
164
+ let router = Router();
165
+ router.on("/api/users/(.*)", id => f"GET user {id}")
166
+ .on("/api/posts/(.*)", id => f"GET post {id}")
167
+ .on("/api/(.*)/delete", res => f"DELETE {res}")
168
+ .default(path => f"404: {path}");
169
+
170
+ core.print(router.dispatch("/api/users/42"));
171
+ core.print(router.dispatch("/api/posts/7"));
172
+ core.print(router.dispatch("/api/comments/delete"));
173
+ core.print(router.dispatch("/unknown"));
174
+
175
+ core.print("\n=== EventBus (standalone) ===");
176
+ let bus = EventBus();
177
+ let busLog = [];
178
+ bus.on("data", v => { addto busLog f"data:{v}"; });
179
+ bus.on("error", e => { addto busLog f"err:{e}"; });
180
+ bus.once("ready", () => { addto busLog "ready!"; });
181
+ bus.emit("ready");
182
+ bus.emit("data", 42);
183
+ bus.emit("data", 99);
184
+ bus.emit("error", "timeout");
185
+ bus.emit("ready"); // once — no second fire
186
+ core.print(f"Bus log: {busLog.join(', ')}");
187
+
188
+ core.print("\n=== Transformer ===");
189
+ let jsonT = TransformerJSON();
190
+ let encoded = jsonT.to({ name: "Nova", version: 2 });
191
+ core.print(f"JSON encode: {encoded}");
192
+
193
+ let b64T = TransformerBase64();
194
+ let b64enc = b64T.to("Hello Nova!");
195
+ let b64dec = b64T.from(b64enc);
196
+ core.print(f"Base64 round-trip: {b64dec}");
197
+
198
+ core.print("\n=== WhileLoop class ===");
199
+ let wn = 1;
200
+ WhileLoop({}).cond(() => wn < 32).do(() => { wn *= 2; }).run();
201
+ core.print(f"WhileLoop powers of 2: {wn}");
202
+
203
+ core.print("\n=== FuncDef ===");
204
+ let adder = FuncDef({ args: ["a", "b"], body: (a, b) => a + b }).named("add");
205
+ core.print(f"FuncDef call: {adder.call(10, 32)}");
206
+ let arrowFn = adder.toArrow();
207
+ core.print(f"FuncDef arrow: {arrowFn(7, 8)}");
208
+
209
+ core.print("\n-- builtins demo done --");
@@ -0,0 +1,62 @@
1
+ /! Nova v2 — HTTP / Server feature demo
2
+
3
+ // ── 1. First-class URL token ──
4
+ let endpoint = https://jsonplaceholder.typicode.com/todos/1;
5
+ core.print(f"URL value: {endpoint}");
6
+
7
+ // ── 2. First-class HTTP method expression ──
8
+ core.print("Fetching todo via GET expression...");
9
+ let todo = get https://jsonplaceholder.typicode.com/todos/1();
10
+ core.print(f" title : {todo.body.title}");
11
+ core.print(f" status : {todo.status}");
12
+ core.print(f" ok : {todo.ok}");
13
+
14
+ // ── 3. Sync fetch() function ──
15
+ core.print("Fetching post via fetch()...");
16
+ let article = fetch("https://jsonplaceholder.typicode.com/posts/1");
17
+ core.print(f" article title: {article.body.title}");
18
+
19
+ // ── 4. fetch() statement form with => binding ──
20
+ fetch("https://jsonplaceholder.typicode.com/todos/2") => todo2;
21
+ core.print(f" todo2: {todo2.body.title}");
22
+
23
+ // ── 5. POST with body ──
24
+ core.print("POST request...");
25
+ let created = post https://jsonplaceholder.typicode.com/posts({ title: "Nova test", body: "hello", userId: 1 });
26
+ core.print(f" created id: {created.body.id}");
27
+ core.print(f" created status: {created.status}");
28
+
29
+ // ── 6. Server ──
30
+ core.print("Starting server on port 4242...");
31
+ server(4242) {
32
+ get "/hello"(req, res) {
33
+ return { message: "Hello from Nova!", method: req.method };
34
+ }
35
+
36
+ get "/echo/:msg"(req, res) {
37
+ return { echo: req.params.msg };
38
+ }
39
+
40
+ post "/data"(req, res) {
41
+ let incoming = req.body;
42
+ return { received: true, data: incoming };
43
+ }
44
+
45
+ get "*"(req, res) {
46
+ res.status(404);
47
+ return { error: "Not found", path: req.path };
48
+ }
49
+ }
50
+
51
+ // Hit the local server
52
+ core.print("Testing server with local requests...");
53
+ let r1 = get http://localhost:4242/hello();
54
+ core.print(f" /hello -> {r1.body.message}");
55
+
56
+ let r2 = get http://localhost:4242/echo/world();
57
+ core.print(f" /echo/world -> {r2.body.echo}");
58
+
59
+ let r3 = post http://localhost:4242/data({ name: "Nova", version: 2 });
60
+ core.print(f" /data received: {r3.body.received}");
61
+
62
+ core.print("All HTTP tests passed!");
@@ -0,0 +1,69 @@
1
+ let Tkit = includeKit("libterm");
2
+ let TView = Tkit.TView;
3
+ let Terminal = Tkit.Terminal;
4
+
5
+ // ─────────────────────────────────────────────────────────────────────────────
6
+ // Boot Terminal (starts input, enters alt-screen, wires resize)
7
+ // ─────────────────────────────────────────────────────────────────────────────
8
+
9
+ const term = Terminal({
10
+ altScreen: true,
11
+ mouse: true,
12
+ theme: 'dark',
13
+ logLevel: 'debug',
14
+ });
15
+
16
+ // ─────────────────────────────────────────────────────────────────────────────
17
+ // Layout: top bar / [left pane | right pane] / sensor bar / bottom bar
18
+ // ─────────────────────────────────────────────────────────────────────────────
19
+
20
+ term.on('ready', async () => {
21
+ let view = term.createView();
22
+ let code = await view.prompt("Enter Brainfuck code:");
23
+ let input = await view.prompt("Enter input for Brainfuck code:");
24
+ let output = "";
25
+ let data = [0, 30000];
26
+ let dataPtr = 0;
27
+ let codePtr = 0;
28
+ while (codePtr < code.length) {
29
+ let cmd = code[codePtr];
30
+ if (cmd == '>') {
31
+ dataPtr++;
32
+ } else if (cmd == '<') {
33
+ dataPtr--;
34
+ } else if (cmd == '+') {
35
+ data[dataPtr] = (data[dataPtr] + 1) % 256;
36
+ } else if (cmd == '-') {
37
+ data[dataPtr] = (data[dataPtr] - 1) % 256;
38
+ } else if (cmd == '.') {
39
+ output += charAt(data[dataPtr]);
40
+ } else if (cmd == ',') {
41
+ if (input.length > 0) {
42
+ data[dataPtr] = (input[0]) as int;
43
+ input = input.substr(1);
44
+ } else {
45
+ data[dataPtr] = 0;
46
+ }
47
+ } else if (cmd == '[') {
48
+ if (data[dataPtr] == 0) {
49
+ let Loop = 1;
50
+ while (Loop > 0) {
51
+ codePtr++;
52
+ if (code[codePtr] == '[') Loop++;
53
+ else if (code[codePtr] == ']') Loop--;
54
+ }
55
+ }
56
+ } else if (cmd == ']') {
57
+ if (data[dataPtr] != 0) {
58
+ let Loop = 1;
59
+ while (Loop > 0) {
60
+ codePtr--;
61
+ if (code[codePtr] == ']') Loop++;
62
+ else if (code[codePtr] == '[') Loop--;
63
+ }
64
+ }
65
+ }
66
+ codePtr++;
67
+ }
68
+ await view.writeText(0, 0, "Output: " + output, { color: 'green' });
69
+ })
@@ -0,0 +1,21 @@
1
+ let Tkit = includeKit("libterm");
2
+ let Terminal = Tkit.Terminal;
3
+ let parseExpr = includeKit('kitparse').parseExpr;
4
+
5
+ // ─────────────────────────────────────────────────────────────────────────────
6
+ // Boot Terminal (starts input, enters alt-screen)
7
+ // ─────────────────────────────────────────────────────────────────────────────
8
+
9
+ const term = Terminal({
10
+ altScreen: true,
11
+ mouse: true,
12
+ theme: 'dark',
13
+ logLevel: 'debug',
14
+ });
15
+
16
+ term.on('ready', async () => {
17
+ let view = term.createView();
18
+ let code = await view.prompt("Enter Math:");
19
+
20
+ await view.writeText(0, 0, "Output: " + parseExpr(code), { color: 'green' });
21
+ })