Commit graph

41 commits

Author SHA1 Message Date
John Kerl
1004ba5097
DSL format function: support 1-based positional placeholders like {1} (#1650) (#2160)
Plain {} placeholders consume arguments sequentially as before; {N}
refers to the Nth argument (1-based) and may be used to repeat and/or
reorder arguments, e.g. format("{1}/{2}/{1}_{3}.ext", $p1, $p2, $p3).
Mixing is allowed: the {} sequence counter is independent of positional
placeholders (as in Rust format!). Out-of-range indices interpolate the
empty string, consistent with existing too-few-arguments behavior; {0}
is an error value since indices are 1-based.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:15:33 -04:00
John Kerl
12c96298b9
Add a first-class bytes type to the DSL, with b"..." literals and base64/hex codecs (#2122)
* Add MT_BYTES mlrval type: foundation and disposition tables

First step toward a first-class bytes type in the DSL (#1231).
Adds MT_BYTES (payload []byte, rendered as lowercase hex in all output
formats, JSON-encoded as a hex string), extends every disposition
matrix/vector with the new row/column -- real cells for comparison,
sorting, and dot-concat of bytes with bytes; type-error stubs
elsewhere -- and adds sweep tests asserting no table has nil cells,
since Go zero-fills short array literals when MT_DIM grows.

Bytes values are not yet constructible from the DSL; b"..." literals
and constructor/codec functions follow in subsequent commits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add b"..." bytes-literal syntax to the DSL

Adds a bytes_literal token to the grammar (regenerating the PGPG lexer
and parser) and a BytesLiteralNode in the CST which evaluates to an
MT_BYTES mlrval. Escape handling reuses UnbackslashStringLiteral,
which is already byte-oriented: b"\xff" is the single byte 0xff.
Unlike string literals, bytes literals never participate in
regex-capture replacement. A bare identifier b is unaffected.

Part of #1231.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add bytes DSL functions: conversions, codecs, and bytes-aware built-ins

- bytes(x) converts strings to bytes; string(b) reinterprets raw bytes
  as UTF-8 text (the reverse)
- base64_decode now always returns bytes (superseding the interim
  string-or-hex behavior); base64_encode accepts string or bytes
- New hex_encode/hex_decode functions
- is_bytes and asserting_bytes predicates
- md5/sha1/sha256/sha512 accept bytes, hashing the raw payload
- strlen of bytes is the byte count; substr/substr0/substr1 on bytes
  slice by byte position and return bytes

The Cyrillic-LDAP scenario from #1231 now works without exec
workarounds: string(base64_decode($x)) recovers the text, and binary
payloads survive undamaged as bytes.

Closes #1231.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add bytes-type docs and regression cases

Documents the bytes type on the data-types page, regenerates the
function-reference/man-page material, and adds regression coverage:
literal escape forms, operators (concat/compare/slice/sort and
type errors), conversions and codec round-trips, and CSV-to-JSON
output rendering of bytes fields.

Part of #1231.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Reposition MT_BYTES to sort adjacent to MT_STRING in the type enum

MT_BYTES was appended after MT_ABSENT for index stability; move it
right after MT_STRING instead, since that's where it conceptually
belongs and where it already sorts in the cmp disposition matrices.
Mechanically re-derive all ~40 disposition tables in pkg/bifs and
pkg/mlrval accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix windows CI

* fix merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 11:58:44 -04:00
John Kerl
91eaff1341
Lint round 5+6: staticcheck and errcheck to zero (#2130)
* refine the plan

* Fix all staticcheck lint findings (uncapped)

golangci-lint's default max-same-issues=3 was hiding most of the backlog:
the true pre-fix count was 69 staticcheck findings, not 34. This fixes all
of them, driving staticcheck to zero:

- ST1023/QF1011 (37): omit explicit types inferred from the RHS
- S1009/S1031 (15): drop redundant nil checks before len()/range
- SA9003 (9): remove comment-only empty branches, keeping the comments
- QF1007 (3): merge conditional assignment into declaration
- QF1006 (3): lift break conditions into loop conditions
- QF1001 (3): apply De Morgan's law / name the negated predicate

Also updates plans/lintfixes.md with the cap discovery and the corrected
errcheck picture (1202 uncapped, ~949 of them fmt.Fprint*).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Drive errcheck to zero: config for bulk categories, propagate real errors

Adds .golangci.yml with errcheck exclude-functions for fmt.Fprint* (usage
printers), (*bufio.Writer).Write/WriteString (sticky errors, surfaced at the
now-checked final Flush), and (*strings.Builder).WriteString; pins
max-issues-per-linter/max-same-issues to 0 so CI reports true counts.

Real error paths now propagate instead of being dropped:
- Finalize{Reader,Writer}Options in join/put/filter/split/tee and the
  repl/script entry points: 'mlr join -i badformat' now errors instead of
  silently using wrong separators
- final output-stream Flush in pkg/stream: write failure no longer exits 0
- DSL emit/print/dump redirect writes, matching their sibling branches
- CSV writer WriteCSVRecordMaybeColorized, close-time Flush in file output
  handlers, ENV[...] Setenv, REPL record-write and redirect-close errors
- termcvt write-side Close before rename (had "TODO: check return status")

The rest are deliberate ignores, marked with _ = and a comment where the
reason isn't obvious: unset-of-missing-path no-ops, read-side closes,
mid-stream FlushOnEveryRecord, init-time strftime registrations, in-memory
usage-capture pipes, and regtest-harness env/temp-file teardown.

golangci-lint now reports 0 issues on ./cmd/mlr ./pkg/... with all caps off.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 11:42:08 -04:00
John Kerl
d56eafff97
Convert if/else-if chains to typed switch statements (staticcheck QF1003) (#2112)
Replaces 100+ if/else-if chains on a single variable with tagged switch
statements across 72 files. The bulk are transformer option-parsing loops
(switch on opt string), plus a handful of value-dispatch sites in mlrval,
dsl/cst, repl, lib, auxents, and bifs. One case (surv.go) required a
labeled break to preserve the loop-exit behavior of the original else branch.

Fixes staticcheck QF1003 findings.

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-06-28 18:27:42 -04:00
John Kerl
7e1c9b4119
Next batch of lint fixes (#2108) 2026-06-28 17:36:36 -04:00
John Kerl
6f1b3958ed
Switch to --as-json (#2106) 2026-06-28 17:04:10 -04:00
John Kerl
2dd94cb181
Add machine-readable help catalog: mlr help --json (#2098) (#2099)
Emit Miller's existing help catalog (verbs, functions, flags, keywords)
as structured JSON so AI agents and tooling can model Miller's surface
without scraping prose. The --json token may appear anywhere on a
`mlr help ...` command line; plain text help is unchanged.

  mlr help --json                  # full catalog
  mlr help verb cat --json         # one or more verbs
  mlr help function splitax --json # one or more functions
  mlr help flag --ifs --json       # one or more flags
  mlr help keyword ENV --json      # one or more keywords

Functions and flags serialize fully (name/class/arity/help/examples;
section/name/alt_names/arg/help). Verbs carry a summary, ignores_input,
and captured raw usage_text as a Tier-1 fallback, since per-verb options
are prose-only today (each verb hand-writes its UsageFunc). Structured
verb options are a planned follow-on (see #2098).

This is a serialization layer over the existing registries -- no
refactor of the text-help path.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 16:55:54 -04:00
John Kerl
299636038c
Shell tab-completion for bash and zsh (#2096)
* initial attempt

* fix bash

* fix zsh

* Add shell-completion docs page

Documents the new 'mlr completion {bash,zsh}' feature: the then-chain
context model, install instructions for bash and zsh (including the macOS
bash-3.2 'eval' caveat and zsh compinit self-init), and examples of
context-aware completion. Added to the nav under "Miller in more detail".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add enum value completion for format and separator flags

Completes the argument value for arg-taking main flags whose values are a
known set: file-format names for -i/-o/--io, separator aliases for
--ifs/--ofs/--ips/etc., and regex-separator aliases for --ifs-regex/--ips-regex.
Other arg-taking flags continue to fall back to filename completion.

Candidate sets come from new cli getters (GetFileFormatNames,
GetSeparatorAliasNames, GetSeparatorRegexAliasNames) that read the same maps
Miller uses at runtime, so there is no separate list to keep in sync. The
command-line walk now records which flag a value position belongs to.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Include format-conversion keystroke-savers in bare-dash completion

Reverts the suppression of --c2j/--x2y-style flags from 'mlr -<TAB>'. The full
set of main flags (297) is now offered, matching what is valid on the command
line. GetFlagNames no longer takes an includeSuppressed argument.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Complete terminal subcommands and top-level help/version flags

'mlr <TAB>' now offers subcommand names (help, version, repl, regtest, script,
completion, terminal-list) alongside verb names, and 'mlr -<TAB>' offers the
top-level terminal flags (-h, --help, --version, --bare-version, and the help
shorthands -g/-l/-L/-f/-F/-k/-K). Subcommand names are offered only as the
first non-flag token, where they are valid.

To let the completion engine know these names without an import cycle
(pkg/terminals imports pkg/terminals/completion), the canonical terminal names
and version-flag spellings are factored into a new leaf package
pkg/terminals/registry, imported by pkg/terminals, pkg/climain, and completion.
The help-flag spellings come from a new help.GetTerminalFlagNames derived from
the existing shorthand table, so nothing drifts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Complete 'mlr help' topics and topic arguments

'mlr help <TAB>' now completes help topics (flags, verb, function, keyword,
list-verbs, ...), and topics that take a name argument complete it too:
'mlr help verb <TAB>' -> verb names, 'mlr help function <TAB>' -> function
names, 'mlr help keyword <TAB>' -> keyword names, 'mlr help flag <TAB>' ->
flag names. 'mlr completion <TAB>' completes bash/zsh.

A terminal subcommand consumes the rest of the command line, so the walk now
returns a ctxTerminalArgs context carrying the terminal name and the words
typed after it. New getters supply the candidate names without drift:
help.GetTopicNames, help.GetFunctionNames/GetKeywordNames (wrapping new
cst.BuiltinFunctionManager.GetBuiltinFunctionNames and cst.GetKeywordNames).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs-neaten

* Move flag-value-candidate logic into pkg/cli; fix verb-flag collision

The mapping of which flags take a format/separator/regex-separator argument is
flag metadata, so it now lives with the flags in pkg/cli as
cli.FlagValueCandidates, alongside the existing GetFileFormatNames /
GetSeparatorAliasNames getters, replacing the maps that were in
pkg/terminals/completion/value_completion.go (now removed).

This also fixes a bug: value completion now applies only to main flags, not to
identically-spelled verb flags. Previously 'mlr uniq -o <TAB>' offered file
formats because uniq's -o (an output field name) collided with the main -o
format flag; it now correctly falls back to filename completion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 12:47:54 -04:00
John Kerl
c5c32a68d2
Drop redundant deep-copy of UDF return values (~3-16% perf on UDFs in mlr put) (#2089)
* Batch-allocate per-record objects; reuse CSV writer field buffer

After batch-arena field allocation, profiling cat over 1M-record CSV showed
the remaining ~5M allocations were almost entirely per-record (one each):
the Mlrmap struct, the RecordAndContext wrapper, the CSV writer's []string,
and the go-csv parser's own buffers.

Address the first three:

- mlrval.RecordArena gains NewRecord(), vending the Mlrmap struct itself from
  a per-batch slab (respecting --no-hash-records). Rolled out to every
  line-based reader (CSV, CSV-lite, TSV, DKVP, NIDX, PPRINT, XTAB, DKVPX) in
  place of NewMlrmapAsRecord.

- The CSV reader batch-allocates RecordAndContext wrappers from a per-batch
  slab instead of one heap object per record (comment/output-string entries
  still allocate individually, but they are rare).

- RecordWriterCSV reuses a single fieldsBuffer []string across records instead
  of allocating one per Write; WriteCSVRecordMaybeColorized consumes it
  synchronously and the writer is single-goroutine, so this is safe.

Effect (big.*, 1M records, cat, best of 5):
  csv   0.26 -> 0.22
  dkvp  0.51 -> 0.45  (Mlrmap slab)

For CSV, cat's allocation-object count drops ~5.0M -> ~2.1M. The remaining
~2M are the go-csv parser's per-record backing string and field slice, which
are intrinsic to parsing and would require a zero-copy/batch-slab parser
rework. A CPU profile of cat now shows it is I/O-bound (syscall ~56%, bufio
read+flush), with allocation/GC down to ~10% -- i.e. further allocation
trimming no longer moves cat's wall-clock. GOGC=off confirms (no change).

Verified: go test ./pkg/... and full regression suite pass; output is
byte-identical across all formats including record-retaining verbs (tac),
hashed and --no-hash-records.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Pool DSL stack frames across records (~8-9% on put)

A StackFrameSet lives on the persistent runtime.State and is reused across
all records, but every block entry (StatementBlockNode.Execute does
PushStackFrame/PopStackFrame, which runs once per record for the main block,
plus once per if/for/etc.) allocated a fresh StackFrame -- a []*var slice and
a map[string]int -- and discarded it on exit. For `put`/`filter` that is
millions of throwaway allocations.

Since push/pop is strictly LIFO, retain popped frames in a per-frameset free
list and clear-and-reuse them on the next push. After the first record
establishes the max block-nesting depth, per-record block execution is
allocation-free for frames. len(stackFrames) remains the logical depth, so
get/set/defineTyped/unset/etc. are unchanged.

Measured (big.csv, 1M rows, best of 4):
  put  chain-1  0.78 -> 0.72  (~8%)
  put  chain-4  0.96 -> 0.87  (~9%)

Allocation objects for put chain-1 drop ~23.1M -> ~20.0M (the per-record
newStackFrame churn, ~2.86M, is eliminated). UDF calls still allocate a fresh
frameset per call (PushStackFrameSet); pooling those is a separate change.

The dominant remaining DSL allocator is FromFloat (~6.8M, interior arithmetic
temporaries); eliminating it needs node-owned result slots + in-place bif
variants, a much larger and aliasing-sensitive change, left for follow-up.

Verified: go test ./pkg/... and full regression suite pass; put output is
byte-identical, including UDFs with locals/loops/blocks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Pool DSL stack-frame *sets* across UDF/subr calls (~31% on function-heavy put)

Companion to the per-block frame pooling: that left PushStackFrameSet /
PopStackFrameSet (entered once per user-defined function or subroutine call)
allocating. Each call did newStackFrameSet() -- a StackFrameSet plus its
initial StackFrame (a slice and a map) -- AND, worse, prepended it with
append([]*StackFrameSet{head}, sets...), allocating a fresh backing slice and
copying the whole save-stack every call.

Two changes:
  - Treat the frameset save-stack as a tail stack (append to push, truncate to
    pop) instead of prepending at index 0. get/set only ever touch the cached
    head, so list order is irrelevant; this removes the per-call slice
    realloc + O(depth) copy.
  - Pool popped framesets (LIFO) and reset-and-reuse them on the next push,
    mirroring the per-frameset frame free list. A reset trims back to one
    cleared base frame (extras go to the frame pool). After warmup, repeated
    calls allocate no framesets or frames.

Measured (big.csv, 1M rows, best of 5):
  put, 2 nested func calls/record:  2.73 -> 1.87  (~31%)
GC cycles 25 -> 16; newStackFrameSet/newStackFrame fall out of the allocation
profile entirely. (chain-1 etc. have no UDFs and are unaffected.)

Verified: go test ./pkg/... and full regression suite pass; recursion
(fact/fib), local-scope isolation, and subroutine+oosvar all correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Drop redundant deep-copy of UDF return values (~3-16% on UDF put)

A user-defined function's return value was deep-copied twice on the way out:
once in ReturnNode.Execute (returnValue.Copy() when building the block-exit
payload) and again in UDFCallsite.EvaluateWithArguments
(blockReturnValue.Copy() at the end).

The ReturnNode copy is the necessary one: it detaches the value from the
callee's frame so it survives the frame being popped (and, since perf-try-7,
pooled/reused). By the time EvaluateWithArguments returns, blockReturnValue is
therefore already an independent deep copy, so the second copy is pure waste --
and callers that retain the result copy again anyway (field/oosvar/local
assignment all PutCopy/Copy). The other return paths (implicit-absent, error)
don't use blockReturnValue, so this only affects the BLOCK_EXIT_RETURN_VALUE
path.

Return blockReturnValue directly.

Measured (big.csv, 1M rows, best of 5):
  put, 2 nested scalar-returning calls/record:  1.89 -> 1.83  (~3%)
  put, map-returning func per record:           2.34 -> 1.97  (~16%)
Win scales with return-value size (the avoided copy is deep). All UDF/HOF
callsites (apply/reduce/sort/select/fold/...) go through this path.

Verified: go test ./pkg/... and full regression suite pass; recursion, HOFs,
and returned-map isolation (mutating a returned map does not affect a
subsequent call) all correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 17:05:16 -04:00
John Kerl
1bb9ba12c2
Fix mlr -s shebang doc and reject arrays/maps in contains/index (#1658) (#2058)
The shebang example `#!/usr/bin/env mlr -s` does not work on Linux
because env(1) does not accept arguments to the interpreter; use
`#!/usr/bin/env -S mlr -s` instead.

`contains` and `index` previously stringified their inputs silently,
so `contains([1,2], $foo)` would match against the literal string
`[1, 2]` and produce surprising results. Both now return a type-error
when either argument is an array or map; help text points users at
`any(arr, func(e){return e == x})` for membership tests.
2026-05-17 11:40:39 -04:00
Balki
c88142a9e2
Add hasvalue builtin function (#2026) 2026-04-08 08:33:12 -04:00
John Kerl
af1adf80ad
Replace GOCC parser-generator with PGPG (#2015)
* Porting

* Update some tests that depend on AST-print output

* iterating on GOCC -> PGPG

* iterating

* iterating

* iterating

* iterating

* iterating

* Modify expout files that need only AST-print-syntax updates

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* sync test cases from mlr-6.17.0, except AST-prints ...

* sync test cases from mlr-6.17.0, except AST-prints ...

* Fix lashed emit for $* and @*

* Fix --1 and ++1 chained unary ops

* Emit with function callsite

* test cases

* dot operator

* M_PI and M_E

* Iterating on lashed emit cases

* error-wording differences

* rm some should-fail files

* Fix issue with leading semicolon

* trailing comma in func params; most AST-print deltas

* error-wording delta

* fix unset all

* AST-print deltas

* go mod tidy: forced `go 1.25` to `go 1.25.0`

* Depend on PGPG v1.0.0

* Fix Windows CI failure

* Remove cmd/experiments/dsl_parser

* GOCC -> PGPG

* neaten

* Fix regex issue found in doc gen
2026-03-15 22:28:57 -04:00
John Kerl
f8a8f29584
Experiment with mlr script (#2009) 2026-03-05 20:14:32 -05:00
John Kerl
d0079a9dac
Simplify positional-indexing syntax in mlr.bnf; push logic to .go source (#2008)
* Move `$[[...]]` and `$[[[...]]]` out of the grammar and into Go

* Update pkg/parsing/mlr.bnf

* Update Go source

* update test files

* Fix NPE

* .gitignore

* more
2026-03-04 21:48:09 -05:00
John Kerl
f60314daaf
Update performance docs (#1991)
* Organize perf-stats runs

* reorg

* scripts/perf/timings-2026-02-22.txt

* iterating

* iterating

* more

* .gitignore

* more

* link checks
2026-02-22 17:04:35 -05:00
Stephen Kitt
f0a7c5832f
Performance and style fixes (#1981)
* Switch to integer ranges in for loops

Signed-off-by: Stephen Kitt <steve@sk2.org>

* Switch to slices functions where appropriate

A number of utility functions can be replaced outright; since Miller
can technically be used as a library, these are deprecated rather than
removed. go:fix directives ensure that they can be replaced
automatically.

Signed-off-by: Stephen Kitt <steve@sk2.org>

* Switch to reflect.TypeFor

This is slightly more efficient than TypeOf when the type is known at
compile time.

Signed-off-by: Stephen Kitt <steve@sk2.org>

* Switch to strings.SplitSeq instead of strings.Split

SplitSeq results in fewer allocations.

Signed-off-by: Stephen Kitt <steve@sk2.org>

* Drop obsolete build directives

Signed-off-by: Stephen Kitt <steve@sk2.org>

* Use min/max instead of explicit comparisons

Signed-off-by: Stephen Kitt <steve@sk2.org>

* Append slices instead of looping

Signed-off-by: Stephen Kitt <steve@sk2.org>

---------

Signed-off-by: Stephen Kitt <steve@sk2.org>
2026-02-18 09:19:31 -05:00
John Kerl
45d2104771
No exit from mlr repl when function is not found (#1976) 2026-02-16 17:07:22 -05:00
John Kerl
5eb40c9e7b
Multiple style updates (#1974)
* Comment style

* IRecordTransformer -> RecordTransfomer

* make fmt

* else-return style mod

* snake-case -> camel-case

* Remove redundant err = nil and similar zero-value initializations.

* redundant break;

* bugfix

* neaten

* typofix

* simplify/standardize init of zero-length slices

* Standardize fmt.Fprintf w/ errors

* fix double print of "mlr:"

* neatening

* Uniformize error messages

* make docs

* avoid shadowing package names

* shorten some receiver names
2026-02-16 15:49:21 -05:00
John Kerl
a3b5d25933
Neaten some comments (#1973)
* comment-neaten

* comment-neaten

* more
2026-02-16 13:38:49 -05:00
John Kerl
7da6f1453d
Replace list.List with Go slices (#1950)
* Add .vscode to .gitignore

* Replace `list.List` with slices
2026-02-01 17:22:28 -05:00
John Kerl
143ff7e20d
Deadstrip (#1947) 2026-02-01 15:44:08 -05:00
John Kerl
ced5e43065
Simplify the internal AST API (#1946)
* Simplify the internal AST API

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating, bisecting

* mlr.bnf neatens

* update old/experimental .bnf files

* More AST method-name changes
2026-02-01 15:15:49 -05:00
John Kerl
96f13b6618 Internal function-name update 2026-01-31 16:35:30 -05:00
John Kerl
9963df4090
Switch to generics (#1763)
* gradually replace list.List with slices

* gradually replace list.List with slices

* more

* more

* more
2025-03-05 08:19:15 -05:00
Michel Lind
bd2497a285
Fix non-constant format string errors with Go 1.24 (#1745)
Use `errors.New` instead of `fmt.Errorf` and `fmt.Fprint` instead of
`fmt.Fprintf` if a non-constant string is used

Signed-off-by: Michel Lind <salimma@fedoraproject.org>
2025-02-05 08:32:23 -05:00
John Kerl
41649bf4f9
Static-check fixes from @lespea #1657, batch 7/n (#1709) 2024-10-27 12:11:28 -04:00
John Kerl
b4ff26a7d0
Static-check fixes from @lespea #1657, batch 6/n (#1708)
* Static-check fixes from @lespea #1657, batch 2/n

* Static-check fixes from @lespea #1657, batch 3/n

* Static-check fixes from @lespea #1657, batch 4/n

* Static-check fixes from @lespea #1657, batch 5/n

* Static-check fixes from @lespea #1657, batch 6/n
2024-10-27 12:06:17 -04:00
John Kerl
02bd5344b9
Static-check fixes from @lespea #1657, batch 5/n (#1707)
* Static-check fixes from @lespea #1657, batch 2/n

* Static-check fixes from @lespea #1657, batch 3/n

* Static-check fixes from @lespea #1657, batch 4/n

* Static-check fixes from @lespea #1657, batch 5/n
2024-10-27 12:05:48 -04:00
John Kerl
cc8a3c4b4e
Static-check fixes from @lespea #1657, batch 2/n (#1704) 2024-10-27 11:50:15 -04:00
John Kerl
047cb4bc28
Static-check fixes from @lespea #1657, batch 1/n (#1703) 2024-10-27 11:42:43 -04:00
Adam Lesperance
085e831668
The package version must match the major tag version (#1654)
* Update package version

* Update makefile targets

* Update readme packages

* Remaining old packages via rg/sd
2024-09-20 12:10:11 -04:00
John Kerl
73e2117b43
Misc. codespell findings (#1628) 2024-08-25 17:40:57 -04:00
John Kerl
5ac48516f7
Add a stat DSL function (#1560)
* Add a `stat` DSL function [WIP]

* artifacts from `make dev`

* regression test
2024-05-09 18:39:44 -04:00
camcui
12480c4ab5
chore: fix function name in comment (#1543)
Signed-off-by: camcui <cuishua@sina.cn>
2024-04-12 09:38:31 -04:00
John Kerl
7bd460a3b8
Support thousands separator in fmtnum (#1499)
* Support thousands separator in `fmtnum`

* doc bits
2024-02-18 14:01:46 -05:00
John Kerl
d2559b8387
Have clean_whitespace re-run type inference (#1464)
* Have `clean_whitespace` re-infer types

* make dev output

* unit-test files

* drive-by typofix

* make dev output
2024-01-01 18:39:27 -05:00
John Kerl
c6b745537a
New strmatch/strmatchx DSL functions (#1448)
* New `match`/`matchx` DSL functions

* unit-test cases

* match/matchx -> strmatch/strmatchx

* help strings for strmatch and strmatchx

* update regex doc page re strmatch/strmatchx

* unit-test update
2023-12-19 14:34:54 -05:00
John Kerl
4053d7684c
Preserve regex captures across stack frames (#1447)
* privatize state.RegexCaptures

* stack frame for regex captures

* merge

* unit-test case

* docs re stack frames for regex captures

* more
2023-12-18 10:21:09 -05:00
John Kerl
1ae670fd4a
Rename internal regex functions (#1446) 2023-12-17 12:46:28 -05:00
John Kerl
bae1daf847
Absent variable on left side of boolean OR (||) expression makes it absent (#1434)
* Absent-handling with short-circuiting operators `&&` and `||`

* add a missing file

* artifacts from make dev

* type-errors

* doc content

* artifacts from make dev
2023-12-02 16:00:05 -05:00
John Kerl
268a96d002
Export library code in pkg/ (#1391)
* Export library code in `pkg/`

* new doc page
2023-09-10 17:15:13 -04:00