All incomplete examples have been updated and some corrections have been made to the parser to make them work. (0.37.17)
This commit is contained in:
parent
37c5ae6f58
commit
92aacff71a
41 changed files with 654 additions and 130 deletions
|
|
@ -15,3 +15,9 @@ boolean b = false
|
|||
print("b => " + to_string(b))
|
||||
/* Try typeof via built-in function if available */
|
||||
print("typeof(b) => " + typeof(b))
|
||||
|
||||
/* Expected output:
|
||||
b => false
|
||||
typeof(b) => Boolean
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -52,3 +52,25 @@ if f
|
|||
print("if f: branch taken (unexpected)")
|
||||
else
|
||||
print("if f: else branch taken")
|
||||
|
||||
/* Expected output:
|
||||
typeof(t) => Boolean
|
||||
typeof(f) => Boolean
|
||||
t literal => true
|
||||
f literal => false
|
||||
true && true => true
|
||||
true && false => false
|
||||
false || true => 1
|
||||
false || false => 0
|
||||
!true => false
|
||||
!false => true
|
||||
true == true => true
|
||||
true != false => true
|
||||
true == 1 => true
|
||||
false == 0 => true
|
||||
1 == true => true
|
||||
0 != true => true
|
||||
if t: branch taken
|
||||
if f: else branch taken
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -52,3 +52,26 @@ print(typeof(cast(42, "Function"))) // -> "Nil"
|
|||
print(cast(cast("42", "Number"), "String")) // -> "42"
|
||||
|
||||
print("=== Done ===")
|
||||
|
||||
/* Expected output:
|
||||
=== CAST demo ===
|
||||
123
|
||||
0
|
||||
42
|
||||
100
|
||||
String
|
||||
0
|
||||
1
|
||||
Array
|
||||
1
|
||||
42
|
||||
String
|
||||
0
|
||||
Nil
|
||||
Function
|
||||
Nil
|
||||
42
|
||||
=== Done ===
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,3 +22,8 @@ if ok == 1
|
|||
print("Downloaded to " + path)
|
||||
else
|
||||
print("Download failed")
|
||||
|
||||
/* Expected output:
|
||||
Downloaded to ./downloaded.png
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -23,3 +23,9 @@ print("Raw length: " + to_string(len(resp)))
|
|||
obj = json_parse(resp)
|
||||
if obj != nil
|
||||
print("Title: " + obj["slideshow"]["title"])
|
||||
|
||||
/* Expected output:
|
||||
Raw length: 429
|
||||
Title: Sample Slide Show
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -30,3 +30,30 @@ if obj != nil
|
|||
|
||||
if obj != nil
|
||||
print("Origin: " + to_string(obj["origin"]))
|
||||
|
||||
/* Possible output:
|
||||
Response: {
|
||||
"args": {},
|
||||
"data": "",
|
||||
"files": {},
|
||||
"form": {
|
||||
"lang": "fun",
|
||||
"name": "Fun"
|
||||
},
|
||||
"headers": {
|
||||
"Accept": "*/*",
|
||||
"Content-Length": "17",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Host": "httpbin.org",
|
||||
"X-Amzn-Trace-Id": "Root=1-6944834b-74f499e251c322713e7dd9a8"
|
||||
},
|
||||
"json": null,
|
||||
"origin": "5.252.226.107",
|
||||
"url": "https://httpbin.org/post"
|
||||
}
|
||||
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Host: httpbin.org
|
||||
Origin: 5.252.226.107
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -19,5 +19,7 @@ echo("Hello, ")
|
|||
echo("world")
|
||||
print("!")
|
||||
|
||||
// Expected output:
|
||||
// Hello, world!
|
||||
/* Expected output:
|
||||
Hello, world!
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -59,3 +59,20 @@ print(a < b && n >= 10) // expect 1
|
|||
print((a + b) == 5 && flag) // expect 1
|
||||
|
||||
print("=== Expressions test end ===")
|
||||
|
||||
/* Expected output:
|
||||
=== Expressions test start ===
|
||||
16
|
||||
10
|
||||
-10
|
||||
1
|
||||
true
|
||||
false
|
||||
true
|
||||
1
|
||||
true
|
||||
true
|
||||
true
|
||||
=== Expressions test end ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ for x in range(1, 3)
|
|||
|
||||
print("=== for/range test end ===")
|
||||
|
||||
/*
|
||||
/* Expected output:
|
||||
=== for/range test start ===
|
||||
0
|
||||
1
|
||||
|
|
@ -112,3 +112,4 @@ print("=== for/range test end ===")
|
|||
4
|
||||
=== for/range test end ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -57,3 +57,17 @@ number n = 5
|
|||
print(add(n, 10)) // expect 15
|
||||
|
||||
print("=== Functions test end ===")
|
||||
|
||||
/* Expected output:
|
||||
=== Functions test start ===
|
||||
5
|
||||
7
|
||||
7
|
||||
4
|
||||
6
|
||||
6
|
||||
42
|
||||
15
|
||||
=== Functions test end ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -14,3 +14,8 @@
|
|||
*/
|
||||
|
||||
print("Have fun!")
|
||||
|
||||
/* Expected output:
|
||||
Have fun!
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
// Have fun in Fun
|
||||
|
||||
string s = "Have fun!"
|
||||
|
||||
|
||||
fun have_fun()
|
||||
print("Have fun!")
|
||||
print(s)
|
||||
|
|
@ -20,3 +20,13 @@ fun have_fun()
|
|||
print(n)
|
||||
|
||||
have_fun()
|
||||
|
||||
print("Have fun!")
|
||||
|
||||
/* Expected output:
|
||||
Have fun!
|
||||
Have fun!
|
||||
10
|
||||
Have fun!
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -41,3 +41,12 @@ if (n >= 10)
|
|||
print("answer") // expect: answer
|
||||
|
||||
print("=== if/else-if/else done ===")
|
||||
|
||||
/* Expected output:
|
||||
=== if/else-if/else test ===
|
||||
big
|
||||
42
|
||||
answer
|
||||
=== if/else-if/else done ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
// Demonstrates system library includes after installation to /usr/lib/fun
|
||||
|
||||
// includes can also be done with a leading # like in C, but some programmers maybe like more clean code without a
|
||||
// includes can also be done with a leading # like in C, but some programmers maybe like more clean code without a
|
||||
// leading #.
|
||||
include <hello.fun>
|
||||
include <utils/math.fun>
|
||||
|
|
@ -24,3 +24,10 @@ number y = 32
|
|||
|
||||
print("add(" + to_string(x) + ", " + to_string(y) + ") = " + to_string(add(x, y)))
|
||||
print("times(" + to_string(x) + ", " + to_string(y) + ") = " + to_string(times(x, y)))
|
||||
|
||||
/* Expected output:
|
||||
== include lib demo ==
|
||||
Hello from system lib!
|
||||
add(10, 32) = 42
|
||||
times(10, 32) = 320
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,3 +27,9 @@ print("sum(" + to_string(a) + ", " + to_string(b) + ") = " + to_string(sum(a, b)
|
|||
// To include from the system library directory (/usr/lib/fun), use angle brackets:
|
||||
// #include <some_lib.fun>
|
||||
|
||||
/* Expected output:
|
||||
== include local demo ==
|
||||
Hello, Fun
|
||||
sum(2, 3) = 5
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -14,3 +14,8 @@ fun greet(name)
|
|||
|
||||
fun sum(a, b)
|
||||
return a + b
|
||||
|
||||
/* Expected output:
|
||||
None, it's a lib...
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -44,3 +44,15 @@ ok = ini.save(nil)
|
|||
print("saved=" + to_string(ok))
|
||||
|
||||
ini.close()
|
||||
|
||||
/* Expected output:
|
||||
[app]
|
||||
name=FunApp
|
||||
version=1.2.3
|
||||
debug=1
|
||||
[database]
|
||||
host=localhost
|
||||
port=5432
|
||||
saved=1
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -73,3 +73,28 @@ else
|
|||
|
||||
// Clean up
|
||||
ini_free(h)
|
||||
|
||||
/* Expected output:
|
||||
[app]
|
||||
name=FunApp
|
||||
version=1.2.3
|
||||
debug=1
|
||||
[database]
|
||||
host=localhost
|
||||
port=5432
|
||||
user=fun
|
||||
pass=secret
|
||||
pool_size=8
|
||||
timeout=2.5
|
||||
[network]
|
||||
ssl=1
|
||||
retries=3
|
||||
base_url=https://api.example.com
|
||||
[features]
|
||||
feature_x=0
|
||||
feature_y=0
|
||||
[paths]
|
||||
data_dir=./data
|
||||
log_file=./logs/app.log
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -28,3 +28,9 @@ else
|
|||
if ok
|
||||
ini_save(h, path)
|
||||
ini_free(h)
|
||||
|
||||
/* Expected output:
|
||||
user=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>U
|
||||
retries=3
|
||||
ssl=1
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -68,3 +68,26 @@ else
|
|||
print(" max_files=" + to_string(logs_max_files))
|
||||
|
||||
ini_free(h)
|
||||
|
||||
/* Expected output:
|
||||
[server]
|
||||
host=example.org
|
||||
port=8080
|
||||
[server.tls]
|
||||
enabled=1
|
||||
version=1.3
|
||||
ciphers=TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256
|
||||
[users.admin]
|
||||
name=alice
|
||||
active=1
|
||||
quota_gb=100
|
||||
[users.guest]
|
||||
name=bob
|
||||
active=0
|
||||
quota_gb=5
|
||||
[paths.logs]
|
||||
dir=./var/log/fun
|
||||
rotate=1
|
||||
max_files=7
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ print(len(cfg["users"])) // number of users
|
|||
|
||||
// Derive a small summary map
|
||||
summary = {}
|
||||
summary["user_count"] = len(cfg["users"])
|
||||
summary["user_count"] = len(cfg["users"])
|
||||
summary["first_user_name"] = cfg["users"][1]["name"]
|
||||
summary["features_enabled"] = cfg["features"]["enabled"]
|
||||
|
||||
|
|
@ -63,3 +63,45 @@ print(json.stringify(summary, 1))
|
|||
out_path = "/tmp/fun_complex_out.json"
|
||||
ok = json.to_file(out_path, cfg, 1)
|
||||
print(ok) // 1 on success
|
||||
|
||||
/* Expected output:
|
||||
-- JSON: parse from string and pretty print --
|
||||
Dump:
|
||||
{"name": Ada, "active": true, "score": 99.5, "count": 42, "tags": [C, Ada, Math], "extra": nil}
|
||||
Ada
|
||||
true
|
||||
42
|
||||
3
|
||||
{
|
||||
"name":"Ada",
|
||||
"active":true,
|
||||
"score":99.5,
|
||||
"count":42,
|
||||
"tags":[
|
||||
"C",
|
||||
"Ada",
|
||||
"Math"
|
||||
],
|
||||
"extra":null
|
||||
}
|
||||
-- JSON: load from file, inspect, and save pretty to /tmp --
|
||||
Dump:
|
||||
nil
|
||||
Dump:
|
||||
{"project": {"name": Fun, "version": 0.27.2, "website": https://fun-lang.xyz, "license": {"name": Apache-2.0, "url": https://opensource.org/license/apache-2-0}}, "features": {"enabled": [arrays, maps, json, pcsc], "experimental": {"repl": true, "sockets": true, "odbc": false, "notes": nil}}, "users": [{"id": 1, "name": Ada, "roles": [admin, math], "active": true, "score": 99.5, "prefs": {"theme": dark, "editor": {"tabWidth": 2, "font": Fira Code}}}, {"id": 2, "name": Linus, "roles": [user, kernel], "active": false, "score": 88, "prefs": {"theme": light, "editor": {"tabWidth": 8, "font": Monospace}}}], "metrics": {"counters": [0, 1, 1, 2, 3, 5, 8], "latency_ms": {"p50": 1.23, "p90": 3.21, "p99": 12.34}, "builds": 1234567890123456789, "last_release_ts": 1732406400000}, "matrix": [[1, 2, 3], [4, 5, 6], [7, 8, 9]], "notes": UTF-8 ✓ – emojis: 🚀🔥, "null_field": nil}
|
||||
Fun
|
||||
0.27.2
|
||||
2
|
||||
{
|
||||
"user_count":2,
|
||||
"first_user_name":"Linus",
|
||||
"features_enabled":[
|
||||
"arrays",
|
||||
"maps",
|
||||
"json",
|
||||
"pcsc"
|
||||
]
|
||||
}
|
||||
1
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env fun
|
||||
// The shebang line makes no sense here because this is a library which will
|
||||
// never be executed, but it shows that it is not wrong.
|
||||
// The shebang line makes no sense here because this is a library which will
|
||||
// never be executed, but it shows that it is not wrong.
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
|
|
@ -23,3 +23,8 @@ class Greeter(string prefix)
|
|||
// Methods must declare 'this' as the first parameter
|
||||
fun say(this, name)
|
||||
print(this.prefix + " " + to_string(name))
|
||||
|
||||
/* Expected output:
|
||||
None, it's a lib.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -25,3 +25,11 @@ fun greet()
|
|||
else
|
||||
print("Hello, " + user + "!")
|
||||
greet()
|
||||
|
||||
/* Possible output:
|
||||
HOME=/home/hanez
|
||||
SHELL=/bin/zsh
|
||||
FUN_NOT_SET=
|
||||
Hello, hanez!
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -28,22 +28,22 @@ print(pcre2_test(pattern, text, flags))
|
|||
m = pcre2_match(pattern, text, flags)
|
||||
if (m != nil)
|
||||
print("first full:")
|
||||
print(m["full"])
|
||||
print(m["full"])
|
||||
print("span:")
|
||||
print(m["start"])
|
||||
print(m["start"])
|
||||
print("..")
|
||||
print(m["end"])
|
||||
print(m["end"])
|
||||
print("groups count:")
|
||||
print(len(m["groups"]))
|
||||
|
||||
all = pcre2_findall("\\w+", text, flags)
|
||||
for x in all
|
||||
print("all:")
|
||||
print(x["full"])
|
||||
print(x["full"])
|
||||
print("@")
|
||||
print(x["start"])
|
||||
print(x["start"])
|
||||
print("..")
|
||||
print(x["end"])
|
||||
print(x["end"])
|
||||
|
||||
print("")
|
||||
print("-- More regex demos --")
|
||||
|
|
@ -59,28 +59,28 @@ email_flags = OR(flags, 1) // UTF | I
|
|||
print("Emails (findall):")
|
||||
emails = pcre2_findall(email_pat, email_text, email_flags)
|
||||
for e in emails
|
||||
print(e["full"])
|
||||
print(e["full"])
|
||||
|
||||
// Demo 2: URLs (very simple, for demo purposes)
|
||||
url_text = "See http://example.com and https://fun-lang.xyz/docs?x=1#top"
|
||||
url_pat = "https?://[A-Za-z0-9._~:/?#[@]!$&'()*+,;=%-]+"
|
||||
print("URLs:")
|
||||
for u in pcre2_findall(url_pat, url_text, flags)
|
||||
print(u["full"])
|
||||
print(u["full"])
|
||||
|
||||
// Demo 3: IPv4 addresses
|
||||
ip_text = "ping 8.8.8.8 and 192.168.0.1; not 999.999.999.999"
|
||||
ip_pat = "(?:(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)"
|
||||
print("IPv4:")
|
||||
for ip in pcre2_findall(ip_pat, ip_text, flags)
|
||||
print(ip["full"])
|
||||
print(ip["full"])
|
||||
|
||||
// Demo 4: Dates (YYYY-MM-DD)
|
||||
date_text = "Born 1999-12-31, updated 2025-11-25, bad 2025-13-40"
|
||||
date_pat = "(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])"
|
||||
print("Dates (with groups Y/M/D):")
|
||||
for d in pcre2_findall(date_pat, date_text, flags)
|
||||
print(d["full"])
|
||||
print(d["full"])
|
||||
print(join(d["groups"], "/"))
|
||||
|
||||
// Demo 5: Hex colors (#RRGGBB)
|
||||
|
|
@ -88,14 +88,14 @@ color_text = "Palette: #FF00FF, #1a2b3c, not #abcd or #12345g"
|
|||
color_pat = "#[0-9A-Fa-f]{6}"
|
||||
print("Hex colors:")
|
||||
for c in pcre2_findall(color_pat, color_text, flags)
|
||||
print(c["full"])
|
||||
print(c["full"])
|
||||
|
||||
// Demo 6: Quoted strings with escapes
|
||||
q_text = 'say "hi there" and "indented" plus "quote\\"inside"'
|
||||
q_pat = '"([^"\\\\]|\\\\.)*"'
|
||||
print("Quoted strings (with escapes):")
|
||||
for q in pcre2_findall(q_pat, q_text, flags)
|
||||
print(q["full"])
|
||||
print(q["full"])
|
||||
|
||||
// Demo 7: Multiline anchors with /m (M flag)
|
||||
ml_text = "first line\nSecond line\nthird"
|
||||
|
|
@ -103,7 +103,7 @@ ml_pat = "^(\\w+)"
|
|||
ml_flags = OR(flags, 2) // UTF | M
|
||||
print("Multiline ^ anchors (first token of each line):")
|
||||
for ml in pcre2_findall(ml_pat, ml_text, ml_flags)
|
||||
print(ml["full"])
|
||||
print(ml["full"])
|
||||
|
||||
// Demo 8: Dotall vs non-dotall
|
||||
ds_text = "BEGIN\nline1\nline2\nEND"
|
||||
|
|
@ -119,14 +119,14 @@ wb_text = "The theater and the THE can differ."
|
|||
wb_pat = "\\bthe\\b"
|
||||
print("Word boundary, case-insensitive:")
|
||||
for w in pcre2_findall(wb_pat, wb_text, OR(flags, 1))
|
||||
print(w["full"])
|
||||
print(w["full"])
|
||||
|
||||
// Demo 10: Lookahead — word followed by number
|
||||
la_text = "foo 123, bar, baz 9"
|
||||
la_pat = "\\w+(?=\\s+\\d+)"
|
||||
print("Lookahead (word before number):")
|
||||
for a in pcre2_findall(la_pat, la_text, flags)
|
||||
print(a["full"])
|
||||
print(a["full"])
|
||||
|
||||
// Demo 11: Non-greedy vs greedy
|
||||
ng_text = "<a>one</a><a>two</a>"
|
||||
|
|
@ -134,7 +134,81 @@ greedy = "<a>.*</a>"
|
|||
lazy = "<a>.*?</a>"
|
||||
print("Greedy:")
|
||||
for g in pcre2_findall(greedy, ng_text, OR(flags, 4)) // DOTALL ensures '.' covers any
|
||||
print(g["full"])
|
||||
print(g["full"])
|
||||
print("Non-greedy:")
|
||||
for l in pcre2_findall(lazy, ng_text, OR(flags, 4))
|
||||
print(l["full"])
|
||||
print(l["full"])
|
||||
|
||||
/* Expected output:
|
||||
-- PCRE2 builtins (no class) --
|
||||
test:
|
||||
1
|
||||
first full:
|
||||
Hello
|
||||
span:
|
||||
0
|
||||
..
|
||||
5
|
||||
groups count:
|
||||
1
|
||||
all:
|
||||
Hello
|
||||
@
|
||||
0
|
||||
..
|
||||
5
|
||||
all:
|
||||
123
|
||||
@
|
||||
6
|
||||
..
|
||||
9
|
||||
all:
|
||||
world
|
||||
@
|
||||
10
|
||||
..
|
||||
15
|
||||
|
||||
-- More regex demos --
|
||||
Emails (findall):
|
||||
one@example.com
|
||||
Two@Example.COM
|
||||
URLs:
|
||||
IPv4:
|
||||
8.8.8.8
|
||||
192.168.0.1
|
||||
Dates (with groups Y/M/D):
|
||||
1999-12-31
|
||||
1999/12/31
|
||||
2025-11-25
|
||||
2025/11/25
|
||||
Hex colors:
|
||||
#FF00FF
|
||||
#1a2b3c
|
||||
Quoted strings (with escapes):
|
||||
"hi there"
|
||||
"indented"
|
||||
"quote\"inside"
|
||||
Multiline ^ anchors (first token of each line):
|
||||
first
|
||||
Second
|
||||
third
|
||||
Dotall OFF (should fail):
|
||||
0
|
||||
Dotall ON (should match):
|
||||
1
|
||||
Word boundary, case-insensitive:
|
||||
The
|
||||
the
|
||||
THE
|
||||
Lookahead (word before number):
|
||||
foo
|
||||
baz
|
||||
Greedy:
|
||||
<a>one</a><a>two</a>
|
||||
Non-greedy:
|
||||
<a>one</a>
|
||||
<a>two</a>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -46,3 +46,5 @@ SHA-1('abc') = e6cd2bcee460c45d41565ac877d866a159a16e19
|
|||
SHA-1(616263 hex) = e6cd2bcee460c45d41565ac877d866a159a16e19
|
||||
SHA-1('') = da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||
=== done ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -27,3 +27,9 @@ print(s.sha384_hex("616263"))
|
|||
|
||||
// Raw string input
|
||||
print(s.sha384_str("abc"))
|
||||
|
||||
/* Expected output:
|
||||
cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
|
||||
cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
|
||||
// Short-circuit demo for || and &&
|
||||
|
||||
print("=== short-circuit demo ===")
|
||||
|
|
@ -43,3 +43,15 @@ else
|
|||
print(0)
|
||||
|
||||
print("=== end ===")
|
||||
|
||||
/* Expected output:
|
||||
=== short-circuit demo ===
|
||||
1
|
||||
0
|
||||
OR-NEEDED
|
||||
1
|
||||
AND-NEEDED
|
||||
1
|
||||
=== end ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
|
||||
// Strings test: concatenation with variables and literals, functions returning strings
|
||||
|
||||
print("=== strings test start ===")
|
||||
|
|
@ -42,3 +42,16 @@ if (a != "")
|
|||
print("a is non-empty")
|
||||
|
||||
print("=== strings test end ===")
|
||||
|
||||
/* Expected output:
|
||||
=== strings test start ===
|
||||
Hello, World!
|
||||
Hi there
|
||||
x
|
||||
x
|
||||
Hello, Fun
|
||||
Hi, Hello, You
|
||||
a is non-empty
|
||||
=== strings test end ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -32,3 +32,21 @@ else
|
|||
data = sock_recv(fd, 8192)
|
||||
print(data)
|
||||
sock_close(fd)
|
||||
|
||||
/* Possible output:
|
||||
HTTP/1.1 200 OK
|
||||
Date: Thu, 18 Dec 2025 23:05:52 GMT
|
||||
Content-Type: text/html
|
||||
Connection: close
|
||||
Vary: accept-encoding
|
||||
Server: cloudflare
|
||||
Last-Modified: Wed, 17 Dec 2025 03:51:06 GMT
|
||||
Accept-Ranges: bytes
|
||||
Cache-Control: max-age=14400
|
||||
cf-cache-status: REVALIDATED
|
||||
CF-RAY: 9b024eb71d91e51d-TXL
|
||||
|
||||
<!doctype html><html lang="en"><head><title>Example Domain</title><meta name="viewport" content="width=device-width, initial-scale=1"><style>body{background:#eee;width:60vw;margin:15vh auto;font-family:system-ui,sans-serif}h1{font-size:1.5em}div{opacity:0.8}a:link,a:visited{color:#348}</style><body><div><h1>Example Domain</h1><p>This domain is for use in documentation examples without needing permission. Avoid use in operations.<p><a href="https://iana.org/domains/example">Learn more</a></div></body></html>
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -30,3 +30,22 @@ else
|
|||
resp = c.recv_all(8192)
|
||||
print(resp)
|
||||
c.close()
|
||||
|
||||
/* Possible output:
|
||||
HTTP/1.1 200 OK
|
||||
Date: Thu, 18 Dec 2025 23:06:52 GMT
|
||||
Content-Type: text/html
|
||||
Connection: close
|
||||
Vary: accept-encoding
|
||||
Server: cloudflare
|
||||
Last-Modified: Wed, 17 Dec 2025 03:51:06 GMT
|
||||
Accept-Ranges: bytes
|
||||
Age: 59
|
||||
Cache-Control: max-age=14400
|
||||
cf-cache-status: HIT
|
||||
CF-RAY: 9b02502e3f993237-TXL
|
||||
|
||||
<!doctype html><html lang="en"><head><title>Example Domain</title><meta name="viewport" content="width=device-width, initial-scale=1"><style>body{background:#eee;width:60vw;margin:15vh auto;font-family:system-ui,sans-serif}h1{font-size:1.5em}div{opacity:0.8}a:link,a:visited{color:#348}</style><body><div><h1>Example Domain</h1><p>This domain is for use in documentation examples without needing permission. Avoid use in operations.<p><a href="https://iana.org/domains/example">Learn more</a></div></body></html>
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -27,3 +27,8 @@ tk.pack("ok")
|
|||
|
||||
// Enter GUI loop (no-op if built without FUN_WITH_TCLTK)
|
||||
tk.loop()
|
||||
|
||||
/* Expected output:
|
||||
A GUI... ;)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -24,3 +24,10 @@ catch err
|
|||
finally
|
||||
print("finally always runs (syntactically)")
|
||||
print("after try")
|
||||
|
||||
/* Expected output:
|
||||
before try
|
||||
inside try body
|
||||
after try
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -70,3 +70,32 @@ print(typeof(nn)) // -> "Nil"
|
|||
|
||||
print("")
|
||||
print("Done. Uncomment lines above to see type errors in action.")
|
||||
|
||||
/* Expected output:
|
||||
== Dynamic variable (untyped) ==
|
||||
Number
|
||||
100
|
||||
String
|
||||
hello
|
||||
|
||||
== Typed variables remain type-stable ==
|
||||
String
|
||||
hello
|
||||
Number
|
||||
0
|
||||
0
|
||||
Sint64
|
||||
456
|
||||
|
||||
== Integer width clamping ==
|
||||
-126
|
||||
56
|
||||
255
|
||||
44
|
||||
|
||||
== Nil-typed variables must stay Nil ==
|
||||
Nil
|
||||
|
||||
Done. Uncomment lines above to see type errors in action.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -19,3 +19,12 @@ print("Now trying to assign a number to a string variable...")
|
|||
s = 42 // Runtime TypeError: expected String (assignment rejected)
|
||||
|
||||
print("This line will not execute due to the type error")
|
||||
|
||||
/* Expected output:
|
||||
Reassigning typed variables to another type should fail
|
||||
String
|
||||
hello
|
||||
Now trying to assign a number to a string variable...
|
||||
TypeError: expected String
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -70,3 +70,24 @@ print("ui8 value = " + to_string(ui8) + ", typeof(ui8) = " + typeof(ui8)) // Uin
|
|||
|
||||
si8 = si8 - 5
|
||||
print("si8 value = " + to_string(si8) + ", typeof(si8) = " + typeof(si8)) // Sint8
|
||||
|
||||
/* Expected output:
|
||||
typeof(si8) = Sint8
|
||||
typeof(si16) = Sint16
|
||||
typeof(si32) = Sint32
|
||||
typeof(si64) = Sint64
|
||||
typeof(ui8) = Uint8
|
||||
typeof(ui16) = Uint16
|
||||
typeof(ui32) = Uint32
|
||||
typeof(ui64) = Uint64
|
||||
typeof(n) = Sint64
|
||||
typeof(s) = String
|
||||
typeof(arr) = Array
|
||||
typeof(m) = Map
|
||||
typeof(f) = Function
|
||||
typeof(x) = Nil
|
||||
typeof(ui8 + 1) = Number
|
||||
typeof(si16 - 2) = Number
|
||||
ui8 value = 9, typeof(ui8) = Uint8
|
||||
si8 value = -6, typeof(si8) = Sint8
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -73,3 +73,32 @@ print("pt['y'] = " + to_string(pt["y"]) + " :: " + typeof(pt["y"]))
|
|||
// Conversions
|
||||
print("to_string(123) => " + to_string(123))
|
||||
print("to_number(\"456\") => " + to_string(to_number("456")))
|
||||
|
||||
/* Expected output:
|
||||
a = 42 :: Sint64
|
||||
b = -7 :: Sint64
|
||||
zero = 0 :: Sint64
|
||||
sum (a + b) = 35
|
||||
diff (a - b) = 49
|
||||
prod (a * 3) = 126
|
||||
quot (a / 2) = 21
|
||||
rem (a % 5) = 2
|
||||
a > b = 1
|
||||
a >= b = 1
|
||||
a < b = 0
|
||||
a <= b = 0
|
||||
a == b = false
|
||||
a != b = true
|
||||
t = true :: Boolean
|
||||
f = false :: Boolean
|
||||
t && (a > 0) = true
|
||||
f || (a < 0) = 0
|
||||
sum 1..5 = 15
|
||||
nums length = 5
|
||||
nums[2] = 3
|
||||
pt['x'] = 10 :: Number
|
||||
pt['y'] = -3 :: Number
|
||||
to_string(123) => 123
|
||||
to_number("456") => 456
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -77,3 +77,45 @@ print(typeof(p)) // -> "Class"
|
|||
|
||||
print("")
|
||||
print("=== Done ===")
|
||||
|
||||
/* Expected output:
|
||||
=== Dynamic (untyped) ===
|
||||
Number
|
||||
String
|
||||
|
||||
=== Numbers and integer subtypes ===
|
||||
Sint64
|
||||
42
|
||||
-126
|
||||
4464
|
||||
255
|
||||
0
|
||||
|
||||
=== Strings ===
|
||||
String
|
||||
hello
|
||||
|
||||
=== Nil ===
|
||||
Nil
|
||||
nil
|
||||
|
||||
=== Arrays ===
|
||||
Array
|
||||
3
|
||||
2
|
||||
[1, 2]
|
||||
|
||||
=== Maps ===
|
||||
Map
|
||||
v
|
||||
|
||||
=== Functions ===
|
||||
Function
|
||||
12
|
||||
|
||||
=== Classes and Class-typed variables ===
|
||||
Class
|
||||
|
||||
=== Done ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
|
||||
// While loops feature test: simple loops, nested with if/else, and functions
|
||||
|
||||
print("=== while test start ===")
|
||||
|
|
@ -42,3 +42,21 @@ fun countdown(n)
|
|||
print(countdown(3)) // expect: 3,2,1 then 0
|
||||
|
||||
print("=== while test end ===")
|
||||
|
||||
/* Expected output:
|
||||
=== while test start ===
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
3
|
||||
99
|
||||
1
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
=== while test end ===
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue