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
|
@@ -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 ===")
|