Add context receiver extensions for DSLs

This commit is contained in:
sergeych committed 2026-04-29 20:49:50 +03:00
1 parent e107296bca
commit b2200e71ff
22 files changed
+860 -71

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
class Tag(name: String) {
val name = name
var inner = ""
fun child(tagName: String, block: Tag.()->void) {
val child = Tag(tagName)
with(child) { block(this) }
inner += child.render()
}
fun head(block: Tag.()->void) { child("head", block) }
fun body(block: Tag.()->void) { child("body", block) }
fun title(block: Tag.()->void) { child("title", block) }
fun h1(block: Tag.()->void) { child("h1", block) }
fun addText(text: String) {
inner += text
}
fun render() {
"<" + name + ">" + inner + "</" + name + ">"
}
}
context(Tag)
fun String.unaryPlus() {
this@Tag.addText(this)
}
fun html(block: Tag.()->void) {
val root = Tag("html")
with(root) { block(this) }
root.render()
}
val page = html {
head {
title {
+"Demo"
}
}
body {
h1 {
+"Heading 1"
}
}
}
println(page)
assertEquals("<html><head><title>Demo</title></head><body><h1>Heading 1</h1></body></html>", page)
+8
View File
@@ -1,6 +1,9 @@
// Sample: Operator Overloading in Lyng
class Vector<T>(val x: T, val y: T) {
// Overload unary +
fun unaryPlus() = this
// Overload +
fun plus(other: Vector<U>) = Vector(x + other.x, y + other.y)
@@ -28,6 +31,11 @@ val v2 = Vector(5, 5)
println("v1: " + v1)
println("v2: " + v2)
// Test unary +
val v0 = +v1
println("+v1 = " + v0)
assertEquals(Vector(10, 20), v0)
// Test binary +
val v3 = v1 + v2
println("v1 + v2 = " + v3)