feat: add regex runtime functions
6cd8efc parent: 8c9eb04 modified
src/core.nim +10 -1 | @@ -1,5 +1,5 @@ | ||
| 1 | 1 | ## clonim core — clojure.core builtins, registered into the global var table. |
| 2 | -import std/[strutils, math, times, random] | |
| 2 | +import std/[strutils, math, times, random, re] | |
| 3 | 3 | import runtime |
| 4 | 4 | |
| 5 | 5 | proc num(v: Value): float64 = |
| @@ -520,6 +520,15 @@ proc registerCore*() = | ||
| 520 | 520 | def "clojure.string/upper-case", proc (a: openArray[Value]): Value = mkStr(a[0].s.toUpperAscii) |
| 521 | 521 | def "clojure.string/lower-case", proc (a: openArray[Value]): Value = mkStr(a[0].s.toLowerAscii) |
| 522 | 522 | def "clojure.string/trim", proc (a: openArray[Value]): Value = mkStr(a[0].s.strip) |
| 523 | + def "re-find", proc (a: openArray[Value]): Value = | |
| 524 | + let pattern = re(a[0].s) | |
| 525 | + let start = find(a[1].s, pattern) | |
| 526 | + if start < 0: NilV | |
| 527 | + else: | |
| 528 | + let n = matchLen(a[1].s, pattern, start) | |
| 529 | + mkStr(a[1].s[start ..< start + n]) | |
| 530 | + def "clojure.string/replace", proc (a: openArray[Value]): Value = | |
| 531 | + mkStr(a[0].s.replace(re(a[1].s), a[2].s)) | |
| 523 | 532 | def "clojure.string/split", proc (a: openArray[Value]): Value = |
| 524 | 533 | var r: seq[Value] = @[] |
| 525 | 534 | for piece in a[0].s.split(a[1].s): r.add mkStr(piece) |
| @@ -1,5 +1,5 @@ | |||
| 1 | ## clonim core — clojure.core builtins, registered into the global var table. | 1 | ## clonim core — clojure.core builtins, registered into the global var table. |
| 2 | -import std/[strutils, math, times, random] | 2 | +import std/[strutils, math, times, random, re] |
| 3 | import runtime | 3 | import runtime |
| 4 | 4 | ||
| 5 | proc num(v: Value): float64 = | 5 | proc num(v: Value): float64 = |
| @@ -520,6 +520,15 @@ proc registerCore*() = | |||
| 520 | def "clojure.string/upper-case", proc (a: openArray[Value]): Value = mkStr(a[0].s.toUpperAscii) | 520 | def "clojure.string/upper-case", proc (a: openArray[Value]): Value = mkStr(a[0].s.toUpperAscii) |
| 521 | def "clojure.string/lower-case", proc (a: openArray[Value]): Value = mkStr(a[0].s.toLowerAscii) | 521 | def "clojure.string/lower-case", proc (a: openArray[Value]): Value = mkStr(a[0].s.toLowerAscii) |
| 522 | def "clojure.string/trim", proc (a: openArray[Value]): Value = mkStr(a[0].s.strip) | 522 | def "clojure.string/trim", proc (a: openArray[Value]): Value = mkStr(a[0].s.strip) |
| 523 | + def "re-find", proc (a: openArray[Value]): Value = | ||
| 524 | + let pattern = re(a[0].s) | ||
| 525 | + let start = find(a[1].s, pattern) | ||
| 526 | + if start < 0: NilV | ||
| 527 | + else: | ||
| 528 | + let n = matchLen(a[1].s, pattern, start) | ||
| 529 | + mkStr(a[1].s[start ..< start + n]) | ||
| 530 | + def "clojure.string/replace", proc (a: openArray[Value]): Value = | ||
| 531 | + mkStr(a[0].s.replace(re(a[1].s), a[2].s)) | ||
| 523 | def "clojure.string/split", proc (a: openArray[Value]): Value = | 532 | def "clojure.string/split", proc (a: openArray[Value]): Value = |
| 524 | var r: seq[Value] = @[] | 533 | var r: seq[Value] = @[] |
| 525 | for piece in a[0].s.split(a[1].s): r.add mkStr(piece) | 534 | for piece in a[0].s.split(a[1].s): r.add mkStr(piece) |
modified
tests/test_namespaces.nim +6 -0 | @@ -28,6 +28,12 @@ suite "static namespace resolution": | ||
| 28 | 28 | check forms[0].kind == kStr |
| 29 | 29 | check forms[0].s == "(?i)^did:[a-z0-9]+:" |
| 30 | 30 | |
| 31 | + test "regex functions operate on literal pattern source": | |
| 32 | + registerCore() | |
| 33 | + let found = call(cellGet(varCell("re-find")), | |
| 34 | + [mkStr("(?i)^did:[a-z0-9]+:"), mkStr("DID:plc:abc")]) | |
| 35 | + check equals(found, mkStr("DID:plc:")) | |
| 36 | + | |
| 31 | 37 | test "host namespaces resolve without placeholder source files": |
| 32 | 38 | checkForms("(ns user (:require [clojure.string :as str])) (str/trim \" hi \")", |
| 33 | 39 | "(clojure.string/trim \" hi \")") |
| @@ -28,6 +28,12 @@ suite "static namespace resolution": | |||
| 28 | check forms[0].kind == kStr | 28 | check forms[0].kind == kStr |
| 29 | check forms[0].s == "(?i)^did:[a-z0-9]+:" | 29 | check forms[0].s == "(?i)^did:[a-z0-9]+:" |
| 30 | 30 | ||
| 31 | + test "regex functions operate on literal pattern source": | ||
| 32 | + registerCore() | ||
| 33 | + let found = call(cellGet(varCell("re-find")), | ||
| 34 | + [mkStr("(?i)^did:[a-z0-9]+:"), mkStr("DID:plc:abc")]) | ||
| 35 | + check equals(found, mkStr("DID:plc:")) | ||
| 36 | + | ||
| 31 | test "host namespaces resolve without placeholder source files": | 37 | test "host namespaces resolve without placeholder source files": |
| 32 | checkForms("(ns user (:require [clojure.string :as str])) (str/trim \" hi \")", | 38 | checkForms("(ns user (:require [clojure.string :as str])) (str/trim \" hi \")", |
| 33 | "(clojure.string/trim \" hi \")") | 39 | "(clojure.string/trim \" hi \")") |