The 10-Part LMScript Examples Book
Organized in progressive order from lmctl-mono/lmscript/examples/. Every example can be checked with
lmscript --check, linted with lmscript --lint, and executed directly.
Part I — First Steps, Variables, Lists & Maps
Covers basic output (println), arithmetic, booleans, 0-based lists (xs[0], negative indexing xs[-1]),
and key-value maps (m.key and m["key"]).
greeting = "Hello, LMScript!";
langs = ["lmscript", "lmcode", "lmaws"];
release = { version: "0.2.38", dslb: 6 };
println(greeting);
println("First: " + langs[0] + " | Last: " + langs[-1]);
println(f"Release {release.version} (DSLB v{release.dslb})");
Part II — Python-Style Strings, Regex Substrings, Stateful pos() Tokenizer & Path Literals
Demonstrates raw strings (r"..."), format strings (f"..."), triple-quoted blocks,
regex containment & substring extraction (regex_test, regex_find, regex_matches,
regex_match, regex_find_all, regex_replace), Perl-like stateful pos()
tokenizers (pos, set_pos, regex_find_pos, regex_match_pos, regex_test_pos),
and first-class paths.
# 1. Check if string matches (contains) pattern & extract 1 or more matched substrings
log = "2026-10-17 ERROR disk 91%\n2026-10-18 WARN cpu 72%\n2026-10-18 ERROR mem 88%";
println(regex_test(log, r"ERROR")); # true
println(regex_find(log, r"\d+%")); # "91%"
println(regex_matches(log, r"\d+%")); # ["91%", "72%", "88%"]
# 2. Stateful Perl-like pos() tokenizer over a list of [kind, pattern] rules
const RULES = [
["WS", r"\s+"],
["NUMBER", r"\d+(?:\.\d+)?"],
["IDENT", r"[A-Za-z_][A-Za-z0-9_]*"],
["OP", r"==|!=|<=|>=|[+\-*/=()<>]"],
["SEMI", r";"]
];
fn tokenize(src) {
pos(src, 0);
let tokens = [];
while (pos() < len(src)) {
let start = pos();
let matched = false;
for (rule in RULES) {
let text = regex_find_pos(src, rule[1]);
if (text != null) {
if (rule[0] != "WS") { push(tokens, { kind: rule[0], text: text, at: start }); }
matched = true;
break;
}
}
if (!matched) {
return { ok: false, error_pos: pos(), rest: slice(src, pos()) };
}
}
return { ok: true, tokens: tokens, final_pos: pos() };
}
res = tokenize("total = 42 + tax_rate * 10.5;");
println(f"tokens={len(res.tokens)} final_pos={res.final_pos}");
Part III — Control Flow, Loops & Functions
Covers if (...) { ... } else if (...) { ... } else { ... }, for (v in xs) { ... },
for (k in map) { ... } (map keys), numeric for (i = 0; i < 10; i = i + 1),
while, and higher-order functions (functions are declared at top level and passed as values; there are no nested closures).
# Part III — Functions, Recursion, Higher-Order Functions & Loops
fn double(x) {
return x * 2;
}
fn apply_twice(f, val) {
return f(f(val));
}
results = [];
for (i = 1; i <= 4; i = i + 1) {
push(results, apply_twice(double, i));
}
println("Sequence: " + json_stringify(results));
Part IV — Embedded Data Blocks (_json_, _csv_, _toml_, _props_, _graphql_)
Data blocks are validated at parse/check time and produce opaque Data for JSON, CSV, and TOML (use .value() for native values); props produces a map and GraphQL produces text.
endpoints = _csv_ heading=true;
name,method,path
health,GET,/healthz
deploy,POST,/v1/deploy
end _csv_
for (ep in endpoints.value()) {
println(f"{ep.method} {ep.path} ({ep.name})");
}
Part V — File System, _cmd_ Blocks & Process Execution
Safe command execution with _cmd_ argv blocks, system(...) status inspection,
system(argv) output capture, and dry-run-aware file mutations.
ver_cmd = _cmd_;
lmscript --version
end _cmd_
res = system(ver_cmd);
println("Exit: " + str(res.code) + " | Output: " + trim(res.stdout));
Part VI — Forward Templates (expand) & Reverse Templates (template_extract)
Render config files and prompts with expand(tpl, map), and invert the same template to extract text
fields back out of logs or command output with template_extract_text(tpl, text).
# Part VI — Forward expand() and Reverse template_extract_text() / template_extract()
tpl = "site=${site};env=${env};end";
line = expand(tpl, {site: "lmscript.io", env: "prod"});
println("Rendered : " + line);
rev = template_extract_text(tpl, line);
require(rev.matched, "expected reverse template text match");
println("Extracted : " + json_stringify(rev.value));
rows = template_extract([{kind: "host", name: "$name"}], [
{kind: "host", name: "lmaws"},
{kind: "skip", name: "none"},
{kind: "host", name: "lmcad"}
]);
println("Projected : " + json_stringify(rows.value));
Part VII — SQLite Databases, HTTP Client & XML/HTML Parsing
Query local SQLite files with literal SQL and bound parameters, fetch text via http_get,
and inspect _xml_ Data using xml_select.
# Part VII — SQLite with a temporary local database
db = temp_file();
sql_exec(db, "CREATE TABLE hosts (name TEXT, lang TEXT)");
sql_exec(db, "INSERT INTO hosts VALUES (?, ?), (?, ?)", ["lmaws", "java", "lmcad", "cpp"]);
rows = sql_read(db, "SELECT name, lang FROM hosts ORDER BY name");
delete_file(db);
println(json_stringify(rows));
Part VIII — Modules (import), Packages & CLI PROPS
Structure multi-file toolchains using import, and CLI PROPS / --pref definitions.
Part IX — Reliability: recover, resumepoint & parallel_map
Select explicit recover / resumepoint entries when rerunning a script, reload any needed
application state explicitly (recovery saves no state and catches no errors), and fan out work across concurrent workers.
Part X — Embedded _lmcode_ Bytecode Hosts & Unified AI Agents
Compile statically typed _lmcode_ blocks to DSLB v6 bytecode, execute them via run_lmcode,
and coordinate multi-turn AI coding agents with agent_open and agent_turn.
Catalog of 58 Core LMScript Example Scripts
The 58 scripts in the main reading sequence from lmctl-mono/lmscript/examples/index.md, in book order. The separate xml_tree.lms example is linked at the end of that repository book. The Part column follows the core sequence: 1 Basics, 2 Data, 3 Text, 4 Files, 5 Processes, 6 Agents, 7 Concurrency & recovery, 8 Checking & tracing, 9 Modules & data blocks (Part 10 is the reference and language comparisons).
| # | Part | Script Name | Core Feature Demonstrated |
|---|---|---|---|
| 1 | Part 1 | hello.lms | The smallest script: variables, println, an f-string; every statement ends with ; |
| 2 | Part 1 | values_and_scope.lms | Six value kinds, strict ==, truthiness, block-owned names, function-local assignment |
| 3 | Part 1 | control_flow.lms | if / else if / else, while, counted for, for (x in list|map|string), break, continue, cond ? a : b |
| 4 | Part 1 | functions.lms | fn with hoisting and recursion, functions as values, let (a, b) = [1, 2]; |
| 5 | Part 1 | config_consts.lms | Top-level const bindings spliced with ${} into _lmcode_ blocks; frozen lists/maps and clone() |
| 6 | Part 1 | strict_access_methods.lms | Missing keys/indices are errors; m.get(key, default), m.has(key), .len(), .keys() |
| 7 | Part 1 | errors_and_exit.lms | require, assert, warning, exit(code) on the passing path |
| 8 | Part 1 | errors_and_exit_failing.lms | error(...) records and continues, failing the run with exit 1 at the end |
| 9 | Part 1 | argv.lms | Everything after the script name is data in ARGV (alias args) |
| 10 | Part 2 | inline_data.lms | json_parse, csv_parse, csv_stringify on raw triple-quoted text |
| 11 | Part 2 | 01_dsl_heredoc.lms | Raw and dedented _lmcode_ heredoc strings preserving UTF-8, quotes and interpolation-looking text |
| 12 | Part 2 | lists.lms | Negative indexing, mutating helpers and their return values, sort/unique/zip/chunk/range/enumerate, clone() |
| 13 | Part 2 | maps_and_json.lms | keys/values/entries, merge, delete_key, nested set(), json_parse/json_stringify, json_parse_safe, pluck/filter_by/find_by |
| 14 | Part 2 | math_and_predicates.lms | abs/ceil/floor/round/sqrt/pow/min/max/clamp, is_* predicates, if_null/coalesce, getstr/getnum/getbool/getlist |
| 15 | Part 3 | strings.lms | Quoting forms (raw r"...", triple), trim/split/join/replace/pad/substring/char_at, UTF-16 units vs code points |
| 16 | Part 3 | formatting.lms | f-strings, format("{} {name}"), sprintf/printf with width and precision |
| 17 | Part 3 | regex.lms | regex_test, regex_find, regex_matches, regex_match, regex_find_all, regex_replace with $1, split_regex, stateful pos() |
| 18 | Part 3 | regex_tokenizer.lms | Perl-like stateful pos() + regex_find_pos lexer over an ordered list of [kind, pattern] rules |
| 19 | Part 3 | expand.lms | expand() resolves ${name} from a vars map, ${PROPS.path} and ${ARGV[n]} |
| 20 | Part 3 | reverse_templates.lms | template_extract tree projection and row filtering, template_extract_text exact text holes, match envelopes |
| 21 | Part 3 | agent_reply_helpers.lms | last_line_as_status, kv_from_last_paragraph, parse_file_blocks/format_file_blocks, write_files, read_tree, split_command |
| 22 | Part 4 | files.lms | Text, lines, JSON and CSV read/write, append, mkdir/list_dir/glob, copy/move/delete, path helpers, temp_file |
| 23 | Part 4 | files_more.lms | write_file_exclusive, remove_file, rmdir, clear/size on a map |
| 24 | Part 4 | path_literals.lms | path"..." literals: the written path in OS form, with no filesystem lookup |
| 25 | Part 4 | env_and_time.lms | env/set_env/getenv, which, now/timestamp/date/strftime, sleep_ms |
| 26 | Part 5 | commands.lms | cmd COMMAND argv construction, system(argv, timeout) with no shell, cmd_render quoting |
| 27 | Part 5 | system_results.lms | {stdout, stderr, code, signal, timed_out, duration_ms, pid}, timeouts, {cwd, timeoutMs, stdin} options |
| 28 | Part 5 | cmd_blocks.lms | Multi-line _cmd_ argv blocks with ${} fields, run with system(...) |
| 29 | Part 5 | run_script.lms | run_script runs another script in-process: {success, exit_code, stdout, output, value, errors} |
| 30 | Part 5 | run_script_child.lms | The child script launched by run_script.lms (its own ARGV and output) |
| 31 | Part 6 | agents_offline_mock.lms | Teamfile, lm_lint, lm_seed, lm_members, lm_prompt, lm_batch_* result shapes, offline with ClaudeMock |
| 32 | Part 6 | agent_unified.lms | Unified agent host offline: agent_providers, agent_open, agent_turn, agent_info, agent_history, agent_close |
| 33 | Part 6 | agent_observe.lms | lm_running, lm_ratelimit_readings, lm_terminal, prompt_human_config |
| 34 | Part 6 | book_live.lms | Shared helpers imported by the live agent examples |
| 35 | Part 6 | agent_prompt.lms | Live: one agent_prompt({provider, model}, prompt) with session_id, token buckets and price |
| 36 | Part 6 | agent_teamfile.lms | Live: write a teamfile, lm_lint, lm_seed, lm_members, lm_prompt(teamfile, alias, prompt) |
| 37 | Part 6 | agent_fanout.lms | Live: parallel_map around agent_prompt sends one prompt to several agents concurrently |
| 38 | Part 6 | batchscript.lms | Live: batch over a teamfile with lm_read_prompts, lm_batch_open, lm_batch_turn, lm_batch_close |
| 39 | Part 6 | llm_classify.lms | Live: one-shot llm_prompt classification with validated JSON output |
| 40 | Part 6 | llm_agent.lms | Live: multi-turn shell agent with session history and restricted tool calling over llm_prompt |
| 41 | Part 6 | tool_agent.lms | Live: workspace agent built from tool_specs, tool_parse, tool_call and llm_prompt |
| 42 | Part 6 | providers_check.lms | Live: iterate llm_providers(), discover llm_models(), test completions |
| 43 | Part 7 | recover_steps.lms | recover { resumepoint NAME: ... }, RESUMEPOINT, --resumepoint PATH |
| 44 | Part 7 | resource_batch.lms | A resource handle closes automatically when its owning scope exits |
| 45 | Part 7 | resource_escape.lms | A resource handle cannot escape the function that owns it |
| 46 | Part 7 | resource_signal.lms | Resource handles are released on SIGINT/SIGTERM |
| 47 | Part 7 | parallel_sync.lms | parallel([f(), g()]) with ordered results and sync x = ... binding locks |
| 48 | Part 7 | parallel_map.lms | parallel_map(items, fn[, limit]) bounded fan-out (default 8, maximum 64) |
| 49 | Part 8 | checking_and_dry_run.lms | --check, --lint, --dry-run PLAN output and --check-files |
| 50 | Part 8 | trace.lms | lmscript --trace FILE JSON Lines execution traces, summarized by event kind |
| 51 | Part 9 | git_summary.lms | Git through system(["git", ...]) argv; check and dry-run launch no process |
| 52 | Part 9 | github_query.lms | The gh source module: import "../modules/gh.lms"; and gh.gh_graphql(query, vars) |
| 53 | Part 9 | graphql_query.lms | A checked _graphql_ block passed as one argv element |
| 54 | Part 9 | imports_and_packages.lms | import "file.lms"; and package NAME; files exposing NAME.member |
| 55 | Part 9 | book_greetings.lms | The package file imported by imports_and_packages.lms |
| 56 | Part 9 | data_blocks_csv_json.lms | _csv_ and _json_ blocks with per-value ${expr} substitution after parsing |
| 57 | Part 9 | data_blocks_toml_props.lms | _toml_ (TOML 1.0) and _props_ (Java .properties) blocks |
| 58 | Part 9 | properties_and_pref.lms | PROPS, has_property, get_property, get_properties, set_property, --pref FILE overlay |