Added lot more example code. (0.39.8).
This commit is contained in:
parent
3b70d6c92a
commit
564999709c
32 changed files with 1353 additions and 53 deletions
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
project(fun VERSION 0.39.7 LANGUAGES C)
|
||||
project(fun VERSION 0.39.8 LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
|
|
|||
24
examples/README.md
Normal file
24
examples/README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Fun Examples
|
||||
|
||||
This directory contains small, pure Fun examples organized by topic.
|
||||
|
||||
How to run:
|
||||
- Build the interpreter once: `cmake --build ./build_debug --target fun`
|
||||
- Execute an example: `./build_debug/fun ./examples/<path>.fun`
|
||||
- For CGI examples under `examples/data/htdocs`, start one of the blocking HTTP servers from `examples/blocking/` and visit the URL noted in the file headers.
|
||||
|
||||
Categories:
|
||||
- basics: hello_world, fizzbuzz, fibonacci, collections
|
||||
- strings: split_join_trim, templating_min, urlencode_decode
|
||||
- io: read_write_file, csv_reader (uses examples/io/sample.csv), word_count
|
||||
- algos: sort_and_search, deduplicate, stack_queue
|
||||
- cli: env_echo, args_parse (parse ARGS env)
|
||||
- net: tcp_echo_server, tcp_echo_client, http_static_server (blocking)
|
||||
- data/htdocs (CGI): hello.fun, info.fun, counter.fun, form_post.fun, redirect.fun, json_like_api.fun
|
||||
- compose: run_other_fun, pipeline
|
||||
- patterns: assert_like, logging_min
|
||||
- snippets: escape_html_demo, maps_iterate
|
||||
|
||||
Notes:
|
||||
- Scripts that start servers (tcp_echo_server, http_static_server, http_server_cgi*.fun) are blocking; run them in a separate terminal.
|
||||
- Some examples rely on stdlib includes; if needed, set `FUN_LIB_DIR=./lib` before running.
|
||||
26
examples/algos/deduplicate.fun
Executable file
26
examples/algos/deduplicate.fun
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// De-duplicate an array using a map as a set
|
||||
arr = [1,2,2,3,1,4]
|
||||
seen = {}
|
||||
out = []
|
||||
for x in arr
|
||||
if (!has(seen, to_string(x)))
|
||||
seen[to_string(x)] = 1
|
||||
push(out, x)
|
||||
print(to_string(out))
|
||||
|
||||
/* Expected output:
|
||||
[array n=4]
|
||||
*/
|
||||
60
examples/algos/sort_and_search.fun
Executable file
60
examples/algos/sort_and_search.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 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Selection sort + linear/binary search
|
||||
|
||||
fun sel_sort(a)
|
||||
n = len(a)
|
||||
i = 0
|
||||
while (i < n)
|
||||
m = i
|
||||
j = i + 1
|
||||
while (j < n)
|
||||
if (a[j] < a[m]) m = j
|
||||
j = j + 1
|
||||
tmp = a[i]
|
||||
a[i] = a[m]
|
||||
a[m] = tmp
|
||||
i = i + 1
|
||||
return a
|
||||
|
||||
fun lin_find(a, x)
|
||||
i = 0
|
||||
while (i < len(a))
|
||||
if (a[i] == x) return i
|
||||
i = i + 1
|
||||
return -1
|
||||
|
||||
fun bin_find(a, x)
|
||||
lo = 0
|
||||
hi = len(a) - 1
|
||||
while (lo <= hi)
|
||||
mid = (lo + hi) / 2
|
||||
v = a[mid]
|
||||
if (v == x) return mid
|
||||
if (v < x)
|
||||
lo = mid + 1
|
||||
else
|
||||
hi = mid - 1
|
||||
return -1
|
||||
|
||||
arr = [5,1,4,2,3]
|
||||
print("sorted: " + to_string(sel_sort(arr)))
|
||||
print("lin_find 4: " + to_string(lin_find(arr, 4)))
|
||||
print("bin_find 4: " + to_string(bin_find(arr, 4)))
|
||||
|
||||
/* Expected output:
|
||||
sorted: [array n=5]
|
||||
lin_find 4: 2
|
||||
bin_find 4: 2
|
||||
*/
|
||||
44
examples/algos/stack_queue.fun
Executable file
44
examples/algos/stack_queue.fun
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Array helpers
|
||||
#include <arrays.fun>
|
||||
|
||||
// Stack via array push/pop
|
||||
stack = []
|
||||
push(stack, 1)
|
||||
push(stack, 2)
|
||||
push(stack, 3)
|
||||
print("stack pop: " + to_string(stack[len(stack)-1]))
|
||||
pop = stack[len(stack)-1]
|
||||
// Use array_slice(arr, start, count) to drop the last element
|
||||
stack = array_slice(stack, 0, len(stack)-1)
|
||||
print("stack now: " + to_string(stack))
|
||||
|
||||
// Queue via array push/shift
|
||||
queue = []
|
||||
push(queue, "a")
|
||||
push(queue, "b")
|
||||
push(queue, "c")
|
||||
head = queue[0]
|
||||
// Keep all but the first element
|
||||
queue = array_slice(queue, 1, len(queue)-1)
|
||||
print("queue head: " + to_string(head))
|
||||
print("queue now: " + to_string(queue))
|
||||
|
||||
/* Expected output:
|
||||
stack pop: 3
|
||||
stack now: [array n=2]
|
||||
queue head: a
|
||||
queue now: [array n=2]
|
||||
*/
|
||||
30
examples/basics/collections.fun
Executable file
30
examples/basics/collections.fun
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Arrays and maps basics
|
||||
|
||||
arr = [1, 2, 3]
|
||||
push(arr, 4)
|
||||
print("arr size=" + to_string(len(arr)) + ", last=" + to_string(arr[3]))
|
||||
|
||||
user = {"name": "Lin", "age": 29}
|
||||
user["city"] = "Paris"
|
||||
for k in keys(user)
|
||||
print(k + ": " + to_string(user[k]))
|
||||
|
||||
/* Expected output:
|
||||
arr size=4, last=4
|
||||
age: 29
|
||||
name: Lin
|
||||
city: Paris
|
||||
*/
|
||||
38
examples/basics/fibonacci.fun
Executable file
38
examples/basics/fibonacci.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 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Fibonacci: iterative and recursive
|
||||
|
||||
fun fib_iter(n)
|
||||
if (n <= 1) return n
|
||||
a = 0
|
||||
b = 1
|
||||
i = 2
|
||||
while (i <= n)
|
||||
t = a + b
|
||||
a = b
|
||||
b = t
|
||||
i = i + 1
|
||||
return b
|
||||
|
||||
fun fib_rec(n)
|
||||
if (n <= 1) return n
|
||||
return fib_rec(n - 1) + fib_rec(n - 2)
|
||||
|
||||
print("fib_iter(10) = " + to_string(fib_iter(10)))
|
||||
print("fib_rec(10) = " + to_string(fib_rec(10)))
|
||||
|
||||
/* Expected output:
|
||||
fib_iter(10) = 55
|
||||
fib_rec(10) = 55
|
||||
*/
|
||||
125
examples/basics/fizzbuzz.fun
Executable file
125
examples/basics/fizzbuzz.fun
Executable file
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Classic FizzBuzz from 1..100
|
||||
i = 1
|
||||
while (i <= 100)
|
||||
out = ""
|
||||
if (i % 3 == 0) out = out + "Fizz"
|
||||
if (i % 5 == 0) out = out + "Buzz"
|
||||
if (len(out) == 0) out = to_string(i)
|
||||
print(out)
|
||||
i = i + 1
|
||||
|
||||
/* Expected output:
|
||||
1
|
||||
2
|
||||
Fizz
|
||||
4
|
||||
Buzz
|
||||
Fizz
|
||||
7
|
||||
8
|
||||
Fizz
|
||||
Buzz
|
||||
11
|
||||
Fizz
|
||||
13
|
||||
14
|
||||
FizzBuzz
|
||||
16
|
||||
17
|
||||
Fizz
|
||||
19
|
||||
Buzz
|
||||
Fizz
|
||||
22
|
||||
23
|
||||
Fizz
|
||||
Buzz
|
||||
26
|
||||
Fizz
|
||||
28
|
||||
29
|
||||
FizzBuzz
|
||||
31
|
||||
32
|
||||
Fizz
|
||||
34
|
||||
Buzz
|
||||
Fizz
|
||||
37
|
||||
38
|
||||
Fizz
|
||||
Buzz
|
||||
41
|
||||
Fizz
|
||||
43
|
||||
44
|
||||
FizzBuzz
|
||||
46
|
||||
47
|
||||
Fizz
|
||||
49
|
||||
Buzz
|
||||
Fizz
|
||||
52
|
||||
53
|
||||
Fizz
|
||||
Buzz
|
||||
56
|
||||
Fizz
|
||||
58
|
||||
59
|
||||
FizzBuzz
|
||||
61
|
||||
62
|
||||
Fizz
|
||||
64
|
||||
Buzz
|
||||
Fizz
|
||||
67
|
||||
68
|
||||
Fizz
|
||||
Buzz
|
||||
71
|
||||
Fizz
|
||||
73
|
||||
74
|
||||
FizzBuzz
|
||||
76
|
||||
77
|
||||
Fizz
|
||||
79
|
||||
Buzz
|
||||
Fizz
|
||||
82
|
||||
83
|
||||
Fizz
|
||||
Buzz
|
||||
86
|
||||
Fizz
|
||||
88
|
||||
89
|
||||
FizzBuzz
|
||||
91
|
||||
92
|
||||
Fizz
|
||||
94
|
||||
Buzz
|
||||
Fizz
|
||||
97
|
||||
98
|
||||
Fizz
|
||||
Buzz
|
||||
*/
|
||||
19
examples/basics/hello_world.fun
Executable file
19
examples/basics/hello_world.fun
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Minimal Hello World in Fun
|
||||
print("Hello, World!")
|
||||
|
||||
/* Expected output:
|
||||
Hello, World!
|
||||
*/
|
||||
41
examples/cli/args_parse.fun
Executable file
41
examples/cli/args_parse.fun
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Parse env-style args: ARGS="key=val foo=bar" (since argv is not available here)
|
||||
// String helpers
|
||||
#include <strings.fun>
|
||||
line = env("ARGS")
|
||||
if (len(line) == 0)
|
||||
line = "name=Fun color=blue"
|
||||
|
||||
parts = str_split(line, " ")
|
||||
cfg = {}
|
||||
for p in parts
|
||||
if (len(p) == 0) continue
|
||||
eq = find(p, "=")
|
||||
if (eq > 0)
|
||||
k = substr(p, 0, eq)
|
||||
v = substr(p, eq + 1, len(p) - eq - 1)
|
||||
cfg[k] = v
|
||||
|
||||
for k in keys(cfg)
|
||||
print(k + ": " + to_string(cfg[k]))
|
||||
|
||||
/* Expected output (order of keys may vary):
|
||||
name: Fun
|
||||
color: blue
|
||||
|
||||
With ARGS overridden, e.g.: ARGS="x=1 y=2"
|
||||
x: 1
|
||||
y: 2
|
||||
*/
|
||||
23
examples/cli/env_echo.fun
Executable file
23
examples/cli/env_echo.fun
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
keys_to_show = ["HOME", "USER", "SHELL", "PATH"]
|
||||
for k in keys_to_show
|
||||
print(k + "=" + env(k))
|
||||
|
||||
/* Expected output (values depend on your environment):
|
||||
HOME=/home/youruser
|
||||
USER=youruser
|
||||
SHELL=/bin/bash
|
||||
PATH=/usr/local/bin:... (truncated)
|
||||
*/
|
||||
23
examples/compose/pipeline.fun
Executable file
23
examples/compose/pipeline.fun
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <strings.fun>
|
||||
|
||||
res1 = proc_run("echo one")
|
||||
res2 = proc_run("echo two")
|
||||
out = str_trim(res1["out"]) + "," + str_trim(res2["out"])
|
||||
print(out)
|
||||
|
||||
/* Expected output:
|
||||
one,two
|
||||
*/
|
||||
25
examples/compose/run_other_fun.fun
Executable file
25
examples/compose/run_other_fun.fun
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
cmd = "./build_debug/fun ./examples/basics/hello_world.fun"
|
||||
res = proc_run(cmd)
|
||||
print("exit: " + to_string(res["code"]))
|
||||
print("out: " + to_string(res["out"]))
|
||||
print("err: " + to_string(res["err"]))
|
||||
|
||||
/* Expected output (with build_debug/fun present):
|
||||
exit: 0
|
||||
out: Hello, World!\n
|
||||
|
||||
err: nil
|
||||
*/
|
||||
31
examples/data/htdocs/counter.fun
Normal file
31
examples/data/htdocs/counter.fun
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <net/cgi.fun>
|
||||
|
||||
cgi = CGI()
|
||||
v = to_number(cgi.cookie("visits"))
|
||||
if (v <= 0) v = 0
|
||||
v = v + 1
|
||||
cgi.header("Set-Cookie", "visits=" + to_string(v) + "; Path=/; HttpOnly")
|
||||
cgi.content_type("text/html; charset=utf-8")
|
||||
body = "<html><body><p>Visits: " + to_string(v) + "</p></body></html>"
|
||||
cgi.send(body)
|
||||
|
||||
/* Expected output (first visit, no existing cookie):
|
||||
Status: 200 OK
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Set-Cookie: visits=1; Path=/; HttpOnly
|
||||
|
||||
<html><body><p>Visits: 1</p></body></html>
|
||||
*/
|
||||
36
examples/data/htdocs/form_post.fun
Normal file
36
examples/data/htdocs/form_post.fun
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <net/cgi.fun>
|
||||
|
||||
cgi = CGI()
|
||||
cgi.content_type("text/html; charset=utf-8")
|
||||
pmap = cgi.params()
|
||||
html = "<html><body><h1>POST fields</h1><ul>"
|
||||
for k in keys(pmap)
|
||||
vals = cgi.param_all(k)
|
||||
i = 0; n = len(vals); joined = ""
|
||||
while (i < n)
|
||||
if (i > 0) joined = joined + ", "
|
||||
joined = joined + cgi.escape_html(vals[i])
|
||||
i = i + 1
|
||||
html = html + "<li><b>" + cgi.escape_html(k) + "</b>: " + joined + "</li>"
|
||||
html = html + "</ul></body></html>"
|
||||
cgi.send(html)
|
||||
|
||||
/* Expected output (POST with body: "a=1&b=two&b=2"):
|
||||
Status: 200 OK
|
||||
Content-Type: text/html; charset=utf-8
|
||||
|
||||
<html><body><h1>POST fields</h1><ul><li><b>a</b>: 1</li><li><b>b</b>: two, 2</li></ul></body></html>
|
||||
*/
|
||||
|
|
@ -52,3 +52,11 @@ html = html + "</body></html>"
|
|||
|
||||
// Send CGI headers + body
|
||||
cgi.send(html)
|
||||
|
||||
/* Expected output (GET /hello.fun?name=Fun with no ua cookie):
|
||||
Status: 200 OK
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Set-Cookie: ua=FunClient; Path=/; HttpOnly
|
||||
|
||||
<html><head><title>Fun CGI</title></head><body><h1>Hello, Fun!</h1><p>REQUEST_METHOD: GET</p><p>QUERY_STRING: name=Fun</p><p>User-Agent cookie: </p><h2>Params</h2><ul><li><b>name</b>: Fun</li></ul></body></html>
|
||||
*/
|
||||
|
|
|
|||
21
examples/data/htdocs/json_like_api.fun
Normal file
21
examples/data/htdocs/json_like_api.fun
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <net/cgi.fun>
|
||||
|
||||
cgi = CGI()
|
||||
cgi.content_type("application/json; charset=utf-8")
|
||||
name = cgi.param("name")
|
||||
if (len(name) == 0) name = "World"
|
||||
body = "{\n \"greeting\": \"Hello, " + cgi.escape_html(name) + "!\",\n \"method\": \"" + cgi.escape_html(cgi.env["REQUEST_METHOD"]) + "\"\n}"
|
||||
cgi.send(body)
|
||||
19
examples/data/htdocs/redirect.fun
Normal file
19
examples/data/htdocs/redirect.fun
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <net/cgi.fun>
|
||||
|
||||
cgi = CGI()
|
||||
cgi.redirect("/hello.fun?name=Fun", 302)
|
||||
cgi.content_type("text/html; charset=utf-8")
|
||||
cgi.send("<html><body>Redirecting...</body></html>")
|
||||
4
examples/data/sample.csv
Normal file
4
examples/data/sample.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
name,age,city
|
||||
Ada,37,London
|
||||
Lin,29,Paris
|
||||
Max,42,Berlin
|
||||
|
37
examples/io/csv_reader.fun
Executable file
37
examples/io/csv_reader.fun
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <strings.fun>
|
||||
|
||||
path = "./examples/data/sample.csv"
|
||||
|
||||
// Very small CSV reader (no quotes/escapes) for demo purposes
|
||||
fun parse_csv_line(line)
|
||||
return str_split(str_trim(line), ",")
|
||||
|
||||
data = read_file(path)
|
||||
if (len(data) == 0)
|
||||
print("No CSV content at: " + path)
|
||||
else
|
||||
rows = str_split(data, "\n")
|
||||
for row in rows
|
||||
if (len(str_trim(row)) == 0) continue
|
||||
cols = parse_csv_line(row)
|
||||
print("ROW: " + to_string(cols))
|
||||
|
||||
/* Expected output (from examples/io/sample.csv):
|
||||
ROW: [array n=3]
|
||||
ROW: [array n=3]
|
||||
ROW: [array n=3]
|
||||
ROW: [array n=3]
|
||||
*/
|
||||
25
examples/io/read_write_file.fun
Executable file
25
examples/io/read_write_file.fun
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <strings.fun>
|
||||
|
||||
path = "./tmp/example.txt"
|
||||
print("Writing to: " + path)
|
||||
write_file(path, "Hello from Fun!\n")
|
||||
txt = read_file(path)
|
||||
print("Read back: " + str_trim(txt))
|
||||
|
||||
/* Expected output:
|
||||
Writing to: ./tmp/example.txt
|
||||
Read back: Hello from Fun!
|
||||
*/
|
||||
412
examples/io/word_count.fun
Executable file
412
examples/io/word_count.fun
Executable file
|
|
@ -0,0 +1,412 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// String helpers
|
||||
#include <strings.fun>
|
||||
|
||||
path = "./README.md"
|
||||
txt = read_file(path)
|
||||
if (len(txt) == 0)
|
||||
print("no content: " + path)
|
||||
return 0
|
||||
|
||||
txt = str_to_lower(txt)
|
||||
txt = str_replace_all(txt, "\n", " ")
|
||||
parts = str_split(txt, " ")
|
||||
freq = {}
|
||||
for w in parts
|
||||
w = str_trim(w)
|
||||
if (len(w) == 0) continue
|
||||
c = to_number(freq[w])
|
||||
if (c <= 0) c = 0
|
||||
freq[w] = c + 1
|
||||
|
||||
for k in keys(freq)
|
||||
print(k + ": " + to_string(freq[k]))
|
||||
|
||||
/* Possible output (first 10 lines; counts depend on README.md contents):
|
||||
#: 1
|
||||
fun: 19
|
||||
([https://fun-lang.xyz](https://fun-lang.xyz)): 1
|
||||
##: 9
|
||||
what: 2
|
||||
is: 16
|
||||
fun?: 1
|
||||
a: 9
|
||||
small,: 1
|
||||
strict,: 1
|
||||
and: 15
|
||||
simple: 3
|
||||
programming: 5
|
||||
language: 5
|
||||
that: 4
|
||||
runs: 1
|
||||
on: 3
|
||||
compact: 1
|
||||
stack-based: 1
|
||||
virtual: 1
|
||||
machine.: 1
|
||||
the: 24
|
||||
c: 2
|
||||
core: 3
|
||||
intentionally: 1
|
||||
minimal;: 1
|
||||
most: 6
|
||||
functionality: 1
|
||||
standard: 2
|
||||
libraries: 2
|
||||
are: 6
|
||||
implemented: 2
|
||||
in: 19
|
||||
itself.: 2
|
||||
emphasizes: 1
|
||||
simplicity,: 1
|
||||
consistency,: 1
|
||||
joy: 3
|
||||
coding.: 2
|
||||
an: 1
|
||||
experiment,: 1
|
||||
just: 2
|
||||
for: 6
|
||||
fun,: 3
|
||||
but: 5
|
||||
works!: 1
|
||||
highly: 2
|
||||
strict: 1
|
||||
language,: 1
|
||||
also: 1
|
||||
simple.: 1
|
||||
it: 2
|
||||
looks: 2
|
||||
like: 4
|
||||
python: 1
|
||||
(my: 1
|
||||
favorite: 1
|
||||
language),: 1
|
||||
there: 2
|
||||
differences.: 1
|
||||
influenced: 1
|
||||
by: 2
|
||||
**[bash](https://www.gnu.org/software/bash/)**,: 1
|
||||
**[c](https://en.wikipedia.org/wiki/the_c_programming_language)**,: 1
|
||||
**[lua](https://www.lua.org/)**,: 1
|
||||
php,: 1
|
||||
**[python](https://www.python.org/)**,: 1
|
||||
rust: 1
|
||||
(most: 1
|
||||
influences: 1
|
||||
came: 1
|
||||
from: 2
|
||||
linked: 1
|
||||
languages).: 1
|
||||
will: 4
|
||||
ever: 1
|
||||
be: 5
|
||||
100%: 1
|
||||
free: 1
|
||||
under: 1
|
||||
terms: 1
|
||||
of: 3
|
||||
[apache-2.0: 1
|
||||
license](https://opensource.org/license/apache-2-0).: 1
|
||||
idea: 1
|
||||
-: 48
|
||||
simplicity: 2
|
||||
consistency: 2
|
||||
to: 7
|
||||
extend: 1
|
||||
hackable: 1
|
||||
coding: 2
|
||||
fun!: 1
|
||||
characteristics: 1
|
||||
dynamic: 1
|
||||
optionally: 1
|
||||
statically: 1
|
||||
typed: 1
|
||||
type: 1
|
||||
safety: 1
|
||||
written: 6
|
||||
(c99): 1
|
||||
internal: 1
|
||||
libs: 2
|
||||
with: 2
|
||||
no_camel_case: 1
|
||||
even: 1
|
||||
when: 1
|
||||
except: 1
|
||||
class: 1
|
||||
names: 1
|
||||
only: 2
|
||||
minimal: 1
|
||||
function: 1
|
||||
set: 1
|
||||
c,: 1
|
||||
other: 1
|
||||
functions: 1
|
||||
manifesto: 1
|
||||
built: 2
|
||||
idea:: 1
|
||||
should: 6
|
||||
enjoyable,: 1
|
||||
elegant,: 1
|
||||
consistent.: 1
|
||||
###: 5
|
||||
philosophy: 1
|
||||
**fun: 2
|
||||
fun**<br>: 1
|
||||
spark: 1
|
||||
creativity,: 1
|
||||
not: 4
|
||||
frustration.: 1
|
||||
code: 3
|
||||
feels: 3
|
||||
light,: 1
|
||||
playful,: 1
|
||||
rewarding.: 1
|
||||
uses: 1
|
||||
nothing**<br>: 1
|
||||
minimalism: 1
|
||||
power.: 1
|
||||
no: 7
|
||||
unnecessary: 1
|
||||
features,: 1
|
||||
endless: 1
|
||||
syntax: 1
|
||||
variations,: 1
|
||||
formatting: 1
|
||||
debates.: 1
|
||||
clean,: 1
|
||||
uniform: 1
|
||||
code.: 1
|
||||
**indentation: 1
|
||||
truth**<br>: 1
|
||||
two: 1
|
||||
spaces,: 1
|
||||
always.: 1
|
||||
tabs,: 1
|
||||
four-space: 1
|
||||
wars.: 1
|
||||
look: 1
|
||||
same: 2
|
||||
everywhere,: 1
|
||||
your: 1
|
||||
laptop: 1
|
||||
/usr/bin/fun.: 1
|
||||
**one: 1
|
||||
way: 1
|
||||
do: 1
|
||||
it**<br>: 1
|
||||
clutter,: 1
|
||||
15: 1
|
||||
ways: 1
|
||||
writing: 1
|
||||
thing.: 1
|
||||
means: 1
|
||||
clarity.: 1
|
||||
**hackable: 1
|
||||
nature**<br>: 1
|
||||
small: 1
|
||||
embeddable,: 1
|
||||
lua.: 1
|
||||
easy: 1
|
||||
understand,: 1
|
||||
extend,: 1
|
||||
tinker: 1
|
||||
—: 2
|
||||
true: 1
|
||||
hacker: 1
|
||||
spirit.: 1
|
||||
**beautiful: 1
|
||||
defaults**<br>: 1
|
||||
doesn’t: 1
|
||||
need: 1
|
||||
linters,: 1
|
||||
formatters,: 1
|
||||
or: 3
|
||||
style: 1
|
||||
guides.: 1
|
||||
beauty: 1
|
||||
in.: 1
|
||||
community: 3
|
||||
about: 2
|
||||
being: 1
|
||||
fastest: 1
|
||||
feature-rich.: 1
|
||||
it’s: 1
|
||||
sharing: 1
|
||||
be:: 1
|
||||
respectful: 1
|
||||
curious: 1
|
||||
creative: 1
|
||||
open: 1
|
||||
everyone: 1
|
||||
name: 1
|
||||
says:: 1
|
||||
unites: 1
|
||||
nerds.: 1
|
||||
please: 1
|
||||
visit: 1
|
||||
[fun: 1
|
||||
page](https://fun-lang.xyz/community/): 1
|
||||
get: 1
|
||||
touch.: 1
|
||||
goal: 1
|
||||
home: 1
|
||||
developers: 1
|
||||
who:: 1
|
||||
love: 1
|
||||
minimal,: 1
|
||||
elegant: 1
|
||||
tools: 1
|
||||
believe: 1
|
||||
freedom: 1
|
||||
want: 1
|
||||
write: 1
|
||||
good: 2
|
||||
may: 2
|
||||
change: 1
|
||||
world: 1
|
||||
make: 1
|
||||
little: 1
|
||||
more: 1
|
||||
fun.: 1
|
||||
features: 2
|
||||
functions/classes/objects: 1
|
||||
if/else: 2
|
||||
try/catch/finally: 1
|
||||
lib: 1
|
||||
(./lib/): 1
|
||||
see: 2
|
||||
[./lib/](https://git.xw3.org/fun/fun/src/branch/main/lib): 2
|
||||
library: 1
|
||||
provides.: 1
|
||||
optional: 1
|
||||
extensions: 1
|
||||
(build-time: 1
|
||||
selectable: 1
|
||||
/: 2
|
||||
testing: 1
|
||||
this: 1
|
||||
linux: 1
|
||||
actually):: 1
|
||||
[cgi](https://en.wikipedia.org/wiki/common_gateway_interface): 1
|
||||
support: 1
|
||||
builtin: 1
|
||||
using: 1
|
||||
[kcgi](https://kristaps.bsd.lv/kcgi/): 1
|
||||
(optional): 11
|
||||
☐: 2
|
||||
[curl: 1
|
||||
(libcurl)](./docs/external/curl.md): 1
|
||||
☑: 11
|
||||
[ini: 1
|
||||
(iniparser)](./docs/external/ini.md): 1
|
||||
[json: 1
|
||||
(json-c)](./docs/external/json.md): 1
|
||||
[libsql](./docs/external/libsql.md): 1
|
||||
[pcre2](./docs/external/pcre2.md): 1
|
||||
[pcsc: 1
|
||||
(smart: 1
|
||||
cards)](./docs/external/pcsc.md): 1
|
||||
[openssl](./docs/external/openssl.md): 1
|
||||
[sqlite](./docs/external/sqlite.md): 1
|
||||
[tk: 1
|
||||
(tcl/tk: 1
|
||||
gui)](./docs/external/tcltk.md): 1
|
||||
[xml: 1
|
||||
(libxml2)](./docs/external/xml2.md): 1
|
||||
=: 2
|
||||
done: 1
|
||||
planned: 1
|
||||
progress.: 1
|
||||
note:: 2
|
||||
all: 1
|
||||
above: 1
|
||||
implemented.: 1
|
||||
those: 1
|
||||
who: 1
|
||||
marked: 1
|
||||
"done": 1
|
||||
probaly: 1
|
||||
remain: 1
|
||||
i: 1
|
||||
don't: 1
|
||||
know: 1
|
||||
actually...: 1
|
||||
;): 1
|
||||
some: 2
|
||||
available: 1
|
||||
diretory.: 1
|
||||
future: 1
|
||||
enhancements: 1
|
||||
openssl: 1
|
||||
quickstart: 1
|
||||
(md5): 1
|
||||
dedicated: 1
|
||||
page:: 1
|
||||
./docs/external/openssl.md: 1
|
||||
documentation: 2
|
||||
looking: 1
|
||||
docs?: 1
|
||||
start: 1
|
||||
here:: 1
|
||||
local: 1
|
||||
index:: 1
|
||||
[docs/readme.md](./docs/readme.md): 1
|
||||
handbook:: 1
|
||||
[docs/handbook.md](./docs/handbook.md): 1
|
||||
types: 1
|
||||
overview:: 1
|
||||
[docs/types.md](./docs/types.md): 1
|
||||
repl: 1
|
||||
guide:: 1
|
||||
[docs/repl.md](./docs/repl.md): 1
|
||||
testing:: 1
|
||||
[docs/testing.md](./docs/testing.md): 1
|
||||
troubleshooting:: 1
|
||||
[docs/troubleshooting.md](./docs/troubleshooting.md): 1
|
||||
additional: 1
|
||||
references:: 1
|
||||
specification:: 1
|
||||
[spec/v0.3.md](./spec/v0.3.md): 1
|
||||
(work: 1
|
||||
progress): 1
|
||||
examples: 1
|
||||
demonstrating: 1
|
||||
features:: 1
|
||||
[examples/](./examples/): 1
|
||||
internals: 1
|
||||
vm: 1
|
||||
opcodes: 1
|
||||
live: 1
|
||||
[src/](./src/): 1
|
||||
(see: 1
|
||||
[src/vm/](./src/vm): 1
|
||||
opcode: 1
|
||||
implementations): 1
|
||||
project: 1
|
||||
evolving;: 1
|
||||
documents: 1
|
||||
lag: 1
|
||||
behind.: 1
|
||||
docs: 1
|
||||
index: 1
|
||||
`./docs/readme.md`: 1
|
||||
up‑to‑date: 1
|
||||
entry: 1
|
||||
point.: 1
|
||||
author: 1
|
||||
johannes: 1
|
||||
findeisen: 1
|
||||
<you@hanez.org>: 1
|
||||
*/
|
||||
40
examples/net/http_static_server.fun
Executable file
40
examples/net/http_static_server.fun
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <io/socket.fun>
|
||||
|
||||
port = 8088
|
||||
srv = TcpServer(port, 10)
|
||||
if (srv.listen() <= 0)
|
||||
print("HTTP static server: listen failed on :" + to_string(port))
|
||||
return 0
|
||||
print("HTTP static server on :" + to_string(port))
|
||||
while true
|
||||
fd = srv.accept()
|
||||
if (fd > 0)
|
||||
_ = sock_recv(fd, 4096) // ignore request
|
||||
body = "<html><body><h1>Hello from Fun static server</h1></body></html>"
|
||||
b = to_string(body)
|
||||
resp = "HTTP/1.1 200 OK\r\n"
|
||||
resp = resp + "Content-Type: text/html; charset=utf-8\r\n"
|
||||
resp = resp + "Content-Length: " + to_string(len(b)) + "\r\n"
|
||||
resp = resp + "Connection: close\r\n\r\n" + b
|
||||
sock_send(fd, resp)
|
||||
sock_close(fd)
|
||||
|
||||
/* Expected output (on start):
|
||||
HTTP static server on :8088
|
||||
|
||||
Then open http://127.0.0.1:8088/ in a browser; it will render:
|
||||
<html><body><h1>Hello from Fun static server</h1></body></html>
|
||||
*/
|
||||
27
examples/net/tcp_echo_client.fun
Executable file
27
examples/net/tcp_echo_client.fun
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <io/socket.fun>
|
||||
|
||||
fd = sock_connect("127.0.0.1", 9090)
|
||||
if (fd <= 0)
|
||||
print("connect failed")
|
||||
return 0
|
||||
sock_send(fd, "ping\n")
|
||||
resp = sock_recv(fd, 4096)
|
||||
print("response: " + resp)
|
||||
sock_close(fd)
|
||||
|
||||
/* Expected output (with tcp_echo_server.fun running):
|
||||
response: ping
|
||||
*/
|
||||
33
examples/net/tcp_echo_server.fun
Executable file
33
examples/net/tcp_echo_server.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 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <io/socket.fun>
|
||||
|
||||
port = 9090
|
||||
srv = TcpServer(port, 10)
|
||||
if (srv.listen() <= 0)
|
||||
print("listen failed on :" + to_string(port))
|
||||
return 0
|
||||
print("Echo server on :" + to_string(port))
|
||||
while true
|
||||
fd = srv.accept()
|
||||
if (fd > 0)
|
||||
msg = sock_recv(fd, 4096)
|
||||
if (len(msg) > 0) sock_send(fd, msg)
|
||||
sock_close(fd)
|
||||
|
||||
/* Expected output (on start):
|
||||
Echo server on :9090
|
||||
|
||||
Then, from another shell: `nc 127.0.0.1 9090` and type "ping" — the server echoes it back.
|
||||
*/
|
||||
25
examples/patterns/assert_like.fun
Executable file
25
examples/patterns/assert_like.fun
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
fun assert_like(cond, msg)
|
||||
if (!cond)
|
||||
print("ASSERT FAILED: " + to_string(msg))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
ok = assert_like(1 + 1 == 2, "math broke")
|
||||
print("assert returned: " + to_string(ok))
|
||||
|
||||
/* Expected output:
|
||||
assert returned: 1
|
||||
*/
|
||||
37
examples/patterns/logging_min.fun
Executable file
37
examples/patterns/logging_min.fun
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Minimal helper: remove trailing newline from a string (no full strings lib needed)
|
||||
fun chomp(s)
|
||||
t = to_string(s)
|
||||
if (len(t) > 0 && substr(t, len(t) - 1, 1) == "\n")
|
||||
return substr(t, 0, len(t) - 1)
|
||||
return t
|
||||
|
||||
fun now()
|
||||
// Very rough timestamp using system 'date' for demo
|
||||
r = proc_run("date +%Y-%m-%dT%H:%M:%S%z")
|
||||
return chomp(r["out"])
|
||||
|
||||
fun log_line(level, msg)
|
||||
print("[" + now() + "] [" + to_string(level) + "] " + to_string(msg))
|
||||
|
||||
log_line("INFO", "Service starting")
|
||||
log_line("DEBUG", "Config loaded")
|
||||
log_line("INFO", "Service running")
|
||||
|
||||
/* Expected output (timestamps will vary):
|
||||
[2026-03-25T23:00:00+0000] [INFO] Service starting
|
||||
[2026-03-25T23:00:00+0000] [DEBUG] Config loaded
|
||||
[2026-03-25T23:00:00+0000] [INFO] Service running
|
||||
*/
|
||||
24
examples/snippets/escape_html_demo.fun
Executable file
24
examples/snippets/escape_html_demo.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 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <net/cgi.fun>
|
||||
|
||||
cgi = CGI()
|
||||
raw = "<script>alert('xss') & more</script>"
|
||||
print("raw: " + raw)
|
||||
print("escaped:" + cgi.escape_html(raw))
|
||||
|
||||
/* Expected output:
|
||||
raw: <script>alert('xss') & more</script>
|
||||
escaped:<script>alert('xss') & more</script>
|
||||
*/
|
||||
29
examples/strings/split_join_trim.fun
Executable file
29
examples/strings/split_join_trim.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 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <strings.fun>
|
||||
|
||||
txt = " one, two , three "
|
||||
parts = str_split(txt, ",")
|
||||
i = 0
|
||||
while (i < len(parts))
|
||||
parts[i] = str_trim(parts[i])
|
||||
i = i + 1
|
||||
print("parts: " + to_string(parts))
|
||||
joined = join(parts, ";")
|
||||
print("joined: " + joined)
|
||||
|
||||
/* Expected output:
|
||||
parts: [array n=3]
|
||||
joined: one;two;three
|
||||
*/
|
||||
30
examples/strings/templating_min.fun
Executable file
30
examples/strings/templating_min.fun
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env fun
|
||||
|
||||
/*
|
||||
* This file is part of the Fun programming language.
|
||||
* https://fun-lang.xyz/
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
// Micro templating: replace {{key}} with map values
|
||||
#include <strings.fun>
|
||||
tpl = "Hello, {{name}} from {{city}}!"
|
||||
ctx = {"name": "Fun", "city": "Cyberspace"}
|
||||
|
||||
fun render(template, data)
|
||||
out = to_string(template)
|
||||
for k in keys(data)
|
||||
needle = "{{" + to_string(k) + "}}"
|
||||
out = str_replace_all(out, needle, to_string(data[k]))
|
||||
return out
|
||||
|
||||
print(render(tpl, ctx))
|
||||
|
||||
/* Expected output:
|
||||
Hello, Fun from Cyberspace!
|
||||
*/
|
||||
24
examples/strings/urlencode_decode.fun
Executable file
24
examples/strings/urlencode_decode.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 2026 Johannes Findeisen
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2026-03-25
|
||||
*/
|
||||
|
||||
#include <net/cgi.fun>
|
||||
|
||||
cgi = CGI()
|
||||
s = "name=Fun+Lang&msg=Hello%2C+World%21"
|
||||
print("raw: " + s)
|
||||
print("decod: " + cgi.url_decode(s))
|
||||
|
||||
/* Expected output:
|
||||
raw: name=Fun+Lang&msg=Hello%2C+World%21
|
||||
decod: name=Fun Lang&msg=Hello%2C World%21
|
||||
*/
|
||||
|
|
@ -16,7 +16,7 @@ fun str_ltrim(s)
|
|||
src = to_string(s)
|
||||
number i = 0
|
||||
ws = " \t\r\n"
|
||||
while i < len(src)
|
||||
while (i < len(src))
|
||||
ch = substr(src, i, 1)
|
||||
if (find(ws, ch) < 0)
|
||||
break
|
||||
|
|
@ -28,7 +28,7 @@ fun str_rtrim(s)
|
|||
src = to_string(s)
|
||||
number i = len(src) - 1
|
||||
ws = " \t\r\n"
|
||||
while i >= 0
|
||||
while (i >= 0)
|
||||
ch = substr(src, i, 1)
|
||||
if (find(ws, ch) < 0)
|
||||
break
|
||||
|
|
@ -69,7 +69,7 @@ fun str_split(s, delim)
|
|||
buf = []
|
||||
number i = 0
|
||||
number n = len(src)
|
||||
while i < n
|
||||
while (i < n)
|
||||
ch = substr(src, i, 1)
|
||||
if (ch == dd)
|
||||
push(parts, join(buf, ""))
|
||||
|
|
@ -92,7 +92,7 @@ fun str_replace_all(s, from, to)
|
|||
return src
|
||||
out = []
|
||||
number i = 0
|
||||
while i < n
|
||||
while (i < n)
|
||||
if ((i + lf <= n) && (substr(src, i, lf) == f))
|
||||
push(out, t)
|
||||
i = i + lf
|
||||
|
|
@ -109,7 +109,7 @@ fun str_to_lower(s)
|
|||
out = []
|
||||
number i = 0
|
||||
number n = len(src)
|
||||
while i < n
|
||||
while (i < n)
|
||||
ch = substr(src, i, 1)
|
||||
idx = find(U, ch)
|
||||
if (idx >= 0)
|
||||
|
|
@ -127,7 +127,7 @@ fun str_to_upper(s)
|
|||
out = []
|
||||
number i = 0
|
||||
number n = len(src)
|
||||
while i < n
|
||||
while (i < n)
|
||||
ch = substr(src, i, 1)
|
||||
idx = find(L, ch)
|
||||
if (idx >= 0)
|
||||
|
|
@ -145,59 +145,19 @@ fun str_repeat(s, count)
|
|||
return ""
|
||||
parts = []
|
||||
number i = 0
|
||||
while i < c
|
||||
while (i < c)
|
||||
push(parts, src)
|
||||
i = i + 1
|
||||
return join(parts, "")
|
||||
|
||||
/*
|
||||
// ASCII string to bytes (printable ASCII 0x20..0x7E)
|
||||
// Temporarily disabled due to parser incompatibilities with certain string
|
||||
// literals in this function on some environments. Re-enable after the
|
||||
// language parser updates to support these cases.
|
||||
fun string_to_bytes_ascii(s)
|
||||
str = to_string(s)
|
||||
out = []
|
||||
number i = 0
|
||||
// ASCII printable ranges
|
||||
P1 = " !\"#$%&'()*+,-./" // 32..47
|
||||
P2 = "0123456789" // 48..57
|
||||
P3 = ":;<=>?@" // 58..64
|
||||
P4 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // 65..90
|
||||
P5 = "[\\]^_`" // 91..96
|
||||
P6 = "abcdefghijklmnopqrstuvwxyz" // 97..122
|
||||
P7 = "{|}~" // 123..126
|
||||
while true
|
||||
ch = substr(str, i, 1)
|
||||
if (typeof(ch) != "String" || ch == "")
|
||||
break
|
||||
number code = -1
|
||||
idx = find(P1, ch)
|
||||
if (idx >= 0)
|
||||
code = 32 + idx
|
||||
else
|
||||
idx = find(P2, ch)
|
||||
if (idx >= 0)
|
||||
code = 48 + idx
|
||||
else
|
||||
idx = find(P3, ch)
|
||||
if (idx >= 0)
|
||||
code = 58 + idx
|
||||
else
|
||||
idx = find(P4, ch)
|
||||
if (idx >= 0)
|
||||
code = 65 + idx
|
||||
else
|
||||
idx = find(P5, ch)
|
||||
if (idx >= 0)
|
||||
code = 91 + idx
|
||||
else
|
||||
idx = find(P6, ch)
|
||||
if (idx >= 0)
|
||||
code = 97 + idx
|
||||
else
|
||||
idx = find(P7, ch)
|
||||
if (idx >= 0)
|
||||
code = 123 + idx
|
||||
else
|
||||
// non-printable -> 0
|
||||
code = 0
|
||||
push(out, code)
|
||||
i = i + 1
|
||||
return out
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue