From f72f9d0c296d973a0cbb5be39fe3a52b43e5ae28 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Fri, 28 Aug 2026 15:50:00 +0200 Subject: [PATCH] docs(examples): add example programs --- examples/calc.lumen | 45 ++++++++++++++++++++++++++++++++++++++ examples/closures.lumen | 33 ++++++++++++++++++++++++++++ examples/csv.lumen | 39 +++++++++++++++++++++++++++++++++ examples/fib.lumen | 12 ++++++++++ examples/fizzbuzz.lumen | 13 +++++++++++ examples/sort.lumen | 30 +++++++++++++++++++++++++ examples/stdlib_demo.lumen | 28 ++++++++++++++++++++++++ 7 files changed, 200 insertions(+) create mode 100644 examples/calc.lumen create mode 100644 examples/closures.lumen create mode 100644 examples/csv.lumen create mode 100644 examples/fib.lumen create mode 100644 examples/fizzbuzz.lumen create mode 100644 examples/sort.lumen create mode 100644 examples/stdlib_demo.lumen diff --git a/examples/calc.lumen b/examples/calc.lumen new file mode 100644 index 0000000..849e973 --- /dev/null +++ b/examples/calc.lumen @@ -0,0 +1,45 @@ +import "lib/mathx.lumen" + +// A tiny reverse-polish-notation calculator written in Lumen. +// It tokenizes a space separated expression and folds it over a stack. + +fn evalRpn(expression) { + let tokens = expression.split(" ") + let stack = [] + for (token in tokens) { + if (token == "+") { + let b = stack.pop() + let a = stack.pop() + stack.push(a + b) + } else if (token == "-") { + let b = stack.pop() + let a = stack.pop() + stack.push(a - b) + } else if (token == "*") { + let b = stack.pop() + let a = stack.pop() + stack.push(a * b) + } else if (token == "/") { + let b = stack.pop() + let a = stack.pop() + stack.push(a / b) + } else { + stack.push(int(token)) + } + } + assert(stack.len() == 1, "expression did not reduce to a single value") + return stack.pop() +} + +let expr = "3 4 + 5 * 2 -" +println(expr + " = " + str(evalRpn(expr))) +println("2 3 4 * + = " + str(evalRpn("2 3 4 * +"))) +println("10 2 / 3 - = " + str(evalRpn("10 2 / 3 -"))) + +// factorial and gcd come from the imported module. +println("6! = " + str(factorial(6))) +println("gcd(48, 36) = " + str(gcd(48, 36))) + +assert(factorial(5) == 120, "factorial broken") +assert(evalRpn("3 4 +") == 7, "rpn broken") +println("calc checks passed") diff --git a/examples/closures.lumen b/examples/closures.lumen new file mode 100644 index 0000000..417258c --- /dev/null +++ b/examples/closures.lumen @@ -0,0 +1,33 @@ +// Closures capturing mutable state, plus higher order functions. + +fn makeCounter() { + var count = 0 + fn increment() { + count = count + 1 + return count + } + return increment +} + +let counter = makeCounter() +println("counter: " + str(counter()) + " " + str(counter()) + " " + str(counter())) + +fn makeAdder(amount) { + fn add(value) { + return value + amount + } + return add +} + +let add10 = makeAdder(10) +let add100 = makeAdder(100) +println("add10(5) = " + str(add10(5))) +println("add100(5) = " + str(add100(5))) + +let numbers = [1, 2, 3, 4, 5] +let doubled = map(fn(x) { return x * 2 }, numbers) +let evens = filter(fn(x) { return x % 2 == 0 }, numbers) +let total = reduce(fn(acc, x) { return acc + x }, numbers, 0) +println("doubled: " + str(doubled)) +println("evens: " + str(evens)) +println("sum: " + str(total)) diff --git a/examples/csv.lumen b/examples/csv.lumen new file mode 100644 index 0000000..0173cf5 --- /dev/null +++ b/examples/csv.lumen @@ -0,0 +1,39 @@ +import "lib/text.lumen" + +// Parse a small CSV document into rows of trimmed fields, then compute a +// column total. Everything runs on the standard library and the text module. + +fn parseCsv(document) { + let rows = [] + for (line in document.split("\n")) { + if (line.trim().len() > 0) { + rows.push(trimAll(line.split(","))) + } + } + return rows +} + +fn columnValues(rows, index) { + return rows.map(fn(row) { return row[index] }) +} + +let document = "name, score +alice, 90 +bob, 75 +carol, 88" + +let rows = parseCsv(document) +let header = rows[0] +let body = rows.slice(1, rows.len()) + +println("columns: " + header.join(" | ")) +for (row in body) { + println(capitalize(row[0]) + " scored " + row[1]) +} + +let scores = columnValues(body, 1).map(fn(cell) { return int(cell) }) +println("total: " + str(scores.sum())) +println("best: " + str(scores.max())) + +assert(scores.sum() == 253, "csv total wrong") +println("csv checks passed") diff --git a/examples/fib.lumen b/examples/fib.lumen new file mode 100644 index 0000000..8aa40f4 --- /dev/null +++ b/examples/fib.lumen @@ -0,0 +1,12 @@ +// Recursive Fibonacci, printed for the first ten indices. + +fn fib(n) { + if (n < 2) { + return n + } + return fib(n - 1) + fib(n - 2) +} + +for (i in range(0, 10)) { + println("fib(" + str(i) + ") = " + str(fib(i))) +} diff --git a/examples/fizzbuzz.lumen b/examples/fizzbuzz.lumen new file mode 100644 index 0000000..e2cb6e0 --- /dev/null +++ b/examples/fizzbuzz.lumen @@ -0,0 +1,13 @@ +// Classic FizzBuzz for the numbers 1 through 15. + +for (n in range(1, 16)) { + if (n % 15 == 0) { + println("FizzBuzz") + } else if (n % 3 == 0) { + println("Fizz") + } else if (n % 5 == 0) { + println("Buzz") + } else { + println(str(n)) + } +} diff --git a/examples/sort.lumen b/examples/sort.lumen new file mode 100644 index 0000000..ded3f61 --- /dev/null +++ b/examples/sort.lumen @@ -0,0 +1,30 @@ +// Quicksort built on lists, recursion and higher level pieces of the language. + +fn quicksort(items) { + if (len(items) < 2) { + return items + } + let pivot = items[0] + let less = [] + let greater = [] + var i = 1 + while (i < len(items)) { + let current = items[i] + if (current < pivot) { + push(less, current) + } else { + push(greater, current) + } + i = i + 1 + } + let result = quicksort(less) + push(result, pivot) + for (value in quicksort(greater)) { + push(result, value) + } + return result +} + +let data = [5, 3, 8, 1, 9, 2, 7, 4, 6, 0] +println("input: " + str(data)) +println("sorted: " + str(quicksort(data))) diff --git a/examples/stdlib_demo.lumen b/examples/stdlib_demo.lumen new file mode 100644 index 0000000..70a775a --- /dev/null +++ b/examples/stdlib_demo.lumen @@ -0,0 +1,28 @@ +// A tour of the standard library and method-call syntax. + +let greeting = " Hello, Lumen World " +println("trimmed: " + greeting.trim()) +println("upper: " + greeting.trim().upper()) +println("words: " + str(greeting.trim().split(" "))) + +let numbers = [5, 3, 8, 1, 9, 2] +println("sorted: " + str(numbers.sort())) +println("reversed: " + str(numbers.reverse())) +println("sum: " + str(numbers.sum())) +println("min/max: " + str(numbers.min()) + " / " + str(numbers.max())) +println("evens: " + str(numbers.filter(fn(n) { return n % 2 == 0 }))) +println("squares: " + str(numbers.map(fn(n) { return n * n }))) + +let scores = {"alice": 90, "bob": 75} +println("has alice: " + str(scores.has("alice"))) +println("keys: " + str(scores.keys())) +println("entries: " + str(scores.entries())) + +println("sqrt 144: " + str(sqrt(144))) +println("pow 2 10: " + str(pow(2, 10))) +println("floor 3.7: " + str(floor(3.7))) +println("round 2.5: " + str(round(2.5))) + +assert(numbers.sum() == 28, "sum should be 28") +assert("lumen".upper() == "LUMEN", "upper should work") +println("all assertions passed")