thyscript 1.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.
Files changed (49) hide show
  1. package/bin/thy-node.js +332 -0
  2. package/bin/thy.js +828 -0
  3. package/bin/thys.js +25 -0
  4. package/examples/calculator.thy +274 -0
  5. package/examples/calculator.thy.js +628 -0
  6. package/examples/hello.thy +34 -0
  7. package/examples/login.thy +382 -0
  8. package/examples/login.thy.js +710 -0
  9. package/package.json +54 -0
  10. package/scripts/_class.js +18 -0
  11. package/scripts/_class2.js +11 -0
  12. package/scripts/_class3.js +21 -0
  13. package/scripts/_dstruct.js +20 -0
  14. package/scripts/_dstruct2.js +24 -0
  15. package/scripts/_scaffold.js +16 -0
  16. package/scripts/_scaffold2.js +16 -0
  17. package/scripts/_scaffold3.js +26 -0
  18. package/scripts/_tpl_compile.js +13 -0
  19. package/scripts/_tpl_test.js +9 -0
  20. package/scripts/_typeof.js +26 -0
  21. package/scripts/_typeof2.js +25 -0
  22. package/scripts/patch_genmethod.js +44 -0
  23. package/scripts/smoke_test.js +167 -0
  24. package/scripts/smoke_test2.js +151 -0
  25. package/scripts/test_control_panel.js +58 -0
  26. package/src/compiler/CodeGenerator.js +1449 -0
  27. package/src/compiler/JITCompiler.js +325 -0
  28. package/src/database/DatabaseEngine.js +931 -0
  29. package/src/errors/ErrorDetector.js +305 -0
  30. package/src/errors/ErrorMessages.js +497 -0
  31. package/src/index.js +169 -0
  32. package/src/lexer/Lexer.js +342 -0
  33. package/src/lexer/TokenTypes.js +1234 -0
  34. package/src/memory/MemoryManager.js +283 -0
  35. package/src/parser/AST.js +606 -0
  36. package/src/parser/Parser.js +1942 -0
  37. package/src/runtime/ThyRuntime.js +265 -0
  38. package/src/runtime/stdlib/ArrayLib.js +207 -0
  39. package/src/runtime/stdlib/FileLib.js +168 -0
  40. package/src/runtime/stdlib/MathLib.js +411 -0
  41. package/src/runtime/stdlib/StringLib.js +387 -0
  42. package/src/server/ControlPanel.js +1188 -0
  43. package/src/server/HTMLCSSEngine.js +866 -0
  44. package/src/server/SecurityEngine.js +714 -0
  45. package/src/server/ServerEngine.js +738 -0
  46. package/tests/test1_math.thy +82 -0
  47. package/tests/test2_oop.thy +133 -0
  48. package/tests/test3_server.thy +143 -0
  49. package/tests/test4_functions.thy +159 -0
@@ -0,0 +1,628 @@
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 value = this.value;
352
+ const operator = this.operator;
353
+ const previousValue = this.previousValue;
354
+ const display = this.display;
355
+ const isNewNumber = this.isNewNumber;
356
+ value = 0;
357
+ operator = '';
358
+ previousValue = 0;
359
+ display = '0';
360
+ isNewNumber = true;
361
+ }
362
+ compute(op, a, b) {
363
+ const value = this.value;
364
+ const operator = this.operator;
365
+ const previousValue = this.previousValue;
366
+ const display = this.display;
367
+ const isNewNumber = this.isNewNumber;
368
+ if ((op === '+')) {
369
+ return ((a + b));
370
+ }
371
+ if ((op === '-')) {
372
+ return ((a - b));
373
+ }
374
+ if ((op === '*')) {
375
+ return ((a * b));
376
+ }
377
+ if ((op === '/')) {
378
+ if ((b !== 0)) {
379
+ return ((a / b));
380
+ } else {
381
+ return 0;
382
+ }
383
+ }
384
+ return b;
385
+ }
386
+ }
387
+ let calc = new Calculator();
388
+ // [ThyScript] Server declaration
389
+ if (!__thy_express) throw new Error('[ThyScript] express is not installed. Run: npm install express');
390
+ __thy_app.use(require('express').json());
391
+ __thy_app.use(require('express').urlencoded({ extended: true }));
392
+ __thy_print('⚡ Starting ThyScript Calculator Web Server...');
393
+ const __thy_server = __thy_app.listen(3000, '0.0.0.0', () => {
394
+ __thy_print(`[ThyScript] Server running on http://${'0.0.0.0'}:${3000}`);
395
+ });
396
+ if (__thy_app) {
397
+ __thy_app.get('/', async (request, response) => {
398
+ const req = request; const res = response;
399
+ // HtmlClass: calculator_page
400
+ const __html_calculator_page = `<!DOCTYPE html>
401
+ <html lang="id">
402
+ <head>
403
+ <meta charset="UTF-8">
404
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
405
+ <title>ThyScript Calculator</title>
406
+ <style>
407
+ * { margin: 0; padding: 0; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
408
+ body {
409
+ background: radial-gradient(circle at 50% 20%, #1e1e38 0%, #0d0d1a 100%);
410
+ min-height: 100vh;
411
+ display: flex;
412
+ align-items: center;
413
+ justify-content: center;
414
+ color: #fff;
415
+ }
416
+ .calculator-card {
417
+ background: rgba(255, 255, 255, 0.05);
418
+ backdrop-filter: blur(25px);
419
+ -webkit-backdrop-filter: blur(25px);
420
+ border: 1px solid rgba(255, 255, 255, 0.15);
421
+ border-radius: 28px;
422
+ padding: 28px;
423
+ width: 360px;
424
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
425
+ }
426
+ .badge {
427
+ display: inline-block;
428
+ background: linear-gradient(135deg, #6366f1, #a855f7);
429
+ color: white;
430
+ font-size: 11px;
431
+ font-weight: 700;
432
+ padding: 4px 10px;
433
+ border-radius: 20px;
434
+ margin-bottom: 16px;
435
+ letter-spacing: 1px;
436
+ }
437
+ .display-container {
438
+ background: rgba(0, 0, 0, 0.4);
439
+ border: 1px solid rgba(255, 255, 255, 0.08);
440
+ border-radius: 18px;
441
+ padding: 20px;
442
+ text-align: right;
443
+ margin-bottom: 24px;
444
+ }
445
+ .history {
446
+ font-size: 14px;
447
+ color: rgba(255, 255, 255, 0.4);
448
+ min-height: 20px;
449
+ margin-bottom: 6px;
450
+ }
451
+ .current-value {
452
+ font-size: 38px;
453
+ font-weight: 300;
454
+ letter-spacing: 1px;
455
+ word-break: break-all;
456
+ }
457
+ .grid {
458
+ display: grid;
459
+ grid-template-columns: repeat(4, 1fr);
460
+ gap: 12px;
461
+ }
462
+ button {
463
+ border: none;
464
+ outline: none;
465
+ height: 60px;
466
+ border-radius: 16px;
467
+ font-size: 20px;
468
+ font-weight: 500;
469
+ cursor: pointer;
470
+ transition: all 0.15s ease;
471
+ display: flex;
472
+ align-items: center;
473
+ justify-content: center;
474
+ }
475
+ button:hover { transform: translateY(-2px); filter: brightness(1.2); }
476
+ button:active { transform: translateY(1px); }
477
+ .btn-num { background: rgba(255, 255, 255, 0.08); color: #fff; }
478
+ .btn-op { background: rgba(99, 102, 241, 0.25); color: #818cf8; }
479
+ .btn-action { background: rgba(239, 68, 68, 0.2); color: #f87171; }
480
+ .btn-equals {
481
+ grid-column: span 2;
482
+ background: linear-gradient(135deg, #6366f1, #a855f7);
483
+ color: white;
484
+ font-weight: 600;
485
+ }
486
+ .perf-badge {
487
+ text-align: center;
488
+ margin-top: 18px;
489
+ font-size: 12px;
490
+ color: #10b981;
491
+ }
492
+ </style>
493
+ </head>
494
+ <body>
495
+ <div class="calculator-card">
496
+ <div class="badge">⚡ THYSCRIPT JIT</div>
497
+ <div class="display-container">
498
+ <div class="history" id="historyText"></div>
499
+ <div class="current-value" id="displayText">0</div>
500
+ </div>
501
+ <div class="grid">
502
+ <button class="btn-action" onclick="handleClear()">C</button>
503
+ <button class="btn-op" onclick="handleOp('+/-')">±</button>
504
+ <button class="btn-op" onclick="handleOp('%')">%</button>
505
+ <button class="btn-op" onclick="handleOp('/')">÷</button>
506
+
507
+ <button class="btn-num" onclick="handleDigit('7')">7</button>
508
+ <button class="btn-num" onclick="handleDigit('8')">8</button>
509
+ <button class="btn-num" onclick="handleDigit('9')">9</button>
510
+ <button class="btn-op" onclick="handleOp('*')">×</button>
511
+
512
+ <button class="btn-num" onclick="handleDigit('4')">4</button>
513
+ <button class="btn-num" onclick="handleDigit('5')">5</button>
514
+ <button class="btn-num" onclick="handleDigit('6')">6</button>
515
+ <button class="btn-op" onclick="handleOp('-')">−</button>
516
+
517
+ <button class="btn-num" onclick="handleDigit('1')">1</button>
518
+ <button class="btn-num" onclick="handleDigit('2')">2</button>
519
+ <button class="btn-num" onclick="handleDigit('3')">3</button>
520
+ <button class="btn-op" onclick="handleOp('+')">+</button>
521
+
522
+ <button class="btn-num" onclick="handleDigit('0')">0</button>
523
+ <button class="btn-num" onclick="handleDigit('.')">.</button>
524
+ <button class="btn-equals" onclick="handleEquals()">=</button>
525
+ </div>
526
+ <div class="perf-badge">🚀 12x Accelerated Math Preprocessing</div>
527
+ </div>
528
+
529
+ <script>
530
+ let cur = '0';
531
+ let prev = null;
532
+ let op = null;
533
+ let reset = false;
534
+
535
+ const disp = document.getElementById('displayText');
536
+ const hist = document.getElementById('historyText');
537
+
538
+ function update() {
539
+ disp.innerText = cur;
540
+ }
541
+
542
+ function handleDigit(d) {
543
+ if (reset || cur === '0') {
544
+ cur = d === '.' ? '0.' : d;
545
+ reset = false;
546
+ } else {
547
+ if (d === '.' && cur.includes('.')) return;
548
+ cur += d;
549
+ }
550
+ update();
551
+ }
552
+
553
+ function handleOp(nextOp) {
554
+ if (nextOp === '+/-') {
555
+ cur = String(-parseFloat(cur));
556
+ update();
557
+ return;
558
+ }
559
+ if (nextOp === '%') {
560
+ cur = String(parseFloat(cur) / 100);
561
+ update();
562
+ return;
563
+ }
564
+ if (op && !reset) {
565
+ calculate();
566
+ }
567
+ prev = parseFloat(cur);
568
+ op = nextOp;
569
+ reset = true;
570
+ hist.innerText = prev + ' ' + op;
571
+ }
572
+
573
+ function calculate() {
574
+ if (!op || prev === null) return;
575
+ const b = parseFloat(cur);
576
+ let res = 0;
577
+ if (op === '+') res = prev + b;
578
+ if (op === '-') res = prev - b;
579
+ if (op === '*') res = prev * b;
580
+ if (op === '/') res = b !== 0 ? prev / b : 'Error';
581
+ cur = String(res);
582
+ op = null;
583
+ prev = null;
584
+ reset = true;
585
+ hist.innerText = '';
586
+ update();
587
+ }
588
+
589
+ function handleEquals() {
590
+ calculate();
591
+ }
592
+
593
+ function handleClear() {
594
+ cur = '0';
595
+ prev = null;
596
+ op = null;
597
+ reset = false;
598
+ hist.innerText = '';
599
+ update();
600
+ }
601
+ </script>
602
+ </body>
603
+ </html>`;
604
+ if (typeof response !== 'undefined' && response && typeof response.send === 'function') {
605
+ response.setHeader('Content-Type', 'text/html; charset=utf-8');
606
+ response.send(__html_calculator_page);
607
+ } else if (typeof __thy_app !== 'undefined' && __thy_app) {
608
+ __thy_app.get('/calculator_page', (req, res) => {
609
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
610
+ res.send(__html_calculator_page);
611
+ });
612
+ }
613
+ });
614
+ }
615
+ if (__thy_app) {
616
+ __thy_app.get('/api/eval', async (request, response) => {
617
+ const req = request; const res = response;
618
+ let expr = request.query.expr;
619
+ if (expr) {
620
+ let result = (expr);
621
+ response.json({ 'success': true, 'result': result, 'poweredBy': 'ThyScript JIT' });
622
+ } else {
623
+ response.json({ 'success': false, 'message': 'No expression provided' });
624
+ }
625
+ });
626
+ }
627
+ __thy_print(('🚀 ThyScript Calculator application loaded successfully on port ' + port));
628
+ })().catch(e => { console.error("[ThyScript Runtime Error]", e); process.exit(1); });
@@ -0,0 +1,34 @@
1
+ // ThyScript Hello World
2
+ print("Hello, World!")
3
+
4
+ const table name = "ThyScript"
5
+ const table version = "1.0.0"
6
+
7
+ print("Welcome to " + name + " v" + version)
8
+ print("Fast. Powerful. Beautiful.")
9
+
10
+ // Math calculation example
11
+ const table x = 10
12
+ const table y = 20
13
+ add 10 in x
14
+ add 10 in y
15
+ print("x + y = " + calculate(x + y))
16
+
17
+ // Loop example
18
+ const table count = 0
19
+ while(count < 5):
20
+ print("Count: " + count)
21
+ add 1 in count
22
+ end()
23
+
24
+ // Class example
25
+ public class(Greeter):
26
+ const table message = "Hello from ThyScript!"
27
+
28
+ func greet(who):
29
+ print(message + " " + who + "!")
30
+ end()
31
+ end()
32
+
33
+ const table g = new Greeter()
34
+ g.greet("World")