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,82 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // TEST 1: Math & Arithmetic Operations
3
+ // Menguji semua operasi matematika ThyScript
4
+ // ═══════════════════════════════════════════════════════
5
+
6
+ print("=== TEST 1: MATH & ARITHMETIC ===")
7
+
8
+ // Basic arithmetic
9
+ const table a = 100
10
+ const table b = 37
11
+ const table c = calculate(a + b)
12
+ print("100 + 37 = " + c)
13
+
14
+ const table d = calculate(a - b)
15
+ print("100 - 37 = " + d)
16
+
17
+ const table e = calculate(a * b)
18
+ print("100 * 37 = " + e)
19
+
20
+ const table f = calculate(a / b)
21
+ print("100 / 37 = " + f)
22
+
23
+ // Power
24
+ const table g = calculate(2 ** 10)
25
+ print("2^10 = " + g)
26
+
27
+ // Modulo
28
+ const table h = calculate(100 % 7)
29
+ print("100 mod 7 = " + h)
30
+
31
+ // Floating point
32
+ const table pi = 3.14159
33
+ const table radius = 5.0
34
+ const table area = calculate(pi * radius * radius)
35
+ print("Circle area r=5: " + area)
36
+
37
+ // Compound operations
38
+ const table result = calculate((a + b) * 2 - 10)
39
+ print("(100+37)*2-10 = " + result)
40
+
41
+ // Variable mutation with add
42
+ const table counter = 0
43
+ add 1 in counter
44
+ add 1 in counter
45
+ add 1 in counter
46
+ print("Counter after 3 adds: " + counter)
47
+
48
+ // Variable reassignment with change
49
+ const table x = 10
50
+ change(x to(99))
51
+ print("x after change to 99: " + x)
52
+
53
+ // Conditionals with math
54
+ const table score = 85
55
+ if(score >= 90):
56
+ print("Grade: A")
57
+ elif(score >= 80):
58
+ print("Grade: B")
59
+ elif(score >= 70):
60
+ print("Grade: C")
61
+ else:
62
+ print("Grade: D")
63
+ end()
64
+
65
+ // While loop with counter
66
+ const table n = 0
67
+ const table sum = 0
68
+ while(n < 5):
69
+ add n in sum
70
+ add 1 in n
71
+ end()
72
+ print("Sum 0+1+2+3+4 = " + sum)
73
+
74
+ // For loop
75
+ const table nums = [10, 20, 30, 40, 50]
76
+ const table total = 0
77
+ for num in nums:
78
+ add num in total
79
+ end()
80
+ print("Sum of array [10,20,30,40,50] = " + total)
81
+
82
+ print("=== TEST 1 PASSED ===")
@@ -0,0 +1,133 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // TEST 2: OOP & Classes
3
+ // Menguji class, inheritance, method, encapsulation
4
+ // ═══════════════════════════════════════════════════════
5
+
6
+ print("=== TEST 2: OOP & CLASSES ===")
7
+
8
+ // Basic class
9
+ public class(Animal):
10
+ const table name = "Unknown"
11
+ const table sound = "..."
12
+ const table legs = 4
13
+
14
+ func speak():
15
+ print(name + " says " + sound)
16
+ end()
17
+
18
+ func describe():
19
+ print(name + " has " + legs + " legs")
20
+ end()
21
+ end()
22
+
23
+ // Instantiate and use
24
+ const table dog = new Animal()
25
+ change(dog.name to("Rex"))
26
+ change(dog.sound to("Woof"))
27
+ dog.speak()
28
+ dog.describe()
29
+
30
+ const table cat = new Animal()
31
+ change(cat.name to("Mimi"))
32
+ change(cat.sound to("Meow"))
33
+ change(cat.legs to(4))
34
+ cat.speak()
35
+ cat.describe()
36
+
37
+ // Class with computation
38
+ public class(Calculator):
39
+ const table memory = 0
40
+ const table history = []
41
+
42
+ func add(a, b):
43
+ const table result = calculate(a + b)
44
+ add result in history
45
+ return result
46
+ end()
47
+
48
+ func subtract(a, b):
49
+ const table result = calculate(a - b)
50
+ add result in history
51
+ return result
52
+ end()
53
+
54
+ func multiply(a, b):
55
+ const table result = calculate(a * b)
56
+ add result in history
57
+ return result
58
+ end()
59
+
60
+ func divide(a, b):
61
+ if(b == 0):
62
+ print("Error: Division by zero!")
63
+ return 0
64
+ end()
65
+ const table result = calculate(a / b)
66
+ add result in history
67
+ return result
68
+ end()
69
+
70
+ func storeMemory(val):
71
+ change(memory to(val))
72
+ print("Stored in memory: " + val)
73
+ end()
74
+
75
+ func recallMemory():
76
+ return memory
77
+ end()
78
+ end()
79
+
80
+ const table calc = new Calculator()
81
+ const table r1 = calc.add(50, 30)
82
+ print("50 + 30 = " + r1)
83
+
84
+ const table r2 = calc.multiply(12, 8)
85
+ print("12 * 8 = " + r2)
86
+
87
+ const table r3 = calc.divide(100, 4)
88
+ print("100 / 4 = " + r3)
89
+
90
+ const table r4 = calc.divide(5, 0)
91
+ print("5 / 0 = " + r4)
92
+
93
+ calc.storeMemory(42)
94
+ const table mem = calc.recallMemory()
95
+ print("Recalled memory: " + mem)
96
+
97
+ // Nested objects
98
+ public class(Person):
99
+ const table firstName = ""
100
+ const table lastName = ""
101
+ const table age = 0
102
+
103
+ func fullName():
104
+ return firstName + " " + lastName
105
+ end()
106
+
107
+ func isAdult():
108
+ return age >= 18
109
+ end()
110
+
111
+ func greet():
112
+ const table name = fullName()
113
+ if(isAdult()):
114
+ print("Hello, " + name + "! You are an adult.")
115
+ else:
116
+ print("Hello, " + name + "! You are a minor.")
117
+ end()
118
+ end()
119
+ end()
120
+
121
+ const table p1 = new Person()
122
+ change(p1.firstName to("Budi"))
123
+ change(p1.lastName to("Santoso"))
124
+ change(p1.age to(25))
125
+ p1.greet()
126
+
127
+ const table p2 = new Person()
128
+ change(p2.firstName to("Ani"))
129
+ change(p2.lastName to("Putri"))
130
+ change(p2.age to(15))
131
+ p2.greet()
132
+
133
+ print("=== TEST 2 PASSED ===")
@@ -0,0 +1,143 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // TEST 3: Server, Routes, API & Web
3
+ // Menguji HTTP server, routes GET/POST, JSON API
4
+ // ═══════════════════════════════════════════════════════
5
+
6
+ const table port = 4200
7
+
8
+ print("=== TEST 3: SERVER & API ===")
9
+
10
+ // Simple data store (in-memory DB)
11
+ const table items = []
12
+ const table idCounter = 1
13
+
14
+ // Initialize server
15
+ server(4200):
16
+ print("Test 3 Server starting on port 4200...")
17
+ end()
18
+
19
+ // Health check route
20
+ route get "/health":
21
+ response.json({
22
+ status: "ok",
23
+ server: "ThyScript Test Server",
24
+ timestamp: Date.now(),
25
+ version: "1.0.0"
26
+ })
27
+ end()
28
+
29
+ // GET all items
30
+ route get "/api/items":
31
+ response.json({
32
+ success: true,
33
+ count: items.length,
34
+ items: items
35
+ })
36
+ end()
37
+
38
+ // POST create item
39
+ route post "/api/items":
40
+ const table name = request.body.name
41
+ const table value = request.body.value
42
+
43
+ if(not name):
44
+ response.json({ success: false, message: "name is required" })
45
+ else:
46
+ const table newItem = {
47
+ id: idCounter,
48
+ name: name,
49
+ value: value || 0,
50
+ createdAt: new Date().toISOString()
51
+ }
52
+ add newItem in items
53
+ add 1 in idCounter
54
+ print("Created item: " + name)
55
+ response.json({ success: true, item: newItem })
56
+ end()
57
+ end()
58
+
59
+ // GET single item by id
60
+ route get "/api/items/:id":
61
+ const table id = parseInt(request.params.id)
62
+ const table found = items.find(i => i.id == id)
63
+ if(found):
64
+ response.json({ success: true, item: found })
65
+ else:
66
+ response.json({ success: false, message: "Item not found" })
67
+ end()
68
+ end()
69
+
70
+ // GET stats
71
+ route get "/api/stats":
72
+ const table count = items.length
73
+ const table total = items.reduce((acc, i) => acc + (i.value || 0), 0)
74
+ const table avg = count > 0 ? calculate(total / count) : 0
75
+ response.json({
76
+ success: true,
77
+ stats: {
78
+ totalItems: count,
79
+ totalValue: total,
80
+ averageValue: avg,
81
+ serverUptime: process.uptime(),
82
+ memUsage: process.memoryUsage().heapUsed
83
+ }
84
+ })
85
+ end()
86
+
87
+ // Web UI
88
+ route get "/":
89
+ classHtml(test3_page):
90
+ <!DOCTYPE html>
91
+ <html lang="id">
92
+ <head>
93
+ <meta charset="UTF-8">
94
+ <title>ThyScript Test 3 - Server & API</title>
95
+ <style>
96
+ body { font-family: monospace; background: #0d0d1a; color: #0f0; padding: 20px; }
97
+ h1 { color: #6366f1; }
98
+ .btn { background: #6366f1; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; margin: 4px; }
99
+ .btn:hover { opacity: 0.85; }
100
+ .output { background: #111; border: 1px solid #333; border-radius: 8px; padding: 16px; margin-top: 16px; min-height: 100px; white-space: pre-wrap; font-size: 13px; }
101
+ input { background: #1a1a2e; border: 1px solid #333; color: #fff; padding: 6px 10px; border-radius: 6px; margin: 4px; }
102
+ </style>
103
+ </head>
104
+ <body>
105
+ <h1>⚡ ThyScript Test 3 - Server API</h1>
106
+ <p>HTTP Server running on port 4200</p>
107
+ <div>
108
+ <button class="btn" onclick="checkHealth()">Health Check</button>
109
+ <button class="btn" onclick="getItems()">Get All Items</button>
110
+ <button class="btn" onclick="getStats()">Get Stats</button>
111
+ </div>
112
+ <div>
113
+ <input id="itemName" placeholder="Item name" />
114
+ <input id="itemValue" type="number" placeholder="Value" />
115
+ <button class="btn" onclick="createItem()">Add Item</button>
116
+ </div>
117
+ <div class="output" id="out">Click a button to test the API...</div>
118
+ <script>
119
+ async function req(url, opts) {
120
+ const r = await fetch(url, opts);
121
+ const d = await r.json();
122
+ document.getElementById('out').textContent = JSON.stringify(d, null, 2);
123
+ }
124
+ function checkHealth() { req('/health'); }
125
+ function getItems() { req('/api/items'); }
126
+ function getStats() { req('/api/stats'); }
127
+ function createItem() {
128
+ const name = document.getElementById('itemName').value;
129
+ const value = +document.getElementById('itemValue').value || 0;
130
+ req('/api/items', {
131
+ method: 'POST',
132
+ headers: { 'Content-Type': 'application/json' },
133
+ body: JSON.stringify({ name, value })
134
+ });
135
+ }
136
+ </script>
137
+ </body>
138
+ </html>
139
+ end()
140
+ end()
141
+
142
+ print("🚀 TEST 3 SERVER READY on port " + port)
143
+ print("Open http://localhost:4200 to test")
@@ -0,0 +1,159 @@
1
+ // ═══════════════════════════════════════════════════════
2
+ // TEST 4: Functions, Closures, Error Handling
3
+ // Menguji func, recursion, try/catch, complex logic
4
+ // ═══════════════════════════════════════════════════════
5
+
6
+ print("=== TEST 4: FUNCTIONS & ERROR HANDLING ===")
7
+
8
+ // Basic function
9
+ func greet(name):
10
+ return "Hello, " + name + "!"
11
+ end()
12
+
13
+ const table msg = greet("ThyScript")
14
+ print(msg)
15
+
16
+ // Recursive function - factorial
17
+ func factorial(n):
18
+ if(n <= 1):
19
+ return 1
20
+ end()
21
+ return calculate(n * factorial(n - 1))
22
+ end()
23
+
24
+ print("5! = " + factorial(5))
25
+ print("10! = " + factorial(10))
26
+
27
+ // Fibonacci
28
+ func fibonacci(n):
29
+ if(n <= 0):
30
+ return 0
31
+ end()
32
+ if(n == 1):
33
+ return 1
34
+ end()
35
+ return calculate(fibonacci(n - 1) + fibonacci(n - 2))
36
+ end()
37
+
38
+ print("fib(7) = " + fibonacci(7))
39
+ print("fib(10) = " + fibonacci(10))
40
+
41
+ // Function with multiple params and default logic
42
+ func clamp(value, minVal, maxVal):
43
+ if(value < minVal):
44
+ return minVal
45
+ end()
46
+ if(value > maxVal):
47
+ return maxVal
48
+ end()
49
+ return value
50
+ end()
51
+
52
+ print("clamp(5, 0, 10) = " + clamp(5, 0, 10))
53
+ print("clamp(-3, 0, 10) = " + clamp(-3, 0, 10))
54
+ print("clamp(15, 0, 10) = " + clamp(15, 0, 10))
55
+
56
+ // Higher order function usage
57
+ func applyTwice(fn, x):
58
+ return fn(fn(x))
59
+ end()
60
+
61
+ func double(n):
62
+ return calculate(n * 2)
63
+ end()
64
+
65
+ func addTen(n):
66
+ return calculate(n + 10)
67
+ end()
68
+
69
+ print("applyTwice(double, 3) = " + applyTwice(double, 3))
70
+ print("applyTwice(addTen, 5) = " + applyTwice(addTen, 5))
71
+
72
+ // Try/catch error handling
73
+ func safeDivide(a, b):
74
+ if(b == 0):
75
+ return "ERROR: division by zero"
76
+ end()
77
+ return calculate(a / b)
78
+ end()
79
+
80
+ print("safeDivide(10, 2) = " + safeDivide(10, 2))
81
+ print("safeDivide(5, 0) = " + safeDivide(5, 0))
82
+
83
+ // Array operations with functions
84
+ func sumArray(arr):
85
+ const table total = 0
86
+ for item in arr:
87
+ add item in total
88
+ end()
89
+ return total
90
+ end()
91
+
92
+ func maxArray(arr):
93
+ const table best = arr[0]
94
+ for item in arr:
95
+ if(item > best):
96
+ change(best to(item))
97
+ end()
98
+ end()
99
+ return best
100
+ end()
101
+
102
+ func minArray(arr):
103
+ const table least = arr[0]
104
+ for item in arr:
105
+ if(item < least):
106
+ change(least to(item))
107
+ end()
108
+ end()
109
+ return least
110
+ end()
111
+
112
+ const table data = [42, 7, 93, 15, 88, 3, 56, 71]
113
+ print("Array: [42, 7, 93, 15, 88, 3, 56, 71]")
114
+ print("Sum = " + sumArray(data))
115
+ print("Max = " + maxArray(data))
116
+ print("Min = " + minArray(data))
117
+
118
+ // String operations
119
+ func reverseString(s):
120
+ return s.split("").reverse().join("")
121
+ end()
122
+
123
+ func isPalindrome(s):
124
+ const table rev = reverseString(s)
125
+ return s == rev
126
+ end()
127
+
128
+ print("reverse('ThyScript') = " + reverseString("ThyScript"))
129
+ print("isPalindrome('racecar') = " + isPalindrome("racecar"))
130
+ print("isPalindrome('hello') = " + isPalindrome("hello"))
131
+
132
+ // Complex nested logic
133
+ func classify(n):
134
+ if(n < 0):
135
+ return "negative"
136
+ end()
137
+ if(n == 0):
138
+ return "zero"
139
+ end()
140
+ if(calculate(n % 2) == 0):
141
+ if(n > 100):
142
+ return "large even"
143
+ end()
144
+ return "even"
145
+ end()
146
+ if(n > 100):
147
+ return "large odd"
148
+ end()
149
+ return "odd"
150
+ end()
151
+
152
+ print("classify(-5) = " + classify(-5))
153
+ print("classify(0) = " + classify(0))
154
+ print("classify(4) = " + classify(4))
155
+ print("classify(7) = " + classify(7))
156
+ print("classify(200) = " + classify(200))
157
+ print("classify(201) = " + classify(201))
158
+
159
+ print("=== TEST 4 PASSED ===")