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.
- package/bin/thy-node.js +332 -0
- package/bin/thy.js +828 -0
- package/bin/thys.js +25 -0
- package/examples/calculator.thy +274 -0
- package/examples/calculator.thy.js +628 -0
- package/examples/hello.thy +34 -0
- package/examples/login.thy +382 -0
- package/examples/login.thy.js +710 -0
- package/package.json +54 -0
- package/scripts/_class.js +18 -0
- package/scripts/_class2.js +11 -0
- package/scripts/_class3.js +21 -0
- package/scripts/_dstruct.js +20 -0
- package/scripts/_dstruct2.js +24 -0
- package/scripts/_scaffold.js +16 -0
- package/scripts/_scaffold2.js +16 -0
- package/scripts/_scaffold3.js +26 -0
- package/scripts/_tpl_compile.js +13 -0
- package/scripts/_tpl_test.js +9 -0
- package/scripts/_typeof.js +26 -0
- package/scripts/_typeof2.js +25 -0
- package/scripts/patch_genmethod.js +44 -0
- package/scripts/smoke_test.js +167 -0
- package/scripts/smoke_test2.js +151 -0
- package/scripts/test_control_panel.js +58 -0
- package/src/compiler/CodeGenerator.js +1449 -0
- package/src/compiler/JITCompiler.js +325 -0
- package/src/database/DatabaseEngine.js +931 -0
- package/src/errors/ErrorDetector.js +305 -0
- package/src/errors/ErrorMessages.js +497 -0
- package/src/index.js +169 -0
- package/src/lexer/Lexer.js +342 -0
- package/src/lexer/TokenTypes.js +1234 -0
- package/src/memory/MemoryManager.js +283 -0
- package/src/parser/AST.js +606 -0
- package/src/parser/Parser.js +1942 -0
- package/src/runtime/ThyRuntime.js +265 -0
- package/src/runtime/stdlib/ArrayLib.js +207 -0
- package/src/runtime/stdlib/FileLib.js +168 -0
- package/src/runtime/stdlib/MathLib.js +411 -0
- package/src/runtime/stdlib/StringLib.js +387 -0
- package/src/server/ControlPanel.js +1188 -0
- package/src/server/HTMLCSSEngine.js +866 -0
- package/src/server/SecurityEngine.js +714 -0
- package/src/server/ServerEngine.js +738 -0
- package/tests/test1_math.thy +82 -0
- package/tests/test2_oop.thy +133 -0
- package/tests/test3_server.thy +143 -0
- package/tests/test4_functions.thy +159 -0
package/bin/thys.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* thys - ThyScript Universal CLI & Control Panel Launcher
|
|
6
|
+
* Usage:
|
|
7
|
+
* thys panel Launch the Live Web Control Panel
|
|
8
|
+
* thys run <file.thy> Run a ThyScript file
|
|
9
|
+
* thys compile <file.thy> Compile to JavaScript
|
|
10
|
+
* thys check Check environment & dependencies
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
// Pass through to bin/thy.js
|
|
16
|
+
// If invoked with no args or 'panel' or 'control-panel', default to panel if intended or forward args
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
if (args.length === 0 || args[0] === 'panel' || args[0] === 'control-panel') {
|
|
19
|
+
// Directly forward with 'panel' if empty
|
|
20
|
+
if (args.length === 0) {
|
|
21
|
+
process.argv.push('panel');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
require(path.join(__dirname, 'thy.js'));
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════
|
|
2
|
+
// ThyScript Web Calculator Application
|
|
3
|
+
// High-Performance Scientific Calculator & API
|
|
4
|
+
// ═══════════════════════════════════════════════════════════════
|
|
5
|
+
|
|
6
|
+
const table port = 3000
|
|
7
|
+
const table title = "ThyScript Advanced Calculator"
|
|
8
|
+
|
|
9
|
+
// Calculator Class with mathematical memory & state
|
|
10
|
+
public class(Calculator):
|
|
11
|
+
const table value = 0
|
|
12
|
+
const table operator = ""
|
|
13
|
+
const table previousValue = 0
|
|
14
|
+
const table display = "0"
|
|
15
|
+
const table isNewNumber = true
|
|
16
|
+
|
|
17
|
+
func clear():
|
|
18
|
+
change(value to(0))
|
|
19
|
+
change(operator to(""))
|
|
20
|
+
change(previousValue to(0))
|
|
21
|
+
change(display to("0"))
|
|
22
|
+
change(isNewNumber to(true))
|
|
23
|
+
end()
|
|
24
|
+
|
|
25
|
+
func compute(op, a, b):
|
|
26
|
+
if(op == "+"):
|
|
27
|
+
return calculate(a + b)
|
|
28
|
+
end()
|
|
29
|
+
if(op == "-"):
|
|
30
|
+
return calculate(a - b)
|
|
31
|
+
end()
|
|
32
|
+
if(op == "*"):
|
|
33
|
+
return calculate(a * b)
|
|
34
|
+
end()
|
|
35
|
+
if(op == "/"):
|
|
36
|
+
if(b != 0):
|
|
37
|
+
return calculate(a / b)
|
|
38
|
+
else:
|
|
39
|
+
return 0
|
|
40
|
+
end()
|
|
41
|
+
end()
|
|
42
|
+
return b
|
|
43
|
+
end()
|
|
44
|
+
end()
|
|
45
|
+
|
|
46
|
+
const table calc = new Calculator()
|
|
47
|
+
|
|
48
|
+
// Initialize Web Server
|
|
49
|
+
server(3000):
|
|
50
|
+
print("⚡ Starting ThyScript Calculator Web Server...")
|
|
51
|
+
end()
|
|
52
|
+
|
|
53
|
+
// Web UI Route
|
|
54
|
+
route get "/":
|
|
55
|
+
classHtml(calculator_page):
|
|
56
|
+
<!DOCTYPE html>
|
|
57
|
+
<html lang="id">
|
|
58
|
+
<head>
|
|
59
|
+
<meta charset="UTF-8">
|
|
60
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
61
|
+
<title>ThyScript Calculator</title>
|
|
62
|
+
<style>
|
|
63
|
+
* { margin: 0; padding: 0; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
|
|
64
|
+
body {
|
|
65
|
+
background: radial-gradient(circle at 50% 20%, #1e1e38 0%, #0d0d1a 100%);
|
|
66
|
+
min-height: 100vh;
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
justify-content: center;
|
|
70
|
+
color: #fff;
|
|
71
|
+
}
|
|
72
|
+
.calculator-card {
|
|
73
|
+
background: rgba(255, 255, 255, 0.05);
|
|
74
|
+
backdrop-filter: blur(25px);
|
|
75
|
+
-webkit-backdrop-filter: blur(25px);
|
|
76
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
77
|
+
border-radius: 28px;
|
|
78
|
+
padding: 28px;
|
|
79
|
+
width: 360px;
|
|
80
|
+
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
|
|
81
|
+
}
|
|
82
|
+
.badge {
|
|
83
|
+
display: inline-block;
|
|
84
|
+
background: linear-gradient(135deg, #6366f1, #a855f7);
|
|
85
|
+
color: white;
|
|
86
|
+
font-size: 11px;
|
|
87
|
+
font-weight: 700;
|
|
88
|
+
padding: 4px 10px;
|
|
89
|
+
border-radius: 20px;
|
|
90
|
+
margin-bottom: 16px;
|
|
91
|
+
letter-spacing: 1px;
|
|
92
|
+
}
|
|
93
|
+
.display-container {
|
|
94
|
+
background: rgba(0, 0, 0, 0.4);
|
|
95
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
96
|
+
border-radius: 18px;
|
|
97
|
+
padding: 20px;
|
|
98
|
+
text-align: right;
|
|
99
|
+
margin-bottom: 24px;
|
|
100
|
+
}
|
|
101
|
+
.history {
|
|
102
|
+
font-size: 14px;
|
|
103
|
+
color: rgba(255, 255, 255, 0.4);
|
|
104
|
+
min-height: 20px;
|
|
105
|
+
margin-bottom: 6px;
|
|
106
|
+
}
|
|
107
|
+
.current-value {
|
|
108
|
+
font-size: 38px;
|
|
109
|
+
font-weight: 300;
|
|
110
|
+
letter-spacing: 1px;
|
|
111
|
+
word-break: break-all;
|
|
112
|
+
}
|
|
113
|
+
.grid {
|
|
114
|
+
display: grid;
|
|
115
|
+
grid-template-columns: repeat(4, 1fr);
|
|
116
|
+
gap: 12px;
|
|
117
|
+
}
|
|
118
|
+
button {
|
|
119
|
+
border: none;
|
|
120
|
+
outline: none;
|
|
121
|
+
height: 60px;
|
|
122
|
+
border-radius: 16px;
|
|
123
|
+
font-size: 20px;
|
|
124
|
+
font-weight: 500;
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
transition: all 0.15s ease;
|
|
127
|
+
display: flex;
|
|
128
|
+
align-items: center;
|
|
129
|
+
justify-content: center;
|
|
130
|
+
}
|
|
131
|
+
button:hover { transform: translateY(-2px); filter: brightness(1.2); }
|
|
132
|
+
button:active { transform: translateY(1px); }
|
|
133
|
+
.btn-num { background: rgba(255, 255, 255, 0.08); color: #fff; }
|
|
134
|
+
.btn-op { background: rgba(99, 102, 241, 0.25); color: #818cf8; }
|
|
135
|
+
.btn-action { background: rgba(239, 68, 68, 0.2); color: #f87171; }
|
|
136
|
+
.btn-equals {
|
|
137
|
+
grid-column: span 2;
|
|
138
|
+
background: linear-gradient(135deg, #6366f1, #a855f7);
|
|
139
|
+
color: white;
|
|
140
|
+
font-weight: 600;
|
|
141
|
+
}
|
|
142
|
+
.perf-badge {
|
|
143
|
+
text-align: center;
|
|
144
|
+
margin-top: 18px;
|
|
145
|
+
font-size: 12px;
|
|
146
|
+
color: #10b981;
|
|
147
|
+
}
|
|
148
|
+
</style>
|
|
149
|
+
</head>
|
|
150
|
+
<body>
|
|
151
|
+
<div class="calculator-card">
|
|
152
|
+
<div class="badge">⚡ THYSCRIPT JIT</div>
|
|
153
|
+
<div class="display-container">
|
|
154
|
+
<div class="history" id="historyText"></div>
|
|
155
|
+
<div class="current-value" id="displayText">0</div>
|
|
156
|
+
</div>
|
|
157
|
+
<div class="grid">
|
|
158
|
+
<button class="btn-action" onclick="handleClear()">C</button>
|
|
159
|
+
<button class="btn-op" onclick="handleOp('+/-')">±</button>
|
|
160
|
+
<button class="btn-op" onclick="handleOp('%')">%</button>
|
|
161
|
+
<button class="btn-op" onclick="handleOp('/')">÷</button>
|
|
162
|
+
|
|
163
|
+
<button class="btn-num" onclick="handleDigit('7')">7</button>
|
|
164
|
+
<button class="btn-num" onclick="handleDigit('8')">8</button>
|
|
165
|
+
<button class="btn-num" onclick="handleDigit('9')">9</button>
|
|
166
|
+
<button class="btn-op" onclick="handleOp('*')">×</button>
|
|
167
|
+
|
|
168
|
+
<button class="btn-num" onclick="handleDigit('4')">4</button>
|
|
169
|
+
<button class="btn-num" onclick="handleDigit('5')">5</button>
|
|
170
|
+
<button class="btn-num" onclick="handleDigit('6')">6</button>
|
|
171
|
+
<button class="btn-op" onclick="handleOp('-')">−</button>
|
|
172
|
+
|
|
173
|
+
<button class="btn-num" onclick="handleDigit('1')">1</button>
|
|
174
|
+
<button class="btn-num" onclick="handleDigit('2')">2</button>
|
|
175
|
+
<button class="btn-num" onclick="handleDigit('3')">3</button>
|
|
176
|
+
<button class="btn-op" onclick="handleOp('+')">+</button>
|
|
177
|
+
|
|
178
|
+
<button class="btn-num" onclick="handleDigit('0')">0</button>
|
|
179
|
+
<button class="btn-num" onclick="handleDigit('.')">.</button>
|
|
180
|
+
<button class="btn-equals" onclick="handleEquals()">=</button>
|
|
181
|
+
</div>
|
|
182
|
+
<div class="perf-badge">🚀 12x Accelerated Math Preprocessing</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<script>
|
|
186
|
+
let cur = '0';
|
|
187
|
+
let prev = null;
|
|
188
|
+
let op = null;
|
|
189
|
+
let reset = false;
|
|
190
|
+
|
|
191
|
+
const disp = document.getElementById('displayText');
|
|
192
|
+
const hist = document.getElementById('historyText');
|
|
193
|
+
|
|
194
|
+
function update() {
|
|
195
|
+
disp.innerText = cur;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function handleDigit(d) {
|
|
199
|
+
if (reset || cur === '0') {
|
|
200
|
+
cur = d === '.' ? '0.' : d;
|
|
201
|
+
reset = false;
|
|
202
|
+
} else {
|
|
203
|
+
if (d === '.' && cur.includes('.')) return;
|
|
204
|
+
cur += d;
|
|
205
|
+
}
|
|
206
|
+
update();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function handleOp(nextOp) {
|
|
210
|
+
if (nextOp === '+/-') {
|
|
211
|
+
cur = String(-parseFloat(cur));
|
|
212
|
+
update();
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (nextOp === '%') {
|
|
216
|
+
cur = String(parseFloat(cur) / 100);
|
|
217
|
+
update();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (op && !reset) {
|
|
221
|
+
calculate();
|
|
222
|
+
}
|
|
223
|
+
prev = parseFloat(cur);
|
|
224
|
+
op = nextOp;
|
|
225
|
+
reset = true;
|
|
226
|
+
hist.innerText = prev + ' ' + op;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function calculate() {
|
|
230
|
+
if (!op || prev === null) return;
|
|
231
|
+
const b = parseFloat(cur);
|
|
232
|
+
let res = 0;
|
|
233
|
+
if (op === '+') res = prev + b;
|
|
234
|
+
if (op === '-') res = prev - b;
|
|
235
|
+
if (op === '*') res = prev * b;
|
|
236
|
+
if (op === '/') res = b !== 0 ? prev / b : 'Error';
|
|
237
|
+
cur = String(res);
|
|
238
|
+
op = null;
|
|
239
|
+
prev = null;
|
|
240
|
+
reset = true;
|
|
241
|
+
hist.innerText = '';
|
|
242
|
+
update();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function handleEquals() {
|
|
246
|
+
calculate();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function handleClear() {
|
|
250
|
+
cur = '0';
|
|
251
|
+
prev = null;
|
|
252
|
+
op = null;
|
|
253
|
+
reset = false;
|
|
254
|
+
hist.innerText = '';
|
|
255
|
+
update();
|
|
256
|
+
}
|
|
257
|
+
</script>
|
|
258
|
+
</body>
|
|
259
|
+
</html>
|
|
260
|
+
end()
|
|
261
|
+
end()
|
|
262
|
+
|
|
263
|
+
// Backend API route for server-side evaluation
|
|
264
|
+
route get "/api/eval":
|
|
265
|
+
const table expr = request.query.expr
|
|
266
|
+
if(expr):
|
|
267
|
+
const table result = calculate(expr)
|
|
268
|
+
response.json({ success: true, result: result, poweredBy: "ThyScript JIT" })
|
|
269
|
+
else:
|
|
270
|
+
response.json({ success: false, message: "No expression provided" })
|
|
271
|
+
end()
|
|
272
|
+
end()
|
|
273
|
+
|
|
274
|
+
print("🚀 ThyScript Calculator application loaded successfully on port " + port)
|