Tiny template renderer — substitute [[key]] placeholders
Fills each [[key]] in a template with its value. Keys and values are passed as two parallel lists (a Map *parameter* can't be key-iterated like a memory slot, so explicit lists are the portable idiom). We use square brackets because Soma string interpolation owns {curly} braces. Run: soma run template.cell --signal greet "Bob" "Paris"
A Soma program from the text part of the verified corpus: 43 lines, cells Template, TemplateTest. It passes soma check with soma 3.2.4.
How it is built
The cell Template declares 2 signals in its face: fill(tmpl: String, names: List<String>, vals: List<String>) -> String and greet(name: String, place: String) -> String. Handlers: fill (line 18) and greet (line 27).
The file also holds 1 test cell (TemplateTest) with 5 assertions, run by soma test.
The source
template.cell
// ============================================================================
// Tiny template renderer — substitute [[key]] placeholders
// ============================================================================
//
// Fills each [[key]] in a template with its value. Keys and values are passed
// as two parallel lists (a Map *parameter* can't be key-iterated like a memory
// slot, so explicit lists are the portable idiom). We use square brackets
// because Soma string interpolation owns {curly} braces.
//
// Run: soma run template.cell --signal greet "Bob" "Paris"
cell Template {
face {
signal fill(tmpl: String, names: List<String>, vals: List<String>) -> String
signal greet(name: String, place: String) -> String
}
on fill(tmpl: String, names: List<String>, vals: List<String>) {
let out = tmpl
for i in range(0, len(names)) {
let placeholder = "[[" + names[i] + "]]"
out = replace(out, placeholder, vals[i])
}
return out
}
on greet(name: String, place: String) {
return fill("Hello [[name]], welcome to [[place]]!",
list("name", "place"),
list(name, place))
}
}
cell test TemplateTest {
rules {
assert fill("Hi [[name]]", list("name"), list("Alice")) == "Hi Alice"
assert fill("[[a]]+[[b]]=[[c]]", list("a","b","c"), list("1","2","3")) == "1+2=3"
assert greet("Bob", "Paris") == "Hello Bob, welcome to Paris!"
assert fill("no placeholders", list("x"), list("9")) == "no placeholders"
assert fill("[[x]] [[x]]", list("x"), list("hi")) == "hi hi"
}
}What the toolchain says
$ soma check template.cell
✓ All checks passed.$ soma test template.cell
test TemplateTest ...
✓ assert fill("Hi [[name]]", list("name"), list("Alice")) == "Hi Alice"
✓ assert fill("[[a]]+[[b]]=[[c]]", list("a","b","c"), list("1","2","3")) == "1+2=3"
✓ assert greet("Bob", "Paris") == "Hello Bob, welcome to Paris!"
✓ assert fill("no placeholders", list("x"), list("9")) == "no placeholders"
✓ assert fill("[[x]] [[x]]", list("x"), list("hi")) == "hi hi"
5 tests: 5 passed, 0 failed$ soma verify template.cell
Verifying template.cell...
No state machine in this program: nothing to prove beyond `soma check` (invariants and lifecycles are what verify proves).
VERIFY OK (vacuous — no state machine)