feat: add async/await keywords, Num/String extensions, and Jinja markdown example
Add `async` and `await` token support to the Wren compiler with scheduler resolution logic, extend `Num` with `e` constant, hyperbolic trig, base conversion, and new methods (`isZero`, `gcd`, `lcm`, `digits`, etc.), extend `String` with `lower`, `upper`, `capitalize`, `title`, and regenerate `wren_core.wren.inc`. Include `Makefile` for multi-platform builds, rewrite `README.md` with updated build instructions, and add `example/await_demo.wren` and `example/jinja_markdown.wren` demonstrating new features.
This commit is contained in:
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "scheduler" for Scheduler, Future
|
||||
import "timer" for Timer
|
||||
|
||||
System.print("=== Await Demo ===\n")
|
||||
|
||||
System.print("--- Basic Await ---")
|
||||
await Timer.sleep(1)
|
||||
System.print("Timer completed")
|
||||
|
||||
System.print("\n--- Concurrent Async ---")
|
||||
var task1 = async { Timer.sleep(1) }
|
||||
var task2 = async { Timer.sleep(1) }
|
||||
await task1
|
||||
await task2
|
||||
System.print("Both tasks completed concurrently")
|
||||
|
||||
System.print("\n--- Async With Result ---")
|
||||
var task = async { "computed value" }
|
||||
var result = await task
|
||||
System.print("Result: %(result)")
|
||||
Vendored
+67
@@ -0,0 +1,67 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "jinja" for Environment, DictLoader
|
||||
|
||||
System.print("=" * 60)
|
||||
System.print("JINJA MARKDOWN - Markdown/HTML Conversion in Templates")
|
||||
System.print("=" * 60)
|
||||
|
||||
var templates = {
|
||||
"md_to_html": "{\% markdowntohtml \%}# {{ title }}
|
||||
|
||||
{{ description }}
|
||||
|
||||
- Item **one**
|
||||
- Item **two**
|
||||
- Item **three**
|
||||
{\% endmarkdowntohtml \%}",
|
||||
|
||||
"html_to_md": "{\% markdownfromhtml \%}<h1>{{ title }}</h1>
|
||||
<p>This is a <strong>paragraph</strong> with <em>formatting</em>.</p>
|
||||
<ul>
|
||||
<li>First</li>
|
||||
<li>Second</li>
|
||||
</ul>{\% endmarkdownfromhtml \%}",
|
||||
|
||||
"filter_md": "{{ content|markdown }}",
|
||||
|
||||
"filter_fromhtml": "{{ content|markdownfromhtml }}",
|
||||
|
||||
"mixed": "<div class=\"article\">
|
||||
{\% markdowntohtml \%}## {{ article.title }}
|
||||
|
||||
{{ article.body }}
|
||||
{\% endmarkdowntohtml \%}
|
||||
</div>"
|
||||
}
|
||||
|
||||
var env = Environment.new(DictLoader.new(templates))
|
||||
|
||||
System.print("\n--- Markdown to HTML (block tag) ---")
|
||||
System.print(env.getTemplate("md_to_html").render({
|
||||
"title": "Welcome",
|
||||
"description": "This is a *template* with markdown support."
|
||||
}))
|
||||
|
||||
System.print("\n--- HTML to Markdown (block tag) ---")
|
||||
System.print(env.getTemplate("html_to_md").render({
|
||||
"title": "Documentation"
|
||||
}))
|
||||
|
||||
System.print("\n--- Markdown filter ---")
|
||||
System.print(env.getTemplate("filter_md").render({
|
||||
"content": "**Bold** and *italic* text."
|
||||
}))
|
||||
|
||||
System.print("\n--- Markdown from HTML filter ---")
|
||||
System.print(env.getTemplate("filter_fromhtml").render({
|
||||
"content": "<h2>Section</h2><p>A paragraph.</p>"
|
||||
}))
|
||||
|
||||
System.print("\n--- Mixed HTML and Markdown ---")
|
||||
System.print(env.getTemplate("mixed").render({
|
||||
"article": {
|
||||
"title": "Getting Started",
|
||||
"body": "Read the **documentation** for details."
|
||||
}
|
||||
}))
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
System.print("=== Num Extensions Demo ===\n")
|
||||
|
||||
System.print("--- Constants ---")
|
||||
System.print("Num.pi: %(Num.pi)")
|
||||
System.print("Num.tau: %(Num.tau)")
|
||||
System.print("Num.e: %(Num.e)")
|
||||
|
||||
System.print("\n--- Query Methods ---")
|
||||
System.print("0.isZero: %(0.isZero)")
|
||||
System.print("5.isPositive: %(5.isPositive)")
|
||||
System.print("(-3).isNegative: %((-3).isNegative)")
|
||||
System.print("42.isFinite: %(42.isFinite)")
|
||||
System.print("(1/0).isFinite: %((1/0).isFinite)")
|
||||
System.print("4.isEven: %(4.isEven)")
|
||||
System.print("3.isOdd: %(3.isOdd)")
|
||||
System.print("5.isBetween(1, 10): %(5.isBetween(1, 10))")
|
||||
|
||||
System.print("\n--- Math Functions ---")
|
||||
System.print("100.log10: %(100.log10)")
|
||||
System.print("0.sinh: %(0.sinh)")
|
||||
System.print("0.cosh: %(0.cosh)")
|
||||
System.print("0.tanh: %(0.tanh)")
|
||||
|
||||
System.print("\n--- Angle Conversion ---")
|
||||
var pi = Num.pi
|
||||
System.print("pi.toDegrees: %(pi.toDegrees)")
|
||||
System.print("180.toRadians: %(180.toRadians)")
|
||||
|
||||
System.print("\n--- Base Conversion ---")
|
||||
System.print("255.toHex: %(255.toHex)")
|
||||
System.print("10.toBinary: %(10.toBinary)")
|
||||
System.print("8.toOctal: %(8.toOctal)")
|
||||
System.print("255.toBase(16): %(255.toBase(16))")
|
||||
System.print("100.toBase(36): %(100.toBase(36))")
|
||||
|
||||
System.print("\n--- Character Conversion ---")
|
||||
System.print("65.toChar: %(65.toChar)")
|
||||
System.print("97.toChar: %(97.toChar)")
|
||||
|
||||
System.print("\n--- Formatting ---")
|
||||
System.print("3.14159.format(2): %(3.14159.format(2))")
|
||||
System.print("42.format(3): %(42.format(3))")
|
||||
System.print("(-1.5).format(1): %((-1.5).format(1))")
|
||||
|
||||
System.print("\n--- Integer Operations ---")
|
||||
System.print("12.gcd(8): %(12.gcd(8))")
|
||||
System.print("4.lcm(6): %(4.lcm(6))")
|
||||
System.print("123.digits: %(123.digits)")
|
||||
System.print("0.digits: %(0.digits)")
|
||||
Vendored
+167
@@ -0,0 +1,167 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "pathlib" for Path
|
||||
|
||||
System.print("=== Pathlib Module Demo ===\n")
|
||||
|
||||
System.print("--- Path Construction ---")
|
||||
var p = Path.new("/home/user/documents/report.tar.gz")
|
||||
System.print("Path: %(p)")
|
||||
System.print("Name: %(p.name)")
|
||||
System.print("Stem: %(p.stem)")
|
||||
System.print("Suffix: %(p.suffix)")
|
||||
System.print("Suffixes: %(p.suffixes)")
|
||||
System.print("Parts: %(p.parts)")
|
||||
|
||||
System.print("\n--- Parent Navigation ---")
|
||||
System.print("Parent: %(p.parent)")
|
||||
System.print("Parents:")
|
||||
for (ancestor in p.parents) {
|
||||
System.print(" %(ancestor)")
|
||||
}
|
||||
|
||||
System.print("\n--- Path Properties ---")
|
||||
System.print("Root: %(p.root)")
|
||||
System.print("Anchor: %(p.anchor)")
|
||||
System.print("Is absolute: %(p.isAbsolute)")
|
||||
var rel = Path.new("relative/path.txt")
|
||||
System.print("%(rel) is absolute: %(rel.isAbsolute)")
|
||||
|
||||
System.print("\n--- Join Operator (/) ---")
|
||||
var base = Path.new("/home/user")
|
||||
var config = base / ".config" / "myapp" / "settings.json"
|
||||
System.print("%(base) / .config / myapp / settings.json = %(config)")
|
||||
|
||||
System.print("\n--- joinpath ---")
|
||||
var multi = Path.new("/opt").joinpath(["local", "bin", "wren_cli"])
|
||||
System.print("Joined: %(multi)")
|
||||
|
||||
System.print("\n--- withName / withStem / withSuffix ---")
|
||||
var orig = Path.new("/data/archive.tar.gz")
|
||||
System.print("Original: %(orig)")
|
||||
System.print("withName(\"backup.zip\"): %(orig.withName("backup.zip"))")
|
||||
System.print("withStem(\"snapshot\"): %(orig.withStem("snapshot"))")
|
||||
System.print("withSuffix(\".bak\"): %(orig.withSuffix(".bak"))")
|
||||
|
||||
System.print("\n--- relativeTo ---")
|
||||
var full = Path.new("/home/user/projects/wren/src/main.c")
|
||||
var project = Path.new("/home/user/projects/wren")
|
||||
System.print("%(full) relative to %(project) = %(full.relativeTo(project))")
|
||||
|
||||
System.print("\n--- Glob Matching ---")
|
||||
var file = Path.new("/tmp/notes.txt")
|
||||
System.print("%(file.name) matches *.txt: %(file.match("*.txt"))")
|
||||
System.print("%(file.name) matches *.md: %(file.match("*.md"))")
|
||||
System.print("%(file.name) matches note?: %(file.match("note?"))")
|
||||
System.print("%(file.name) matches n*s.txt: %(file.match("n*s.txt"))")
|
||||
|
||||
System.print("\n--- Home and CWD ---")
|
||||
System.print("Home: %(Path.home)")
|
||||
System.print("CWD: %(Path.cwd)")
|
||||
|
||||
System.print("\n--- Expand User ---")
|
||||
var tilde = Path.new("~/.bashrc")
|
||||
System.print("%(tilde) -> %(tilde.expanduser())")
|
||||
|
||||
System.print("\n--- Equality ---")
|
||||
var a = Path.new("/tmp/test")
|
||||
var b = Path.new("/tmp/test")
|
||||
var c = Path.new("/tmp/other")
|
||||
System.print("%(a) == %(b): %(a == b)")
|
||||
System.print("%(a) == %(c): %(a == c)")
|
||||
System.print("%(a) != %(c): %(a != c)")
|
||||
|
||||
System.print("\n--- Filesystem Operations ---")
|
||||
var testDir = Path.new("/tmp/wren_pathlib_demo")
|
||||
if (testDir.exists()) testDir.rmtree()
|
||||
|
||||
testDir.mkdir(true)
|
||||
System.print("Created: %(testDir)")
|
||||
System.print("Exists: %(testDir.exists())")
|
||||
System.print("Is dir: %(testDir.isDir())")
|
||||
|
||||
var testFile = testDir / "hello.txt"
|
||||
testFile.writeText("Hello from pathlib!")
|
||||
System.print("Wrote: %(testFile)")
|
||||
System.print("Content: %(testFile.readText())")
|
||||
System.print("Is file: %(testFile.isFile())")
|
||||
|
||||
System.print("\n--- Stat ---")
|
||||
var s = testFile.stat()
|
||||
System.print("Size: %(s.size) bytes")
|
||||
|
||||
System.print("\n--- Touch ---")
|
||||
var marker = testDir / "marker"
|
||||
marker.touch()
|
||||
System.print("Touched: %(marker) (exists: %(marker.exists()))")
|
||||
|
||||
System.print("\n--- Copy ---")
|
||||
var copy = testDir / "hello_copy.txt"
|
||||
testFile.copyfile(copy)
|
||||
System.print("Copied to: %(copy)")
|
||||
System.print("Copy content: %(copy.readText())")
|
||||
|
||||
System.print("\n--- Rename ---")
|
||||
var renamed = testFile.rename(testDir / "greeting.txt")
|
||||
System.print("Renamed to: %(renamed)")
|
||||
System.print("Old exists: %(testFile.exists())")
|
||||
System.print("New content: %(renamed.readText())")
|
||||
|
||||
System.print("\n--- Resolve ---")
|
||||
var resolved = Path.new(".").resolve()
|
||||
System.print("Resolved '.': %(resolved)")
|
||||
|
||||
System.print("\n--- Same File ---")
|
||||
System.print("Same file: %(renamed.samefile(renamed))")
|
||||
|
||||
System.print("\n--- Owner and Group ---")
|
||||
System.print("Owner: %(renamed.owner())")
|
||||
System.print("Group: %(renamed.group())")
|
||||
|
||||
System.print("\n--- Mkdir with Parents ---")
|
||||
var deep = testDir / "a" / "b" / "c"
|
||||
deep.mkdir(true)
|
||||
System.print("Created: %(deep)")
|
||||
System.print("Exists: %(deep.exists())")
|
||||
|
||||
System.print("\n--- Iterdir ---")
|
||||
(testDir / "file1.txt").writeText("one")
|
||||
(testDir / "file2.txt").writeText("two")
|
||||
var entries = testDir.iterdir()
|
||||
System.print("Entries in %(testDir.name):")
|
||||
for (entry in entries) {
|
||||
var kind = entry.isDir() ? "dir" : "file"
|
||||
System.print(" %(entry.name) (%(kind))")
|
||||
}
|
||||
|
||||
System.print("\n--- Glob ---")
|
||||
var txtFiles = testDir.glob("*.txt")
|
||||
System.print("Text files in %(testDir.name):")
|
||||
for (f in txtFiles) {
|
||||
System.print(" %(f.name)")
|
||||
}
|
||||
|
||||
System.print("\n--- Recursive Glob ---")
|
||||
(testDir / "a" / "nested.txt").writeText("nested")
|
||||
(testDir / "a" / "b" / "deep.txt").writeText("deep")
|
||||
var allTxt = testDir.rglob("*.txt")
|
||||
System.print("All text files (recursive):")
|
||||
for (f in allTxt) {
|
||||
System.print(" %(f.relativeTo(testDir))")
|
||||
}
|
||||
|
||||
System.print("\n--- Walk ---")
|
||||
System.print("Directory tree:")
|
||||
for (entry in testDir.walk()) {
|
||||
var dir = entry[0]
|
||||
var dirs = entry[1]
|
||||
var files = entry[2]
|
||||
var indent = dir == testDir ? "" : " "
|
||||
System.print("%(indent)%(dir.relativeTo(testDir))/ (%(dirs.count) dirs, %(files.count) files)")
|
||||
}
|
||||
|
||||
System.print("\n--- Cleanup ---")
|
||||
testDir.rmtree()
|
||||
System.print("Cleaned up: %(testDir) (exists: %(testDir.exists()))")
|
||||
|
||||
System.print("\n=== Demo Complete ===")
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
System.print("=== String Methods Demo ===\n")
|
||||
|
||||
System.print("--- Case Conversion ---")
|
||||
var text = "Hello World"
|
||||
System.print("Original: %(text)")
|
||||
System.print("lower: %(text.lower)")
|
||||
System.print("upper: %(text.upper)")
|
||||
System.print("capitalize: %("hello world".capitalize)")
|
||||
System.print("title: %("hello world".title)")
|
||||
System.print("swapCase: %(text.swapCase)")
|
||||
|
||||
System.print("\n--- Character Testing ---")
|
||||
System.print("\"hello\".isLower: %("hello".isLower)")
|
||||
System.print("\"HELLO\".isUpper: %("HELLO".isUpper)")
|
||||
System.print("\"12345\".isDigit: %("12345".isDigit)")
|
||||
System.print("\"hello\".isAlpha: %("hello".isAlpha)")
|
||||
System.print("\"hello1\".isAlphaNumeric: %("hello1".isAlphaNumeric)")
|
||||
System.print("\" \".isSpace: %(" ".isSpace)")
|
||||
System.print("\"hello\".isAscii: %("hello".isAscii)")
|
||||
|
||||
System.print("\n--- Search ---")
|
||||
var sentence = "hello world hello"
|
||||
System.print("Text: %(sentence)")
|
||||
System.print("lastIndexOf(\"hello\"): %(sentence.lastIndexOf("hello"))")
|
||||
System.print("lastIndexOf(\"hello\", 11): %(sentence.lastIndexOf("hello", 11))")
|
||||
|
||||
System.print("\n--- Transformation ---")
|
||||
System.print("\"hello\".reverse: %("hello".reverse)")
|
||||
System.print("\"hi\".center(10, \"-\"): %("hi".center(10, "-"))")
|
||||
System.print("\"42\".lpad(5, \"0\"): %("42".lpad(5, "0"))")
|
||||
System.print("\"hi\".rpad(5, \".\"): %("hi".rpad(5, "."))")
|
||||
System.print("\"42\".zfill(5): %("42".zfill(5))")
|
||||
System.print("\"-42\".zfill(6): %("-42".zfill(6))")
|
||||
|
||||
System.print("\n--- Prefix/Suffix ---")
|
||||
System.print("removePrefix(\"Hello\"): %("HelloWorld".removePrefix("Hello"))")
|
||||
System.print("removeSuffix(\"World\"): %("HelloWorld".removeSuffix("World"))")
|
||||
|
||||
System.print("\n--- Comparison ---")
|
||||
System.print("\"apple\" < \"banana\": %("apple" < "banana")")
|
||||
System.print("\"banana\" > \"apple\": %("banana" > "apple")")
|
||||
System.print("\"abc\" <= \"abc\": %("abc" <= "abc")")
|
||||
System.print("\"abc\" >= \"abc\": %("abc" >= "abc")")
|
||||
System.print("\"abc\" < \"abcd\": %("abc" < "abcd")")
|
||||
System.print("\"abcd\" > \"abc\": %("abcd" > "abc")")
|
||||
System.print("\"Z\" < \"a\": %("Z" < "a")")
|
||||
|
||||
var fruits = ["cherry", "apple", "banana"]
|
||||
System.print("Sorted: %(fruits.sort {|a, b| a < b})")
|
||||
|
||||
System.print("\n--- Splitting ---")
|
||||
var lines = "line1\nline2\nline3".splitLines
|
||||
System.print("splitLines: %(lines)")
|
||||
|
||||
var chars = "abc".chars
|
||||
System.print("chars: %(chars)")
|
||||
|
||||
System.print("\n--- Conversion ---")
|
||||
System.print("\"42\".toNum: %("42".toNum)")
|
||||
System.print("\"3.14\".toNum: %("3.14".toNum)")
|
||||
System.print("\"abc\".toNum: %("abc".toNum)")
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "tempfile" for TempFile, NamedTemporaryFile, TemporaryDirectory
|
||||
import "pathlib" for Path
|
||||
|
||||
System.print("=== TempFile Module Demo ===\n")
|
||||
|
||||
System.print("--- Utility Functions ---")
|
||||
System.print("Temp directory: %(TempFile.gettempdir())")
|
||||
System.print("Temp prefix: %(TempFile.gettempprefix())")
|
||||
|
||||
System.print("\n--- mktemp (name only, no file created) ---")
|
||||
var name = TempFile.mktemp(".txt", "demo_")
|
||||
System.print("Generated name: %(name)")
|
||||
System.print("File exists: %(Path.new(name).exists())")
|
||||
|
||||
System.print("\n--- mkstemp (creates file atomically) ---")
|
||||
var path = TempFile.mkstemp(".dat", "demo_")
|
||||
System.print("Created file: %(path)")
|
||||
System.print("File exists: %(Path.new(path).exists())")
|
||||
Path.new(path).unlink()
|
||||
|
||||
System.print("\n--- mkdtemp (creates directory) ---")
|
||||
var dir = TempFile.mkdtemp("_work", "demo_")
|
||||
System.print("Created directory: %(dir)")
|
||||
System.print("Is directory: %(Path.new(dir).isDir())")
|
||||
Path.new(dir).rmdir()
|
||||
|
||||
System.print("\n--- NamedTemporaryFile ---")
|
||||
var tmp = NamedTemporaryFile.new(".txt", "demo_")
|
||||
System.print("Temp file: %(tmp.name)")
|
||||
tmp.write("Hello from tempfile module!")
|
||||
System.print("Content: %(tmp.read())")
|
||||
System.print("Auto-delete: %(tmp.delete)")
|
||||
tmp.close()
|
||||
System.print("Deleted after close: %(!(Path.new(tmp.name).exists()))")
|
||||
|
||||
System.print("\n--- NamedTemporaryFile.use (context manager) ---")
|
||||
NamedTemporaryFile.new(".log").use {|f|
|
||||
f.write("Log entry: operation completed")
|
||||
System.print("Inside use block: %(f.read())")
|
||||
}
|
||||
System.print("Automatically cleaned up after use block")
|
||||
|
||||
System.print("\n--- TemporaryDirectory ---")
|
||||
var tmpDir = TemporaryDirectory.new("_session", "demo_")
|
||||
System.print("Temp dir: %(tmpDir.name)")
|
||||
System.print("Is directory: %(tmpDir.path.isDir())")
|
||||
tmpDir.cleanup()
|
||||
System.print("Deleted after cleanup: %(!(Path.new(tmpDir.name).exists()))")
|
||||
|
||||
System.print("\n--- TemporaryDirectory.use (context manager) ---")
|
||||
TemporaryDirectory.new().use {|d|
|
||||
System.print("Working in: %(d.name)")
|
||||
Path.new(d.name + "/data.txt").writeText("temporary data")
|
||||
System.print("Created file inside temp dir")
|
||||
}
|
||||
System.print("Automatically cleaned up with all contents")
|
||||
|
||||
System.print("\n=== Done ===")
|
||||
Reference in New Issue
Block a user