Refactoring. (0.37.51)
This commit is contained in:
parent
db68b30d5b
commit
c6aef6f290
19 changed files with 31 additions and 16 deletions
29
examples/extra/curl_download.fun
Executable file
29
examples/extra/curl_download.fun
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Demonstrates curl_download saving a file to disk.
|
||||
*/
|
||||
|
||||
url = "https://httpbin.org/image/png"
|
||||
path = "./downloaded.png"
|
||||
ok = curl_download(url, path)
|
||||
if ok == 1
|
||||
print("Downloaded to " + path)
|
||||
else
|
||||
print("Download failed")
|
||||
|
||||
/* Expected output:
|
||||
Downloaded to ./downloaded.png
|
||||
*/
|
||||
|
||||
58
examples/extra/ini_class_demo.fun
Executable file
58
examples/extra/ini_class_demo.fun
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-30
|
||||
*/
|
||||
|
||||
// Demonstration of the Ini stdlib class from lib/io/ini.fun
|
||||
include <io/ini.fun>
|
||||
|
||||
ini = INI()
|
||||
path = "./examples/data/complex.ini"
|
||||
|
||||
if (ini.load(path) == 0)
|
||||
print("Failed to load " + path)
|
||||
exit(1)
|
||||
|
||||
// Read a few values
|
||||
app_name = ini.get_string("app", "name", "FunApp")
|
||||
app_version = ini.get_string("app", "version", "0.0.0")
|
||||
app_debug = ini.get_bool("app", "debug", 0)
|
||||
|
||||
db_host = ini.get_string("database", "host", "localhost")
|
||||
db_port = ini.get_int("database", "port", 5432)
|
||||
|
||||
print("[app]")
|
||||
print(" name=" + app_name)
|
||||
print(" version=" + app_version)
|
||||
print(" debug=" + to_string(app_debug))
|
||||
|
||||
print("[database]")
|
||||
print(" host=" + db_host)
|
||||
print(" port=" + to_string(db_port))
|
||||
|
||||
// Update a value and save back to the same file
|
||||
ini.set("app", "debug", 1)
|
||||
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
|
||||
*/
|
||||
|
||||
99
examples/extra/ini_complex.fun
Executable file
99
examples/extra/ini_complex.fun
Executable file
|
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-30
|
||||
*/
|
||||
|
||||
// Complex INI parsing example using iniparser 4.2.6 opcodes.
|
||||
|
||||
path = "./examples/data/complex.ini"
|
||||
h = ini_load(path)
|
||||
if h == 0
|
||||
print("Failed to load "+path)
|
||||
else
|
||||
// app
|
||||
app_name = ini_get_string(h, "app", "name", "FunApp")
|
||||
app_version = ini_get_string(h, "app", "version", "0.0.0")
|
||||
app_debug = ini_get_bool(h, "app", "debug", 0)
|
||||
|
||||
// database
|
||||
db_host = ini_get_string(h, "database", "host", "localhost")
|
||||
db_port = ini_get_int(h, "database", "port", 5432)
|
||||
db_user = ini_get_string(h, "database", "user", "user")
|
||||
db_pass = ini_get_string(h, "database", "pass", "")
|
||||
db_pool = ini_get_int(h, "database", "pool_size", 4)
|
||||
db_timeout = ini_get_double(h, "database", "timeout", 2.0)
|
||||
|
||||
// network
|
||||
net_ssl = ini_get_bool(h, "network", "ssl", 0)
|
||||
net_retries = ini_get_int(h, "network", "retries", 3)
|
||||
base_url = ini_get_string(h, "network", "base_url", "")
|
||||
|
||||
// features
|
||||
feature_x = ini_get_bool(h, "features", "feature_x", 0)
|
||||
feature_y = ini_get_bool(h, "features", "feature_y", 0)
|
||||
|
||||
// paths
|
||||
data_dir = ini_get_string(h, "paths", "data_dir", "./data")
|
||||
log_file = ini_get_string(h, "paths", "log_file", "./logs/app.log")
|
||||
|
||||
// Print a structured summary
|
||||
print("[app]")
|
||||
print(" name=" + app_name)
|
||||
print(" version=" + app_version)
|
||||
print(" debug=" + to_string(app_debug))
|
||||
|
||||
print("[database]")
|
||||
print(" host=" + db_host)
|
||||
print(" port=" + to_string(db_port))
|
||||
print(" user=" + db_user)
|
||||
print(" pass=" + db_pass)
|
||||
print(" pool_size=" + to_string(db_pool))
|
||||
print(" timeout=" + to_string(db_timeout))
|
||||
|
||||
print("[network]")
|
||||
print(" ssl=" + to_string(net_ssl))
|
||||
print(" retries=" + to_string(net_retries))
|
||||
print(" base_url=" + base_url)
|
||||
|
||||
print("[features]")
|
||||
print(" feature_x=" + to_string(feature_x))
|
||||
print(" feature_y=" + to_string(feature_y))
|
||||
|
||||
print("[paths]")
|
||||
print(" data_dir=" + data_dir)
|
||||
print(" log_file=" + log_file)
|
||||
|
||||
// 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=1
|
||||
feature_y=0
|
||||
[paths]
|
||||
data_dir=./data
|
||||
log_file=./logs/app.log
|
||||
*/
|
||||
43
examples/extra/ini_demo.fun
Executable file
43
examples/extra/ini_demo.fun
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-30
|
||||
*/
|
||||
|
||||
// Minimal demo for INI opcodes using iniparser 4.2.6
|
||||
|
||||
path = "./examples/data/complex.ini"
|
||||
h = ini_load(path)
|
||||
if h == 0
|
||||
print("Failed to load " + path)
|
||||
else
|
||||
u = ini_get_string(h, "auth", "user", "guest")
|
||||
r = ini_get_int(h, "network", "retries", 5)
|
||||
s = ini_get_bool(h, "network", "ssl", 0)
|
||||
print("user=" + u)
|
||||
print("retries=" + to_string(r))
|
||||
print("ssl=" + to_string(s))
|
||||
ok = ini_set(h, "auth", "token", "abcd1234")
|
||||
if ok
|
||||
ini_save(h, path)
|
||||
ini_free(h)
|
||||
|
||||
/* Expected output:
|
||||
user=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>U
|
||||
retries=3
|
||||
ssl=1
|
||||
|
||||
I wonder about the user= value when the default value is used!
|
||||
|
||||
It should look like:
|
||||
user=guest
|
||||
retries=3
|
||||
ssl=1
|
||||
*/
|
||||
50
examples/extra/ini_diag.fun
Executable file
50
examples/extra/ini_diag.fun
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-01-02
|
||||
*/
|
||||
|
||||
// Minimal diagnostic for INI lookups
|
||||
|
||||
path = "./examples/data/complex.ini"
|
||||
h = ini_load(path)
|
||||
print("h=" + to_string(h))
|
||||
if h == 0
|
||||
print("Failed to load: " + path)
|
||||
else
|
||||
print("[try app:name]")
|
||||
v1 = ini_get_string(h, "app", "name", "<def>")
|
||||
print("app:name => " + v1)
|
||||
|
||||
print("[try app:version]")
|
||||
v2 = ini_get_string(h, "app", "version", "<def>")
|
||||
print("app:version => " + v2)
|
||||
|
||||
print("[try database:port]")
|
||||
v3 = ini_get_int(h, "database", "port", -1)
|
||||
print("database:port => " + to_string(v3))
|
||||
|
||||
print("[try network:ssl]")
|
||||
v4 = ini_get_bool(h, "network", "ssl", -9)
|
||||
print("network:ssl => " + to_string(v4))
|
||||
|
||||
ini_free(h)
|
||||
|
||||
/* Expected output:
|
||||
h=1
|
||||
[try app:name]
|
||||
app:name => FunApp
|
||||
[try app:version]
|
||||
app:version => 1.2.3
|
||||
[try database:port]
|
||||
database:port => 5432
|
||||
[try network:ssl]
|
||||
network:ssl => 1
|
||||
*/
|
||||
93
examples/extra/ini_subsections.fun
Executable file
93
examples/extra/ini_subsections.fun
Executable file
|
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-30
|
||||
*/
|
||||
|
||||
// Demonstration of INI subsections like [section.subsection]
|
||||
// Uses iniparser 4.2.6 via Fun's ini_* opcodes
|
||||
|
||||
path = "./examples/data/subsections.ini"
|
||||
h = ini_load(path)
|
||||
if h == 0
|
||||
print("Failed to load "+path)
|
||||
else
|
||||
// Top-level server
|
||||
srv_host = ini_get_string(h, "server", "host", "localhost")
|
||||
srv_port = ini_get_int(h, "server", "port", 80)
|
||||
|
||||
// Subsection: server.tls
|
||||
tls_enabled = ini_get_bool(h, "server.tls", "enabled", 0)
|
||||
tls_version = ini_get_double(h, "server.tls", "version", 1.2)
|
||||
tls_ciphers = ini_get_string(h, "server.tls", "ciphers", "")
|
||||
|
||||
// Subsections: users.*
|
||||
admin_name = ini_get_string(h, "users.admin", "name", "admin")
|
||||
admin_active = ini_get_bool(h, "users.admin", "active", 1)
|
||||
admin_quota = ini_get_int(h, "users.admin", "quota_gb", 10)
|
||||
|
||||
guest_name = ini_get_string(h, "users.guest", "name", "guest")
|
||||
guest_active = ini_get_bool(h, "users.guest", "active", 0)
|
||||
guest_quota = ini_get_int(h, "users.guest", "quota_gb", 1)
|
||||
|
||||
// Subsection: paths.logs
|
||||
logs_dir = ini_get_string(h, "paths.logs", "dir", "./logs")
|
||||
logs_rotate = ini_get_bool(h, "paths.logs", "rotate", 0)
|
||||
logs_max_files = ini_get_int(h, "paths.logs", "max_files", 5)
|
||||
|
||||
// Print
|
||||
print("[server]")
|
||||
print(" host=" + srv_host)
|
||||
print(" port=" + to_string(srv_port))
|
||||
|
||||
print("[server.tls]")
|
||||
print(" enabled=" + to_string(tls_enabled))
|
||||
print(" version=" + to_string(tls_version))
|
||||
print(" ciphers=" + tls_ciphers)
|
||||
|
||||
print("[users.admin]")
|
||||
print(" name=" + admin_name)
|
||||
print(" active=" + to_string(admin_active))
|
||||
print(" quota_gb=" + to_string(admin_quota))
|
||||
|
||||
print("[users.guest]")
|
||||
print(" name=" + guest_name)
|
||||
print(" active=" + to_string(guest_active))
|
||||
print(" quota_gb=" + to_string(guest_quota))
|
||||
|
||||
print("[paths.logs]")
|
||||
print(" dir=" + logs_dir)
|
||||
print(" rotate=" + to_string(logs_rotate))
|
||||
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
|
||||
*/
|
||||
|
||||
59
examples/extra/libsql_example.fun
Executable file
59
examples/extra/libsql_example.fun
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-26
|
||||
*/
|
||||
|
||||
// Demonstrates the optional libSQL extension
|
||||
// Build with: cmake -S . -B build -DFUN_WITH_LIBSQL=ON && cmake --build build
|
||||
|
||||
// Prepare sample DB from SQL if needed (requires sqlite3 CLI installed)
|
||||
// Create it once with:
|
||||
// sqlite3 ./database.sqlite < ./examples/data/database.sql
|
||||
|
||||
number h = libsql_open("./database.sqlite")
|
||||
if h == 0
|
||||
print("Failed to open libSQL database")
|
||||
else
|
||||
libsql_exec(h, "CREATE TABLE IF NOT EXISTS todos(id INTEGER PRIMARY KEY, title TEXT, done INT)")
|
||||
libsql_exec(h, "DELETE FROM todos")
|
||||
libsql_exec(h, "INSERT INTO todos(title, done) VALUES('Buy milk', 0)")
|
||||
libsql_exec(h, "INSERT INTO todos(title, done) VALUES('Write code', 1)")
|
||||
|
||||
rows = libsql_query(h, "SELECT id, title, done FROM todos ORDER BY id")
|
||||
for row in rows
|
||||
print(to_string(row["id"]) + ": " + to_string(row["title"]) + " (done="+to_string(row["done"]) + ")")
|
||||
|
||||
rows = libsql_query(h, "SELECT id, title, done, created_at FROM tasks ORDER BY id;")
|
||||
print("Tasks (" + to_string(len(rows)) + "):")
|
||||
for row in rows
|
||||
string status = "✘"
|
||||
if row["done"] == 1
|
||||
status = "✔"
|
||||
print("- [" + status + "] (#" + to_string(row["id"]) + ") " + to_string(row["title"]) + " — " + to_string(row["created_at"]))
|
||||
|
||||
number rc = libsql_exec(h, "INSERT INTO tasks (title, done) VALUES ('Try Fun + SQLite', 0);")
|
||||
print("Insert rc=" + to_string(rc))
|
||||
|
||||
rows2 = libsql_query(h, "SELECT count(*) AS cnt FROM tasks;")
|
||||
print("Total tasks now: " + to_string(rows2[0]["cnt"]))
|
||||
|
||||
libsql_close(h)
|
||||
|
||||
/* Example output:
|
||||
1: Buy milk (done=0)
|
||||
2: Write code (done=1)
|
||||
Tasks (3):
|
||||
- [✔] (#1) Write Fun + SQLite example — 2025-11-26 23:20:41
|
||||
- [✘] (#2) Ship optional feature flag — 2025-11-26 23:20:41
|
||||
- [✘] (#3) Celebrate with coffee — 2025-11-26 23:20:41
|
||||
Insert rc=0
|
||||
Total tasks now: 4
|
||||
*/
|
||||
48
examples/extra/sqlite_example.fun
Executable file
48
examples/extra/sqlite_example.fun
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-11-26
|
||||
*/
|
||||
|
||||
// Prepare sample DB from SQL if needed (requires sqlite3 CLI installed)
|
||||
// Create it once with:
|
||||
// sqlite3 ./database.sqlite < ./examples/data/database.sql
|
||||
|
||||
string db_path = "./database.sqlite"
|
||||
|
||||
number h = sqlite_open(db_path)
|
||||
if h == 0
|
||||
print("Failed to open DB: " + db_path)
|
||||
exit(1)
|
||||
|
||||
rows = sqlite_query(h, "SELECT id, title, done, created_at FROM tasks ORDER BY id;")
|
||||
print("Tasks (" + to_string(len(rows)) + "):")
|
||||
for row in rows
|
||||
string status = "✘"
|
||||
if row["done"] == 1
|
||||
status = "✔"
|
||||
print("- [" + status + "] (#" + to_string(row["id"]) + ") " + to_string(row["title"]) + " — " + to_string(row["created_at"]))
|
||||
|
||||
number rc = sqlite_exec(h, "INSERT INTO tasks (title, done) VALUES ('Try Fun + SQLite', 0);")
|
||||
print("Insert rc=" + to_string(rc))
|
||||
|
||||
rows2 = sqlite_query(h, "SELECT count(*) AS cnt FROM tasks;")
|
||||
print("Total tasks now: " + to_string(rows2[0]["cnt"]))
|
||||
|
||||
sqlite_close(h)
|
||||
|
||||
/* Example output:
|
||||
Tasks (3):
|
||||
- [✔] (#1) Write Fun + SQLite example — 2025-11-26 23:22:04
|
||||
- [✘] (#2) Ship optional feature flag — 2025-11-26 23:22:04
|
||||
- [✘] (#3) Celebrate with coffee — 2025-11-26 23:22:04
|
||||
Insert rc=0
|
||||
Total tasks now: 4
|
||||
*/
|
||||
59
examples/extra/tk_file_manager.fun
Executable file
59
examples/extra/tk_file_manager.fun
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-23
|
||||
*/
|
||||
|
||||
#include <ui/tk.fun>
|
||||
|
||||
print("Initializing Fun File Manager...")
|
||||
tk = TK()
|
||||
tk.title("Fun File Manager")
|
||||
|
||||
// Current directory
|
||||
dir = env("PWD")
|
||||
if (dir == "")
|
||||
dir = "."
|
||||
print("Current directory: " + dir)
|
||||
|
||||
tk.label("path", "Current Dir: " + dir)
|
||||
tk.pack("path")
|
||||
|
||||
// Files listbox
|
||||
tk.listbox("files")
|
||||
tk.pack("files")
|
||||
|
||||
// Populate listbox
|
||||
fun refresh(tk, dir)
|
||||
print("Refreshing file list for: " + dir)
|
||||
tk.clear("files")
|
||||
files = os_list_dir(dir)
|
||||
print("Found " + to_string(len(files)) + " entries.")
|
||||
for f in files
|
||||
tk.insert("files", "end", f)
|
||||
|
||||
refresh(tk, dir)
|
||||
|
||||
// Refresh button
|
||||
// Using tk.eval for button because tk.button currently exits the app.
|
||||
tk.eval("button .refresh -text {Refresh} -command {puts {Refresh requested}}")
|
||||
tk.pack("refresh")
|
||||
|
||||
// Exit button
|
||||
tk.button("exit", "Exit")
|
||||
tk.pack("exit")
|
||||
|
||||
print("Entering Tk loop...")
|
||||
tk.loop()
|
||||
print("Tk loop exited.")
|
||||
|
||||
/* Expected output:
|
||||
A GUI... ;)
|
||||
*/
|
||||
33
examples/extra/tk_hello.fun
Executable file
33
examples/extra/tk_hello.fun
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-09
|
||||
*/
|
||||
|
||||
// Demonstrates the Tk stdlib wrapper class using the new Tk opcodes.
|
||||
|
||||
include <ui/tk.fun>
|
||||
|
||||
tk = TK()
|
||||
|
||||
tk.title("Fun + Tk GUI")
|
||||
|
||||
tk.label("hello", "Hello, world!")
|
||||
tk.pack("hello")
|
||||
|
||||
tk.button("ok", "OK")
|
||||
tk.pack("ok")
|
||||
|
||||
// Enter GUI loop (no-op if built without FUN_WITH_TCLTK)
|
||||
tk.loop()
|
||||
|
||||
/* Expected output:
|
||||
A GUI... ;)
|
||||
*/
|
||||
38
examples/extra/tk_testing.fun
Executable file
38
examples/extra/tk_testing.fun
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-23
|
||||
*/
|
||||
|
||||
#include <ui/tk.fun>
|
||||
|
||||
print("Testing os_list_dir...")
|
||||
files = os_list_dir(".")
|
||||
print("Found " + to_string(len(files)) + " files.")
|
||||
if len(files) > 0
|
||||
print("First file: " + files[0])
|
||||
|
||||
print("Testing tk_bind parsing...")
|
||||
// We can't easily test Tk without an X server, but we can see if it crashes.
|
||||
// If built with FUN_WITH_TCLTK, it should at least initialize.
|
||||
// We use tk_eval to avoid full loop.
|
||||
rc = tk_eval("set x 1")
|
||||
print("tk_eval rc: " + to_string(rc))
|
||||
if rc == 0
|
||||
print("Tcl Result: " + tk_result())
|
||||
|
||||
/* Expected output:
|
||||
Testing os_list_dir...
|
||||
Found 23 files.
|
||||
First file: build
|
||||
Testing tk_bind parsing...
|
||||
tk_eval rc: 0
|
||||
Tcl Result: 1
|
||||
*/
|
||||
97
examples/extra/xml_access_catalog.fun
Executable file
97
examples/extra/xml_access_catalog.fun
Executable file
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Demonstrate reading specific fields from an XML file using
|
||||
* the minimal XML API (root name) and simple string parsing.
|
||||
*/
|
||||
|
||||
include <io/xml.fun>
|
||||
|
||||
path = "./examples/data/catalog.xml"
|
||||
xml = XML()
|
||||
doc = xml.from_file(path)
|
||||
if (doc == 0)
|
||||
print("Failed to load: ")
|
||||
print(path)
|
||||
else
|
||||
root = xml.root(doc)
|
||||
print("Root element: ")
|
||||
print(xml.name(root))
|
||||
|
||||
// Show how to access specific fields by quick-and-dirty parsing
|
||||
content = read_file(path) // raw XML text
|
||||
// First product name
|
||||
name = xml.between(content, "<name>", "</name>")
|
||||
// First price value and its currency attribute (extract value, then attribute)
|
||||
price_val = xml.between(content, "<price", "</price>")
|
||||
currency = ""
|
||||
if (len(price_val) > 0)
|
||||
currency = xml.between(price_val, "currency=\"", "\"")
|
||||
// strip attribute tag part
|
||||
price_text = xml.between(price_val, ">", "") // until end
|
||||
if (len(price_text) == 0)
|
||||
price_text = price_val
|
||||
else
|
||||
price_text = ""
|
||||
|
||||
print("First product name: ")
|
||||
print(name)
|
||||
print("First price: ")
|
||||
if (len(currency) > 0)
|
||||
print(currency)
|
||||
print(" ")
|
||||
print(price_text)
|
||||
|
||||
/* Expected output:
|
||||
Root element:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<catalog>
|
||||
<product id="SKU-1001">
|
||||
<name>Wireless Keyboard</name>
|
||||
<category>Peripherals</category>
|
||||
<price currency="USD">39.99</price>
|
||||
<specs>
|
||||
<layout>US</layout>
|
||||
<connection>Bluetooth</connection>
|
||||
<battery>AA</battery>
|
||||
</specs>
|
||||
</product>
|
||||
<product id="SKU-2002">
|
||||
<name>27" Monitor</name>
|
||||
<category>Displays</category>
|
||||
<price currency="USD">199.00</price>
|
||||
<specs>
|
||||
<resolution>2560x1440</resolution>
|
||||
<panel>IPS</panel>
|
||||
<refresh>75Hz</refresh>
|
||||
</specs>
|
||||
</product>
|
||||
<product id="SKU-3003">
|
||||
<name>USB-C Dock</name>
|
||||
<category>Peripherals</category>
|
||||
<price currency="USD">89.50</price>
|
||||
<specs>
|
||||
<ports>2xHDMI, 3xUSB-A, 1xUSB-C PD</ports>
|
||||
<pd>65W</pd>
|
||||
</specs>
|
||||
</product>
|
||||
</catalog>
|
||||
|
||||
First product name:
|
||||
Wireless Keyboard
|
||||
First price:
|
||||
USD
|
||||
|
||||
39.99
|
||||
*/
|
||||
81
examples/extra/xml_access_employees.fun
Executable file
81
examples/extra/xml_access_employees.fun
Executable file
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Access selected fields in employees.xml using minimal XML API.
|
||||
*/
|
||||
|
||||
include <io/xml.fun>
|
||||
|
||||
path = "./examples/data/employees.xml"
|
||||
xml = XML()
|
||||
doc = xml.from_file(path)
|
||||
if (doc == 0)
|
||||
print("Failed to load: ")
|
||||
print(path)
|
||||
else
|
||||
root = xml.root(doc)
|
||||
print("Root element: ")
|
||||
print(xml.name(root))
|
||||
|
||||
content = read_file(path)
|
||||
// Find the first <employee> block and extract its fields
|
||||
first_emp = xml.between(content, "<employee", "</employee>")
|
||||
name = xml.between(first_emp, "<name>", "</name>")
|
||||
role = xml.between(first_emp, "<role>", "</role>")
|
||||
email = xml.between(first_emp, "<email>", "</email>")
|
||||
emp_id = xml.between(first_emp, "id=\"", "\"")
|
||||
|
||||
print("First employee id: ")
|
||||
print(emp_id)
|
||||
print("Name: ")
|
||||
print(name)
|
||||
print("Role: ")
|
||||
print(role)
|
||||
print("Email: ")
|
||||
print(email)
|
||||
|
||||
/* Expected output:
|
||||
Root element:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<company>
|
||||
<department name="Engineering">
|
||||
<employee id="E-100">
|
||||
<name>Alice Doe</name>
|
||||
<role>Senior Developer</role>
|
||||
<email>alice@example.com</email>
|
||||
</employee>
|
||||
<employee id="E-101">
|
||||
<name>Bob Roe</name>
|
||||
<role>DevOps Engineer</role>
|
||||
<email>bob@example.com</email>
|
||||
</employee>
|
||||
</department>
|
||||
<department name="Sales">
|
||||
<employee id="S-200">
|
||||
<name>Carol Smith</name>
|
||||
<role>Account Executive</role>
|
||||
<email>carol@example.com</email>
|
||||
</employee>
|
||||
</department>
|
||||
</company>
|
||||
|
||||
First employee id:
|
||||
E-100
|
||||
Name:
|
||||
Alice Doe
|
||||
Role:
|
||||
Senior Developer
|
||||
Email:
|
||||
alice@example.com
|
||||
*/
|
||||
60
examples/extra/xml_access_ns.fun
Executable file
60
examples/extra/xml_access_ns.fun
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Access a namespaced XML file and show prefixed element names.
|
||||
*/
|
||||
|
||||
include <io/xml.fun>
|
||||
|
||||
path = "./examples/data/ns_example.xml"
|
||||
xml = XML()
|
||||
doc = xml.from_file(path)
|
||||
if (doc == 0)
|
||||
print("Failed to load: ")
|
||||
print(path)
|
||||
else
|
||||
root = xml.root(doc)
|
||||
// With namespaces, the node name may include the prefix, e.g., "ns:library"
|
||||
print("Root element: ")
|
||||
print(xml.name(root))
|
||||
|
||||
content = read_file(path)
|
||||
// Extract first book title and author (namespace prefix bk:)
|
||||
b1 = xml.between(content, "<bk:book", "</bk:book>")
|
||||
title = xml.between(b1, "<bk:title>", "</bk:title>")
|
||||
author = xml.between(b1, "<bk:author>", "</bk:author>")
|
||||
print("First book title: ")
|
||||
print(title)
|
||||
print("Author: ")
|
||||
print(author)
|
||||
|
||||
/* Expected output:
|
||||
Root element:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ns:library xmlns:ns="http://example.org/ns/library" xmlns:bk="http://example.org/ns/book">
|
||||
<bk:book id="B-1">
|
||||
<bk:title>The Art of Fun</bk:title>
|
||||
<bk:author>J. Findeisen</bk:author>
|
||||
</bk:book>
|
||||
<bk:book id="B-2">
|
||||
<bk:title>Minimal VM Design</bk:title>
|
||||
<bk:author>A. Dev</bk:author>
|
||||
</bk:book>
|
||||
</ns:library>
|
||||
|
||||
First book title:
|
||||
The Art of Fun
|
||||
Author:
|
||||
J. Findeisen
|
||||
*/
|
||||
110
examples/extra/xml_class_example.fun
Executable file
110
examples/extra/xml_class_example.fun
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-09
|
||||
*/
|
||||
|
||||
// Example using the stdlib XML class wrapper
|
||||
|
||||
include <io/xml.fun>
|
||||
|
||||
xml = XML()
|
||||
doc = xml.from_file("./examples/data/example.xml")
|
||||
print("doc handle:")
|
||||
print(doc)
|
||||
if (doc == 0)
|
||||
print("Failed to load XML file")
|
||||
else
|
||||
root = xml.root(doc)
|
||||
print("root name:")
|
||||
print(xml.name(root))
|
||||
print("root text:")
|
||||
print(xml.text(root))
|
||||
|
||||
/* Expected output:
|
||||
doc handle:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<company name="Acme Corp">
|
||||
<departments>
|
||||
<department id="eng" name="Engineering">
|
||||
<team name="Platform">
|
||||
<member id="u1">Alice</member>
|
||||
<member id="u2">Bob</member>
|
||||
</team>
|
||||
<team name="Product">
|
||||
<member id="u3">Carol</member>
|
||||
</team>
|
||||
</department>
|
||||
<department id="ops" name="Operations">
|
||||
<team name="SRE">
|
||||
<member id="u4">Dave</member>
|
||||
</team>
|
||||
</department>
|
||||
</departments>
|
||||
<offices>
|
||||
<office city="Berlin" country="DE"/>
|
||||
<office city="Paris" country="FR"/>
|
||||
</offices>
|
||||
<note>Welcome to Acme!</note>
|
||||
</company>
|
||||
|
||||
root name:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<company name="Acme Corp">
|
||||
<departments>
|
||||
<department id="eng" name="Engineering">
|
||||
<team name="Platform">
|
||||
<member id="u1">Alice</member>
|
||||
<member id="u2">Bob</member>
|
||||
</team>
|
||||
<team name="Product">
|
||||
<member id="u3">Carol</member>
|
||||
</team>
|
||||
</department>
|
||||
<department id="ops" name="Operations">
|
||||
<team name="SRE">
|
||||
<member id="u4">Dave</member>
|
||||
</team>
|
||||
</department>
|
||||
</departments>
|
||||
<offices>
|
||||
<office city="Berlin" country="DE"/>
|
||||
<office city="Paris" country="FR"/>
|
||||
</offices>
|
||||
<note>Welcome to Acme!</note>
|
||||
</company>
|
||||
|
||||
root text:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<company name="Acme Corp">
|
||||
<departments>
|
||||
<department id="eng" name="Engineering">
|
||||
<team name="Platform">
|
||||
<member id="u1">Alice</member>
|
||||
<member id="u2">Bob</member>
|
||||
</team>
|
||||
<team name="Product">
|
||||
<member id="u3">Carol</member>
|
||||
</team>
|
||||
</department>
|
||||
<department id="ops" name="Operations">
|
||||
<team name="SRE">
|
||||
<member id="u4">Dave</member>
|
||||
</team>
|
||||
</department>
|
||||
</departments>
|
||||
<offices>
|
||||
<office city="Berlin" country="DE"/>
|
||||
<office city="Paris" country="FR"/>
|
||||
</offices>
|
||||
<note>Welcome to Acme!</note>
|
||||
</company>
|
||||
|
||||
*/
|
||||
24
examples/extra/xml_minimal.fun
Executable file
24
examples/extra/xml_minimal.fun
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-12-09
|
||||
*/
|
||||
|
||||
// Minimal XML example using libxml2-backed builtins
|
||||
|
||||
doc = xml_parse("<root><item id=\"1\">a</item><item id=\"2\">b</item></root>")
|
||||
print("doc handle=\(doc)")
|
||||
root = xml_root(doc)
|
||||
print("root name=\(xml_name(root)) text=\(xml_text(root))")
|
||||
|
||||
/* Expected output:
|
||||
doc handle=(doc)
|
||||
root name=(xml_name(root)) text=(xml_text(root))
|
||||
*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue