diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-04-01 15:15:28 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-04-01 15:15:28 -0400 |
| commit | d888bec4095170d159c488292ba098b243c0a44e (patch) | |
| tree | 0d0ff7c2e2c4ed75519ee32ec6482e04b1e68b3d /examples | |
| parent | 354ed77535d17f2fc71780f1aaeb7ebfb80307d4 (diff) | |
Clean up and improve patterns
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/colorful/colorful.tm | 15 | ||||
| -rw-r--r-- | examples/commands/commands.tm | 2 | ||||
| -rw-r--r-- | examples/ini/ini.tm | 15 | ||||
| -rw-r--r-- | examples/patterns/patterns.tm | 36 | ||||
| -rw-r--r-- | examples/time/time.tm | 2 | ||||
| -rw-r--r-- | examples/tomo-install/tomo-install.tm | 9 | ||||
| -rw-r--r-- | examples/tomodeps/tomodeps.tm | 14 |
7 files changed, 48 insertions, 45 deletions
diff --git a/examples/colorful/colorful.tm b/examples/colorful/colorful.tm index e138e037..7b265ecb 100644 --- a/examples/colorful/colorful.tm +++ b/examples/colorful/colorful.tm @@ -1,4 +1,5 @@ # Colorful language + HELP := " colorful: A domain-specific language for writing colored text to the terminal Usage: colorful [args...] [--by-line] [--files files...] @@ -6,6 +7,8 @@ HELP := " CSI := "$\033[" +use patterns + lang Colorful: convert(text:Text -> Colorful): text = text:translate({"@"="@(at)", "("="@(lparen)", ")"="@(rparen)"}) @@ -42,18 +45,18 @@ func main(texts:[Text], files=[:Path], by_line=no): func _for_terminal(c:Colorful, state:_TermState -> Text): - return c.text:map(recursive=no, $/@(?)/, func(m:Match): _add_ansi_sequences(m.captures[1], state)) + return c.text:map_pattern(recursive=no, $Pat/@(?)/, func(m:PatternMatch): _add_ansi_sequences(m.captures[1], state)) enum _Color(Default, Bright(color:Int16), Color8Bit(color:Int16), Color24Bit(color:Int32)): func from_text(text:Text -> _Color?): - if text:matches($/#{3-6 hex}/): + if text:matches_pattern($Pat/#{3-6 hex}/): hex := text:from(2) return none unless hex.length == 3 or hex.length == 6 if hex.length == 3: hex = hex[1]++hex[1]++hex[2]++hex[2]++hex[3]++hex[3] n := Int32.parse("0x" ++ hex) or return none return Color24Bit(n) - else if text:matches($/{1-3 digit}/): + else if text:matches_pattern($Pat/{1-3 digit}/): n := Int16.parse(text) or return none if n >= 0 and n <= 255: return Color8Bit(n) else if text == "black": return _Color.Color8Bit(0) @@ -168,10 +171,10 @@ func _add_ansi_sequences(text:Text, prev_state:_TermState -> Text): else if text == "rparen": return ")" else if text == "@" or text == "at": return "@" parts := ( - text:matches($/{0+..}:{0+..}/) or + text:matches_pattern($Pat/{0+..}:{0+..}/) or return "@("++_for_terminal(Colorful.from_text(text), prev_state)++")" ) - attributes := parts[1]:split($/{0+space},{0+space}/) + attributes := parts[1]:split_pattern($Pat/{0+space},{0+space}/) new_state := prev_state for attr in attributes: if attr:starts_with("fg="): @@ -210,6 +213,6 @@ func _add_ansi_sequences(text:Text, prev_state:_TermState -> Text): fail("Invalid attribute: '$attr'") result := prev_state:apply(new_state) - result ++= parts[2]:map(recursive=no, $/@(?)/, func(m:Match): _add_ansi_sequences(m.captures[1], new_state)) + result ++= parts[2]:map_pattern(recursive=no, $Pat/@(?)/, func(m:PatternMatch): _add_ansi_sequences(m.captures[1], new_state)) result ++= new_state:apply(prev_state) return result diff --git a/examples/commands/commands.tm b/examples/commands/commands.tm index 70a2303b..26b82790 100644 --- a/examples/commands/commands.tm +++ b/examples/commands/commands.tm @@ -28,7 +28,7 @@ struct ProgramResult(stdout:[Byte], stderr:[Byte], exit_type:ExitType): if status == 0: if text := Text.from_bytes(r.stdout): if trim_newline: - text = text:trim($/{1 nl}/, trim_left=no, trim_right=yes) + text = text:without_suffix(\n) return text else: return none return none diff --git a/examples/ini/ini.tm b/examples/ini/ini.tm index 1c50ac37..1c90b715 100644 --- a/examples/ini/ini.tm +++ b/examples/ini/ini.tm @@ -1,3 +1,6 @@ + +use patterns + _USAGE := " Usage: ini <filename> "[section[/key]]" " @@ -12,18 +15,18 @@ func parse_ini(path:Path -> {Text,{Text,Text}}): current_section := @{:Text,Text} # Line wraps: - text = text:replace($/\{1 nl}{0+space}/, " ") + text = text:replace_pattern($Pat/\{1 nl}{0+space}/, " ") for line in text:lines(): line = line:trim() skip if line:starts_with(";") or line:starts_with("#") - if line:matches($/[?]/): - section_name := line:replace($/[?]/, "\1"):trim():lower() + if line:matches_pattern($Pat/[?]/): + section_name := line:replace($Pat/[?]/, "\1"):trim():lower() current_section = @{:Text,Text} sections[section_name] = current_section - else if line:matches($/{..}={..}/): - key := line:replace($/{..}={..}/, "\1"):trim():lower() - value := line:replace($/{..}={..}/, "\2"):trim() + else if line:matches_pattern($Pat/{..}={..}/): + key := line:replace_pattern($Pat/{..}={..}/, "\1"):trim():lower() + value := line:replace_pattern($Pat/{..}={..}/, "\2"):trim() current_section[key] = value return {k=v[] for k,v in sections[]} diff --git a/examples/patterns/patterns.tm b/examples/patterns/patterns.tm index 5e9ebe69..8ca5faa2 100644 --- a/examples/patterns/patterns.tm +++ b/examples/patterns/patterns.tm @@ -10,49 +10,43 @@ lang Pat: return Pat.from_text("$n") extend Text: - func matches(text:Text, pattern:Pat -> [Text]?): + func matches_pattern(text:Text, pattern:Pat -> [Text]?): return inline C : [Text]? { Pattern$matches(_$text, _$pattern); } - func pat_replace(text:Text, pattern:Pat, replacement:Text, backref="@", recursive=yes -> Text): + func replace_pattern(text:Text, pattern:Pat, replacement:Text, backref="@", recursive=yes -> Text): return inline C : Text { Pattern$replace(_$text, _$pattern, _$replacement, _$backref, _$recursive); } - func pat_replace_all(text:Text, replacements:{Pat,Text}, backref="@", recursive=yes -> Text): + func translate_patterns(text:Text, replacements:{Pat,Text}, backref="@", recursive=yes -> Text): return inline C : Text { Pattern$replace_all(_$text, _$replacements, _$backref, _$recursive); } - func has(text:Text, pattern:Pat -> Bool): + func has_pattern(text:Text, pattern:Pat -> Bool): return inline C : Bool { Pattern$has(_$text, _$pattern); } - func find_all(text:Text, pattern:Pat -> [PatternMatch]): + func find_patterns(text:Text, pattern:Pat -> [PatternMatch]): return inline C : [PatternMatch] { Pattern$find_all(_$text, _$pattern); } - func by_match(text:Text, pattern:Pat -> func(->PatternMatch?)): + func by_pattern(text:Text, pattern:Pat -> func(->PatternMatch?)): return inline C : func(->PatternMatch?) { Pattern$by_match(_$text, _$pattern); } - func each(text:Text, pattern:Pat, fn:func(m:PatternMatch), recursive=yes): + func each_pattern(text:Text, pattern:Pat, fn:func(m:PatternMatch), recursive=yes): inline C { Pattern$each(_$text, _$pattern, _$fn, _$recursive); } - func map(text:Text, pattern:Pat, fn:func(m:PatternMatch -> Text), recursive=yes -> Text): + func map_pattern(text:Text, pattern:Pat, fn:func(m:PatternMatch -> Text), recursive=yes -> Text): return inline C : Text { Pattern$map(_$text, _$pattern, _$fn, _$recursive); } - func split(text:Text, pattern:Pat -> [Text]): + func split_pattern(text:Text, pattern:Pat -> [Text]): return inline C : [Text] { Pattern$split(_$text, _$pattern); } - func by_split(text:Text, pattern:Pat -> func(->Text?)): + func by_pattern_split(text:Text, pattern:Pat -> func(->Text?)): return inline C : func(->Text?) { Pattern$by_split(_$text, _$pattern); } - func trim(text:Text, pattern:Pat, trim_left=yes, trim_right=yes -> Text): - return inline C : Text { Pattern$trim(_$text, _$pattern, _$trim_left, _$trim_right); } - - func trim_left(text:Text, pattern:Pat -> Text): - return text:trim(pattern, trim_left=yes, trim_right=no) - - func trim_right(text:Text, pattern:Pat -> Text): - return text:trim(pattern, trim_left=no, trim_right=yes) + func trim_pattern(text:Text, pattern=$Pat"{space}", left=yes, right=yes -> Text): + return inline C : Text { Pattern$trim(_$text, _$pattern, _$left, _$right); } func main(): - >> "hello world":pat_replace($Pat/{id}/, "XXX") - >> "hello world":find_all($Pat/l/) + >> "hello world":replace_pattern($Pat/{id}/, "XXX") + >> "hello world":find_patterns($Pat/l/) - for m in "hello one two three":by_match($Pat/{id}/): + for m in "hello one two three":by_pattern($Pat/{id}/): >> m diff --git a/examples/time/time.tm b/examples/time/time.tm index 909c24ec..8664f2e4 100644 --- a/examples/time/time.tm +++ b/examples/time/time.tm @@ -123,7 +123,7 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern): t:format("%l:%M%P") else: t:format("%H:%M") - return time:trim($/ /, trim_left=yes, trim_right=yes) + return time:trim() func date(t:Time, timezone=Time.local_timezone() -> Text): return t:format("%F") diff --git a/examples/tomo-install/tomo-install.tm b/examples/tomo-install/tomo-install.tm index 0a6c608d..3be23a81 100644 --- a/examples/tomo-install/tomo-install.tm +++ b/examples/tomo-install/tomo-install.tm @@ -1,4 +1,5 @@ use shell +use patterns _USAGE := " tomo-install file.tm... @@ -16,7 +17,7 @@ func find_urls(path:Path -> [Text]): urls:insert_all(find_urls(f)) else if path:is_file() and path:extension() == ".tm": for line in path:by_line()!: - if m := line:matches($/use{space}{url}/) or line:matches($/{id}{space}:={space}use{space}{url}/): + if m := line:matches_pattern($Pat/use{space}{url}/) or line:matches_pattern($Pat/{id}{space}:={space}use{space}{url}/): urls:insert(m[-1]) return urls @@ -33,7 +34,7 @@ func main(paths:[Path]): for url in urls: original_url := url - url_without_protocol := url:trim($|http{0-1 s}://|, trim_right=no) + url_without_protocol := url:trim_pattern($Pat"http{0-1 s}://", right=no) hash := $Shell@(echo -n @url_without_protocol | sha256sum):get_output()!:slice(to=32) if (~/.local/share/tomo/installed/$hash):is_directory(): say("Already installed: $url") @@ -41,12 +42,12 @@ func main(paths:[Path]): alias := none:Text curl_flags := ["-L"] - if github := url_without_protocol:matches($|github.com/{!/}/{!/}#{..}|): + if github := url_without_protocol:matches_pattern($Pat"github.com/{!/}/{!/}#{..}"): user := github[1] repo := github[2] tag := github[3] url = "https://api.github.com/repos/$user/$repo/tarball/$tag" - alias = "$(repo:trim($/tomo-/, trim_right=no)).$(tag).$(user)" + alias = "$(repo:without_prefix("tomo-")).$(tag).$(user)" if github_token: curl_flags ++= ["-H", "Authorization: Bearer $github_token"] curl_flags ++= [ diff --git a/examples/tomodeps/tomodeps.tm b/examples/tomodeps/tomodeps.tm index 8149ff88..96838a66 100644 --- a/examples/tomodeps/tomodeps.tm +++ b/examples/tomodeps/tomodeps.tm @@ -1,5 +1,7 @@ # Show a Tomo dependency graph +use patterns + _USAGE := "Usage: tomodeps <files...>" _HELP := " @@ -17,11 +19,11 @@ func _get_file_dependencies(file:Path -> {Dependency}): deps := @{:Dependency} if lines := file:by_line(): for line in lines: - if line:matches($/use {..}.tm/): - file_import := Path.from_text(line:replace($/use {..}/, "\1")):resolved(relative_to=file) + if line:matches_pattern($Pat/use {..}.tm/): + file_import := Path.from_text(line:replace_pattern($Pat/use {..}/, "\1")):resolved(relative_to=file) deps:add(Dependency.File(file_import)) - else if line:matches($/use {id}/): - module_name := line:replace($/use {..}/, "\1") + else if line:matches_pattern($Pat/use {id}/): + module_name := line:replace_pattern($Pat/use {..}/, "\1") deps:add(Dependency.Module(module_name)) return deps[] @@ -102,11 +104,11 @@ func main(files:[Text]): ") for arg in files: - if arg:matches($/{..}.tm/): + if arg:matches_pattern($Pat/{..}.tm/): path := Path.from_text(arg):resolved() dependencies := get_dependency_graph(File(path)) draw_tree(File(path), dependencies) - else if arg:matches($/{id}/): + else if arg:matches_pattern($Pat/{id}/): dependencies := get_dependency_graph(Module(arg)) draw_tree(Module(arg), dependencies) else: |
