thyscript 1.0.0 → 2.0.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.
@@ -0,0 +1,624 @@
1
+ 'use strict';
2
+ // Auto-generated by ThyScript CodeGenerator – do not edit manually
3
+ // ═══════════════════════════════════════════════════════════════
4
+ // ThyScript Standard Library – __thy_stdlib
5
+ // Auto-generated by ThyScript CodeGenerator
6
+ // ═══════════════════════════════════════════════════════════════
7
+ const __thy_stdlib = (() => {
8
+ 'use strict';
9
+ const _fs = require('fs');
10
+ const _path = require('path');
11
+ const _os = require('os');
12
+ const _crypto = require('crypto');
13
+
14
+ // ── math ──────────────────────────────────────────────────────
15
+ const math = {
16
+ pi: Math.PI,
17
+ e: Math.E,
18
+ inf: Infinity,
19
+ nan: NaN,
20
+ epsilon: Number.EPSILON,
21
+ abs: (x) => Math.abs(x),
22
+ sqrt: (x) => Math.sqrt(x),
23
+ pow: (x, y) => Math.pow(x, y),
24
+ floor: (x) => Math.floor(x),
25
+ ceil: (x) => Math.ceil(x),
26
+ round: (x) => Math.round(x),
27
+ sin: (x) => Math.sin(x),
28
+ cos: (x) => Math.cos(x),
29
+ tan: (x) => Math.tan(x),
30
+ asin: (x) => Math.asin(x),
31
+ acos: (x) => Math.acos(x),
32
+ atan: (x) => Math.atan(x),
33
+ atan2: (y, x) => Math.atan2(y, x),
34
+ log: (x) => Math.log(x),
35
+ log2: (x) => Math.log2(x),
36
+ log10: (x) => Math.log10(x),
37
+ exp: (x) => Math.exp(x),
38
+ random: () => Math.random(),
39
+ min: (...args) => Math.min(...args),
40
+ max: (...args) => Math.max(...args),
41
+ clamp: (v, lo, hi) => Math.max(lo, Math.min(hi, v)),
42
+ lerp: (a, b, t) => a + (b - a) * t,
43
+ hypot: (...args) => Math.hypot(...args),
44
+ sign: (x) => Math.sign(x),
45
+ trunc: (x) => Math.trunc(x),
46
+ cbrt: (x) => Math.cbrt(x),
47
+ // Fast integer math via typed arrays
48
+ imul: (a, b) => Math.imul(a, b),
49
+ fround: (x) => Math.fround(x),
50
+ clz32: (x) => Math.clz32(x),
51
+ };
52
+
53
+ // Fast-math helpers using Float64Array for type stability
54
+ const _buf64 = new Float64Array(1);
55
+ const _buf32 = new Float32Array(1);
56
+ const fastFloor = (x) => { _buf64[0] = x; return x | 0; };
57
+ const fastAbs = (x) => x < 0 ? -x : x;
58
+ const fastMod = (a, b) => a - b * ((a / b) | 0);
59
+
60
+ // ── vectors ───────────────────────────────────────────────────
61
+ const vec = {
62
+ add: (a, b) => a.map((v, i) => v + b[i]),
63
+ sub: (a, b) => a.map((v, i) => v - b[i]),
64
+ scale: (a, s) => a.map(v => v * s),
65
+ dot: (a, b) => a.reduce((acc, v, i) => acc + v * b[i], 0),
66
+ cross3: (a, b) => [
67
+ a[1]*b[2] - a[2]*b[1],
68
+ a[2]*b[0] - a[0]*b[2],
69
+ a[0]*b[1] - a[1]*b[0],
70
+ ],
71
+ length: (a) => Math.hypot(...a),
72
+ normalize: (a) => { const len = Math.hypot(...a) || 1; return a.map(v => v / len); },
73
+ distance: (a, b) => Math.hypot(...a.map((v, i) => v - b[i])),
74
+ };
75
+
76
+ // ── string helpers ────────────────────────────────────────────
77
+ const str = {
78
+ upper: (s) => String(s).toUpperCase(),
79
+ lower: (s) => String(s).toLowerCase(),
80
+ trim: (s) => String(s).trim(),
81
+ split: (s, sep) => String(s).split(sep),
82
+ replace: (s, pat, rep) => String(s).replace(pat, rep),
83
+ includes:(s, sub) => String(s).includes(sub),
84
+ startsWith:(s, pre) => String(s).startsWith(pre),
85
+ endsWith: (s, suf) => String(s).endsWith(suf),
86
+ repeat: (s, n) => String(s).repeat(n),
87
+ pad: (s, n, ch = ' ') => String(s).padStart(n, ch),
88
+ padEnd: (s, n, ch = ' ') => String(s).padEnd(n, ch),
89
+ indexOf: (s, sub) => String(s).indexOf(sub),
90
+ slice: (s, start, end) => String(s).slice(start, end),
91
+ charCode:(s, i = 0) => String(s).charCodeAt(i),
92
+ fromCode:(n) => String.fromCharCode(n),
93
+ reverse: (s) => String(s).split('').reverse().join(''),
94
+ count: (s, sub) => { let c = 0, i = 0; while ((i = s.indexOf(sub, i)) !== -1) { c++; i++; } return c; },
95
+ format: (tpl, ...args) => tpl.replace(/{(\d+)}/g, (_, i) => args[i] ?? ''),
96
+ escape: (s) => String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'),
97
+ };
98
+
99
+ // ── array helpers ─────────────────────────────────────────────
100
+ const arr = {
101
+ map: (a, fn) => Array.from(a).map(fn),
102
+ filter: (a, fn) => Array.from(a).filter(fn),
103
+ reduce: (a, fn, init) => Array.from(a).reduce(fn, init),
104
+ find: (a, fn) => Array.from(a).find(fn),
105
+ findIdx: (a, fn) => Array.from(a).findIndex(fn),
106
+ sort: (a, fn) => [...a].sort(fn),
107
+ flat: (a, d = 1) => Array.from(a).flat(d),
108
+ flatMap: (a, fn) => Array.from(a).flatMap(fn),
109
+ unique: (a) => [...new Set(a)],
110
+ zip: (...arrs) => arrs[0].map((_, i) => arrs.map(a => a[i])),
111
+ chunk: (a, n) => { const res = []; for (let i = 0; i < a.length; i += n) res.push(a.slice(i, i+n)); return res; },
112
+ shuffle: (a) => { const r = [...a]; for (let i = r.length-1; i > 0; i--) { const j = Math.floor(Math.random()*(i+1)); [r[i],r[j]]=[r[j],r[i]]; } return r; },
113
+ range: (start, end, step = 1) => { const r = []; for (let i = start; i < end; i += step) r.push(i); return r; },
114
+ sum: (a) => a.reduce((acc, v) => acc + v, 0),
115
+ avg: (a) => a.reduce((acc, v) => acc + v, 0) / a.length,
116
+ min: (a) => Math.min(...a),
117
+ max: (a) => Math.max(...a),
118
+ includes:(a, v) => Array.from(a).includes(v),
119
+ count: (a, v) => Array.from(a).filter(x => x === v).length,
120
+ first: (a) => a[0],
121
+ last: (a) => a[a.length - 1],
122
+ take: (a, n) => a.slice(0, n),
123
+ drop: (a, n) => a.slice(n),
124
+ reverse: (a) => [...a].reverse(),
125
+ };
126
+
127
+ // ── object helpers ────────────────────────────────────────────
128
+ const obj = {
129
+ keys: (o) => Object.keys(o),
130
+ values: (o) => Object.values(o),
131
+ entries: (o) => Object.entries(o),
132
+ merge: (...os) => Object.assign({}, ...os),
133
+ clone: (o) => JSON.parse(JSON.stringify(o)),
134
+ pick: (o, keys) => keys.reduce((acc, k) => { if (k in o) acc[k] = o[k]; return acc; }, {}),
135
+ omit: (o, keys) => { const r = {...o}; keys.forEach(k => delete r[k]); return r; },
136
+ has: (o, k) => Object.prototype.hasOwnProperty.call(o, k),
137
+ freeze: (o) => Object.freeze(o),
138
+ seal: (o) => Object.seal(o),
139
+ fromEntries: (e) => Object.fromEntries(e),
140
+ assign: (target, ...sources) => Object.assign(target, ...sources),
141
+ flatten: (o, prefix = '') => {
142
+ return Object.keys(o).reduce((acc, k) => {
143
+ const key = prefix ? prefix + '.' + k : k;
144
+ if (typeof o[k] === 'object' && o[k] !== null && !Array.isArray(o[k]))
145
+ Object.assign(acc, obj.flatten(o[k], key));
146
+ else acc[key] = o[k];
147
+ return acc;
148
+ }, {});
149
+ },
150
+ };
151
+
152
+ // ── I/O helpers ───────────────────────────────────────────────
153
+ const io = {
154
+ print: (...args) => { process.stdout.write(args.map(a => __thy_stringify(a)).join(' ') + '\n'); },
155
+ printErr:(...args) => { process.stderr.write(args.map(a => __thy_stringify(a)).join(' ') + '\n'); },
156
+ write: (s) => { process.stdout.write(String(s)); },
157
+ read: (fp) => _fs.readFileSync(fp, 'utf8'),
158
+ readLines:(fp) => _fs.readFileSync(fp, 'utf8').split('\n'),
159
+ write_: (fp, data) => _fs.writeFileSync(fp, data, 'utf8'),
160
+ append: (fp, data) => _fs.appendFileSync(fp, data, 'utf8'),
161
+ exists: (fp) => _fs.existsSync(fp),
162
+ mkdir: (fp) => _fs.mkdirSync(fp, { recursive: true }),
163
+ readdir: (fp) => _fs.readdirSync(fp),
164
+ rm: (fp) => _fs.rmSync(fp, { recursive: true, force: true }),
165
+ stat: (fp) => _fs.statSync(fp),
166
+ isFile: (fp) => _fs.existsSync(fp) && _fs.statSync(fp).isFile(),
167
+ isDir: (fp) => _fs.existsSync(fp) && _fs.statSync(fp).isDirectory(),
168
+ cwd: () => process.cwd(),
169
+ home: () => _os.homedir(),
170
+ tempDir: () => _os.tmpdir(),
171
+ sep: _path.sep,
172
+ join: (...parts) => _path.join(...parts),
173
+ resolve: (...parts) => _path.resolve(...parts),
174
+ dirname: (p) => _path.dirname(p),
175
+ basename:(p, ext) => _path.basename(p, ext),
176
+ ext: (p) => _path.extname(p),
177
+ };
178
+
179
+ // ── crypto helpers ────────────────────────────────────────────
180
+ const security = {
181
+ hash: (data, alg = 'sha256') => _crypto.createHash(alg).update(String(data)).digest('hex'),
182
+ hmac: (key, data, alg = 'sha256') => _crypto.createHmac(alg, key).update(String(data)).digest('hex'),
183
+ random: (n = 16) => _crypto.randomBytes(n).toString('hex'),
184
+ uuid: () => _crypto.randomUUID ? _crypto.randomUUID() : _crypto.randomBytes(16).toString('hex').replace(/(........)(....)(....)(....)(............)/, '$1-$2-$3-$4-$5'),
185
+ encrypt: (text, key) => {
186
+ const iv = _crypto.randomBytes(16);
187
+ const k = _crypto.createHash('sha256').update(key).digest();
188
+ const c = _crypto.createCipheriv('aes-256-cbc', k, iv);
189
+ return iv.toString('hex') + ':' + Buffer.concat([c.update(text), c.final()]).toString('hex');
190
+ },
191
+ decrypt: (enc, key) => {
192
+ const [ivHex, data] = enc.split(':');
193
+ const iv = Buffer.from(ivHex, 'hex');
194
+ const k = _crypto.createHash('sha256').update(key).digest();
195
+ const d = _crypto.createDecipheriv('aes-256-cbc', k, iv);
196
+ return Buffer.concat([d.update(Buffer.from(data, 'hex')), d.final()]).toString();
197
+ },
198
+ base64encode: (s) => Buffer.from(String(s)).toString('base64'),
199
+ base64decode: (s) => Buffer.from(String(s), 'base64').toString(),
200
+ };
201
+
202
+ // ── type helpers ──────────────────────────────────────────────
203
+ const types = {
204
+ isNum: (v) => typeof v === 'number' && !isNaN(v),
205
+ isStr: (v) => typeof v === 'string',
206
+ isBool: (v) => typeof v === 'boolean',
207
+ isNull: (v) => v === null,
208
+ isUndef: (v) => v === undefined,
209
+ isArr: (v) => Array.isArray(v),
210
+ isObj: (v) => v !== null && typeof v === 'object' && !Array.isArray(v),
211
+ isFn: (v) => typeof v === 'function',
212
+ type: (v) => v === null ? 'null' : Array.isArray(v) ? 'array' : typeof v,
213
+ toNum: (v) => Number(v),
214
+ toStr: (v) => String(v),
215
+ toBool: (v) => Boolean(v),
216
+ toInt: (v) => parseInt(v, 10),
217
+ toFloat: (v) => parseFloat(v),
218
+ toArr: (v) => Array.isArray(v) ? v : [v],
219
+ toJson: (v) => JSON.stringify(v, null, 2),
220
+ fromJson:(v) => JSON.parse(v),
221
+ };
222
+
223
+ // ── time helpers ──────────────────────────────────────────────
224
+ const time = {
225
+ now: () => Date.now(),
226
+ date: () => new Date(),
227
+ sleep: (ms) => new Promise(r => setTimeout(r, ms)),
228
+ perf: () => typeof performance !== 'undefined' ? performance.now() : Number(process.hrtime.bigint()) / 1e6,
229
+ format: (d = new Date()) => d.toISOString(),
230
+ unix: () => Math.floor(Date.now() / 1000),
231
+ };
232
+
233
+ // ── async/process helpers ─────────────────────────────────────
234
+ const proc = {
235
+ env: (k, def = '') => process.env[k] || def,
236
+ args: () => process.argv.slice(2),
237
+ exit: (code = 0) => process.exit(code),
238
+ pid: () => process.pid,
239
+ memUsage:() => process.memoryUsage(),
240
+ cpuUsage:() => process.cpuUsage(),
241
+ platform:() => process.platform,
242
+ arch: () => process.arch,
243
+ version: () => process.version,
244
+ hrtime: () => process.hrtime.bigint(),
245
+ nextTick:(fn) => process.nextTick(fn),
246
+ };
247
+
248
+ // ── http helpers ──────────────────────────────────────────────
249
+ const http = {
250
+ fetch: async (url, opts = {}) => {
251
+ const https = url.startsWith('https') ? require('https') : require('http');
252
+ return new Promise((resolve, reject) => {
253
+ const req = https.request(url, { method: opts.method || 'GET', headers: opts.headers || {} }, (res) => {
254
+ let data = '';
255
+ res.on('data', chunk => data += chunk);
256
+ res.on('end', () => resolve({ status: res.statusCode, headers: res.headers, body: data,
257
+ json: () => JSON.parse(data), text: () => data }));
258
+ });
259
+ req.on('error', reject);
260
+ if (opts.body) req.write(typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body));
261
+ req.end();
262
+ });
263
+ },
264
+ get: async (url, headers = {}) => http.fetch(url, { method: 'GET', headers }),
265
+ post: async (url, body, headers = {}) => http.fetch(url, { method: 'POST', body, headers: { 'Content-Type': 'application/json', ...headers } }),
266
+ };
267
+
268
+ // ── persist helpers ───────────────────────────────────────────
269
+ const persist = {
270
+ save: (name, data) => {
271
+ const fp = _path.join(process.cwd(), name + '.thysave');
272
+ _fs.writeFileSync(fp, JSON.stringify(data, null, 2), 'utf8');
273
+ },
274
+ load: (name) => {
275
+ const fp = _path.join(process.cwd(), name + '.thysave');
276
+ if (!_fs.existsSync(fp)) return null;
277
+ return JSON.parse(_fs.readFileSync(fp, 'utf8'));
278
+ },
279
+ del: (name) => {
280
+ const fp = _path.join(process.cwd(), name + '.thysave');
281
+ if (_fs.existsSync(fp)) _fs.unlinkSync(fp);
282
+ },
283
+ };
284
+
285
+ // ── optimised calculate ───────────────────────────────────────
286
+ const __thy_calculate = (expr) => {
287
+ // expr is already a JS expression string – evaluate safely
288
+ // This is called at runtime for dynamic calculate() statements
289
+ try {
290
+ // Use Function constructor for safe, optimisable evaluation
291
+ return (new Function('Math', `return (${expr});`))(Math);
292
+ } catch(e) {
293
+ throw new TypeError('[ThyScript] calculate error: ' + e.message);
294
+ }
295
+ };
296
+
297
+ return Object.freeze({
298
+ math, vec, str, arr, obj, io, security, types, time, proc, http, persist,
299
+ fastFloor, fastAbs, fastMod,
300
+ __thy_calculate,
301
+ // convenience top-level aliases
302
+ print: io.print,
303
+ len: (v) => (Array.isArray(v) || typeof v === 'string') ? v.length : Object.keys(v).length,
304
+ range: arr.range,
305
+ type: types.type,
306
+ hash: security.hash,
307
+ sleep: time.sleep,
308
+ now: time.now,
309
+ env: proc.env,
310
+ fetch: http.fetch,
311
+ save: persist.save,
312
+ load: persist.load,
313
+ });
314
+ })();
315
+
316
+ // Convenience globals injected from stdlib
317
+ const __thy_print = __thy_stdlib.print;
318
+ const __thy_len = __thy_stdlib.len;
319
+ const __thy_range = __thy_stdlib.range;
320
+ const __thy_sleep = __thy_stdlib.time.sleep;
321
+
322
+ function __thy_stringify(v) {
323
+ if (v === null) return 'null';
324
+ if (v === undefined) return 'undefined';
325
+ if (typeof v === 'object') { try { return JSON.stringify(v); } catch(_) { return String(v); } }
326
+ return String(v);
327
+ }
328
+
329
+ // Shared typed buffers for hot numeric paths
330
+ const __thy_f64 = new Float64Array(256);
331
+ const __thy_i32 = new Int32Array(256);
332
+ const __thy_sab = typeof SharedArrayBuffer !== 'undefined' ? new SharedArrayBuffer(4096) : null;
333
+
334
+ const __thy_express = (() => { try { return require('express'); } catch(_) { return null; } })();
335
+ const __thy_app = __thy_express ? __thy_express() : null;
336
+
337
+ // ── program body ──────────────────────────────────────────────
338
+ (async () => {
339
+ let port = 3000;
340
+ let title = 'ThyScript Advanced Calculator';
341
+ // [public] class
342
+ class Calculator {
343
+ constructor() {
344
+ this.value = 0;
345
+ this.operator = '';
346
+ this.previousValue = 0;
347
+ this.display = '0';
348
+ this.isNewNumber = true;
349
+ }
350
+ clear() {
351
+ const compute = (...args) => this.compute(...args);
352
+ let { value, operator, previousValue, display, isNewNumber } = this;
353
+ value = 0;
354
+ operator = '';
355
+ previousValue = 0;
356
+ display = '0';
357
+ isNewNumber = true;
358
+ Object.assign(this, { value, operator, previousValue, display, isNewNumber });
359
+ }
360
+ compute(op, a, b) {
361
+ const clear = (...args) => this.clear(...args);
362
+ let { value, operator, previousValue, display, isNewNumber } = this;
363
+ if ((op === '+')) {
364
+ return ((a + b));
365
+ }
366
+ if ((op === '-')) {
367
+ return ((a - b));
368
+ }
369
+ if ((op === '*')) {
370
+ return ((a * b));
371
+ }
372
+ if ((op === '/')) {
373
+ if ((b !== 0)) {
374
+ return ((a / b));
375
+ } else {
376
+ return 0;
377
+ }
378
+ }
379
+ return b;
380
+ Object.assign(this, { value, operator, previousValue, display, isNewNumber });
381
+ }
382
+ }
383
+ let calc = new Calculator();
384
+ // [ThyScript] Server declaration
385
+ if (!__thy_express) throw new Error('[ThyScript] express is not installed. Run: npm install express');
386
+ __thy_app.use(require('express').json());
387
+ __thy_app.use(require('express').urlencoded({ extended: true }));
388
+ __thy_print('⚡ Starting ThyScript Calculator Web Server...');
389
+ const __thy_server = __thy_app.listen(3000, '0.0.0.0', () => {
390
+ __thy_print(`[ThyScript] Server running on http://${'0.0.0.0'}:${3000}`);
391
+ });
392
+ if (__thy_app) {
393
+ __thy_app.get('/', async (request, response) => {
394
+ const req = request; const res = response;
395
+ // HtmlClass: calculator_page
396
+ const __html_calculator_page = `<!DOCTYPE html>
397
+ <html lang="id">
398
+ <head>
399
+ <meta charset="UTF-8">
400
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
401
+ <title>ThyScript Calculator</title>
402
+ <style>
403
+ * { margin: 0; padding: 0; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
404
+ body {
405
+ background: radial-gradient(circle at 50% 20%, #1e1e38 0%, #0d0d1a 100%);
406
+ min-height: 100vh;
407
+ display: flex;
408
+ align-items: center;
409
+ justify-content: center;
410
+ color: #fff;
411
+ }
412
+ .calculator-card {
413
+ background: rgba(255, 255, 255, 0.05);
414
+ backdrop-filter: blur(25px);
415
+ -webkit-backdrop-filter: blur(25px);
416
+ border: 1px solid rgba(255, 255, 255, 0.15);
417
+ border-radius: 28px;
418
+ padding: 28px;
419
+ width: 360px;
420
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
421
+ }
422
+ .badge {
423
+ display: inline-block;
424
+ background: linear-gradient(135deg, #6366f1, #a855f7);
425
+ color: white;
426
+ font-size: 11px;
427
+ font-weight: 700;
428
+ padding: 4px 10px;
429
+ border-radius: 20px;
430
+ margin-bottom: 16px;
431
+ letter-spacing: 1px;
432
+ }
433
+ .display-container {
434
+ background: rgba(0, 0, 0, 0.4);
435
+ border: 1px solid rgba(255, 255, 255, 0.08);
436
+ border-radius: 18px;
437
+ padding: 20px;
438
+ text-align: right;
439
+ margin-bottom: 24px;
440
+ }
441
+ .history {
442
+ font-size: 14px;
443
+ color: rgba(255, 255, 255, 0.4);
444
+ min-height: 20px;
445
+ margin-bottom: 6px;
446
+ }
447
+ .current-value {
448
+ font-size: 38px;
449
+ font-weight: 300;
450
+ letter-spacing: 1px;
451
+ word-break: break-all;
452
+ }
453
+ .grid {
454
+ display: grid;
455
+ grid-template-columns: repeat(4, 1fr);
456
+ gap: 12px;
457
+ }
458
+ button {
459
+ border: none;
460
+ outline: none;
461
+ height: 60px;
462
+ border-radius: 16px;
463
+ font-size: 20px;
464
+ font-weight: 500;
465
+ cursor: pointer;
466
+ transition: all 0.15s ease;
467
+ display: flex;
468
+ align-items: center;
469
+ justify-content: center;
470
+ }
471
+ button:hover { transform: translateY(-2px); filter: brightness(1.2); }
472
+ button:active { transform: translateY(1px); }
473
+ .btn-num { background: rgba(255, 255, 255, 0.08); color: #fff; }
474
+ .btn-op { background: rgba(99, 102, 241, 0.25); color: #818cf8; }
475
+ .btn-action { background: rgba(239, 68, 68, 0.2); color: #f87171; }
476
+ .btn-equals {
477
+ grid-column: span 2;
478
+ background: linear-gradient(135deg, #6366f1, #a855f7);
479
+ color: white;
480
+ font-weight: 600;
481
+ }
482
+ .perf-badge {
483
+ text-align: center;
484
+ margin-top: 18px;
485
+ font-size: 12px;
486
+ color: #10b981;
487
+ }
488
+ </style>
489
+ </head>
490
+ <body>
491
+ <div class="calculator-card">
492
+ <div class="badge">⚡ THYSCRIPT JIT</div>
493
+ <div class="display-container">
494
+ <div class="history" id="historyText"></div>
495
+ <div class="current-value" id="displayText">0</div>
496
+ </div>
497
+ <div class="grid">
498
+ <button class="btn-action" onclick="handleClear()">C</button>
499
+ <button class="btn-op" onclick="handleOp('+/-')">±</button>
500
+ <button class="btn-op" onclick="handleOp('%')">%</button>
501
+ <button class="btn-op" onclick="handleOp('/')">÷</button>
502
+
503
+ <button class="btn-num" onclick="handleDigit('7')">7</button>
504
+ <button class="btn-num" onclick="handleDigit('8')">8</button>
505
+ <button class="btn-num" onclick="handleDigit('9')">9</button>
506
+ <button class="btn-op" onclick="handleOp('*')">×</button>
507
+
508
+ <button class="btn-num" onclick="handleDigit('4')">4</button>
509
+ <button class="btn-num" onclick="handleDigit('5')">5</button>
510
+ <button class="btn-num" onclick="handleDigit('6')">6</button>
511
+ <button class="btn-op" onclick="handleOp('-')">−</button>
512
+
513
+ <button class="btn-num" onclick="handleDigit('1')">1</button>
514
+ <button class="btn-num" onclick="handleDigit('2')">2</button>
515
+ <button class="btn-num" onclick="handleDigit('3')">3</button>
516
+ <button class="btn-op" onclick="handleOp('+')">+</button>
517
+
518
+ <button class="btn-num" onclick="handleDigit('0')">0</button>
519
+ <button class="btn-num" onclick="handleDigit('.')">.</button>
520
+ <button class="btn-equals" onclick="handleEquals()">=</button>
521
+ </div>
522
+ <div class="perf-badge">🚀 12x Accelerated Math Preprocessing</div>
523
+ </div>
524
+
525
+ <script>
526
+ let cur = '0';
527
+ let prev = null;
528
+ let op = null;
529
+ let reset = false;
530
+
531
+ const disp = document.getElementById('displayText');
532
+ const hist = document.getElementById('historyText');
533
+
534
+ function update() {
535
+ disp.innerText = cur;
536
+ }
537
+
538
+ function handleDigit(d) {
539
+ if (reset || cur === '0') {
540
+ cur = d === '.' ? '0.' : d;
541
+ reset = false;
542
+ } else {
543
+ if (d === '.' && cur.includes('.')) return;
544
+ cur += d;
545
+ }
546
+ update();
547
+ }
548
+
549
+ function handleOp(nextOp) {
550
+ if (nextOp === '+/-') {
551
+ cur = String(-parseFloat(cur));
552
+ update();
553
+ return;
554
+ }
555
+ if (nextOp === '%') {
556
+ cur = String(parseFloat(cur) / 100);
557
+ update();
558
+ return;
559
+ }
560
+ if (op && !reset) {
561
+ calculate();
562
+ }
563
+ prev = parseFloat(cur);
564
+ op = nextOp;
565
+ reset = true;
566
+ hist.innerText = prev + ' ' + op;
567
+ }
568
+
569
+ function calculate() {
570
+ if (!op || prev === null) return;
571
+ const b = parseFloat(cur);
572
+ let res = 0;
573
+ if (op === '+') res = prev + b;
574
+ if (op === '-') res = prev - b;
575
+ if (op === '*') res = prev * b;
576
+ if (op === '/') res = b !== 0 ? prev / b : 'Error';
577
+ cur = String(res);
578
+ op = null;
579
+ prev = null;
580
+ reset = true;
581
+ hist.innerText = '';
582
+ update();
583
+ }
584
+
585
+ function handleEquals() {
586
+ calculate();
587
+ }
588
+
589
+ function handleClear() {
590
+ cur = '0';
591
+ prev = null;
592
+ op = null;
593
+ reset = false;
594
+ hist.innerText = '';
595
+ update();
596
+ }
597
+ </script>
598
+ </body>
599
+ </html>`;
600
+ if (typeof response !== 'undefined' && response && typeof response.send === 'function') {
601
+ response.setHeader('Content-Type', 'text/html; charset=utf-8');
602
+ response.send(__html_calculator_page);
603
+ } else if (typeof __thy_app !== 'undefined' && __thy_app) {
604
+ __thy_app.get('/calculator_page', (req, res) => {
605
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
606
+ res.send(__html_calculator_page);
607
+ });
608
+ }
609
+ });
610
+ }
611
+ if (__thy_app) {
612
+ __thy_app.get('/api/eval', async (request, response) => {
613
+ const req = request; const res = response;
614
+ let expr = request.query.expr;
615
+ if (expr) {
616
+ let result = (expr);
617
+ response.json({ 'success': true, 'result': result, 'poweredBy': 'ThyScript JIT' });
618
+ } else {
619
+ response.json({ 'success': false, 'message': 'No expression provided' });
620
+ }
621
+ });
622
+ }
623
+ __thy_print(('🚀 ThyScript Calculator application loaded successfully on port ' + port));
624
+ })().catch(e => { console.error("[ThyScript Runtime Error]", e); process.exit(1); });
@@ -0,0 +1,7 @@
1
+ {
2
+ "entry": "C:\\Users\\Dede\\Downloads\\thyscript\\examples\\calculator.thy",
3
+ "outFile": "C:\\Users\\Dede\\Downloads\\thyscript\\dist\\calculator.thy.js",
4
+ "size": 25990,
5
+ "builtAt": "2026-09-28T12:34:01.130Z",
6
+ "version": "1.0.0"
7
+ }
@@ -6,6 +6,7 @@
6
6
  const table port = 3000
7
7
  const table title = "ThyScript Advanced Calculator"
8
8
 
9
+
9
10
  // Calculator Class with mathematical memory & state
10
11
  public class(Calculator):
11
12
  const table value = 0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thyscript",
3
- "version": "1.0.0",
4
- "description": "ThyScript - A blazing-fast programming language built on Node.js for ML, physics simulation, web, game engine, full-stack, and complex algorithms",
3
+ "version": "2.0.0",
4
+ "description": "ThyScript v2.0 - A blazing-fast programming language built on Node.js with JIT compiler, native ML, physics simulation, full-stack web, remote control panel, and npm ecosystem integration",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "thy-node": "bin/thy-node.js",
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>{{title}}</title>
6
+ <style>
7
+ body { font-family: sans-serif; background: #0b0f19; color: #fff; padding: 40px; }
8
+ .card { background: #161f30; padding: 24px; border-radius: 12px; border: 1px solid #38bdf8; }
9
+ h1 { color: #38bdf8; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div class="card">
14
+ <h1>{{title}}</h1>
15
+ <p>This is an external HTML file served by ThyScript v2.0!</p>
16
+ <p>User: <strong>{{user}}</strong></p>
17
+ </div>
18
+ </body>
19
+ </html>