Skip to content

Commit 4f600e7

Browse files
committed
feat(isc): stage(name) syntax, some() constructor, list values with comments
- Codemod: stage(translit) { -> stage translit { - Parser: accept stage(name) { syntax - Parser: some() constructor (one-or-more match) - Codemod: multi-line list values with # comments before items Verification: 193/289 maps equivalent (67%).
1 parent 5b060cd commit 4f600e7

5 files changed

Lines changed: 34 additions & 10 deletions

File tree

exe/codemod-imp-to-isc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,17 +283,15 @@ module Interscript
283283
@out << "\n#{indent}notes {"
284284
convert_notes_list_until_dedent(indent)
285285
@out << "\n#{indent}}"
286-
elsif @scanner.scan(/(?:\A|\n)([ \t]+)([A-Za-z_][\w]*)[ \t]*:[ \t]*\n([ \t]+)-[ \t]*/)
287-
# Multi-line list value: `field:\n - item1\n - item2`
286+
elsif @scanner.scan(/(?:\A|\n)([ \t]+)([A-Za-z_][\w]*)[ \t]*:[ \t]*\n(?:[ \t]*#[^\n]*\n)*([ \t]+)-[ \t]*/)
287+
# Multi-line list value: `field:\n # optional comment\n - item1\n - item2`
288288
indent = @scanner[1]
289289
field = @scanner[2]
290-
first_item_indent = @scanner[3]
290+
item_indent = @scanner[3]
291291
@out << "\n#{indent}#{field} "
292-
# Read the first item value
293292
text = @scanner.scan(/[^\n]+/).to_s
294293
@out << text
295-
# Read subsequent `- item` lines at the same or deeper indent
296-
while @scanner.check(/\n[ \t]{#{first_item_indent.length},}-[ \t]/)
294+
while @scanner.check(/\n[ \t]{#{item_indent.length},}-[ \t]/)
297295
@scanner.scan(/\n[ \t]+-[ \t]+/)
298296
text = @scanner.scan(/[^\n]+/).to_s
299297
@out << " " + text
@@ -551,7 +549,10 @@ module Interscript
551549

552550
def convert_stage_header
553551
# Legacy `stage {` becomes `stage main {` if no name is given.
554-
if @scanner.scan(/\s*\{/)
552+
# `stage(translit) {` becomes `stage translit {`.
553+
if @scanner.scan(/\s*\(([A-Za-z_]\w*)\)\s*\{/)
554+
@out << " #{@scanner[1]} {"
555+
elsif @scanner.scan(/\s*\{/)
555556
@out << " main {"
556557
elsif @scanner.scan(/\s+([A-Za-z_]\w*)\s*\{/)
557558
@out << " #{@scanner[1]} {"

lib/interscript/isc/grammar/concerns/items.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@ module Items
1717
any_constructor |
1818
capture_constructor |
1919
maybe_constructor |
20+
some_constructor |
2021
function_call |
2122
capture_reference |
2223
alias_reference
2324
end
2425

26+
# some(...) — one or more matches (greedy).
27+
rule(:some_constructor) do
28+
str("some") >> str("(") >> whitespace? >>
29+
item.as(:some_inner) >>
30+
whitespace? >> str(")")
31+
end
32+
2533
# Function call: upcase, downcase, title_case, reverse, etc.
2634
# These appear as the `to` value in sub rules: `sub "X" upcase`.
2735
rule(:function_call) do
@@ -107,7 +115,7 @@ module Items
107115
str("none") | str("boundary") | str("line_start") |
108116
str("line_end") | str("word_boundary") |
109117
str("downcase") | str("upcase") | str("title_case") |
110-
str("capture") | str("maybe") | str("ref")
118+
str("capture") | str("maybe") | str("some") | str("ref")
111119
end
112120

113121
# Concatenation: one or more atoms. The continuation pattern

lib/interscript/isc/grammar/concerns/stages.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ module Stages
1111
include Parslet
1212

1313
rule(:stage_block) do
14-
str("stage") >> whitespace >>
15-
identifier.as(:stage_name) >> whitespace? >>
14+
str("stage") >>
15+
(str("(") >> identifier.as(:stage_name) >> str(")") |
16+
whitespace >> identifier.as(:stage_name)) >> whitespace? >>
1617
braced(stage_item.repeat(0)).as(:stage)
1718
end
1819

lib/interscript/isc/items.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,19 @@ def inspect
111111
end
112112
end
113113

114+
# Wraps a one-or-more sub-expression (greedy).
115+
class Some
116+
attr_reader :inner
117+
118+
def initialize(inner)
119+
@inner = inner
120+
end
121+
122+
def inspect
123+
"Some(#{@inner.inspect})"
124+
end
125+
end
126+
114127
class Range
115128
attr_reader :lo, :hi
116129

lib/interscript/isc/transform.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Transform < Parslet::Transform
5757
rule(ref: subtree(:h)) { Items::Capture.new(h[:digit].to_s.to_i) }
5858
rule(capture_inner: subtree(:inner)) { Items::CaptureGroup.new(materialize_item(inner)) }
5959
rule(maybe_inner: subtree(:inner)) { Items::Maybe.new(materialize_item(inner)) }
60+
rule(some_inner: subtree(:inner)) { Items::Some.new(materialize_item(inner)) }
6061

6162
rule(dquote: simple(:_)) { '"' }
6263
rule(backslash: simple(:_)) { "\\" }

0 commit comments

Comments
 (0)