Skip to content

Commit 1c78a2a

Browse files
committed
feat(isc): rababa funcall directive — grammar, kwargs, node adapter
The rababa directive (rababa config: "key") parses as a Funcall node with string kwargs instead of a passthrough comment; the codemod emits it directly. Grammar gains a general kwarg_list. Also fixes the Isc autoload constant (was ISC). Without this the var-ara map does not parse — caught by the maps CI parse-all job.
1 parent b708602 commit 1c78a2a

5 files changed

Lines changed: 49 additions & 10 deletions

File tree

lib/interscript.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module Interscript
1111
autoload :DSL, "interscript/dsl"
1212
autoload :Node, "interscript/node"
1313
autoload :Detector, "interscript/detector"
14-
autoload :ISC, "interscript/isc"
14+
autoload :Isc, "interscript/isc"
1515

1616
# An error caused by a lack of some map
1717
class MapNotFoundError < StandardError; end

lib/interscript/isc/codemod.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,8 @@ def convert_body
119119
elsif @scanner.scan(/stage\b/)
120120
@out << "stage"
121121
convert_stage_header
122-
elsif @scanner.scan(/\b(parallel|sequence|separate|deep|compose|decompose|downcase|upcase|title_case)\b/)
122+
elsif @scanner.scan(/\b(parallel|sequence|separate|deep|compose|decompose|downcase|upcase|title_case|rababa)\b/)
123123
@out << @scanner.matched
124-
elsif @scanner.scan(/\brababa\b/)
125-
# rababa config: "200" — special directive, pass through as comment
126-
rest = @scanner.scan_until(/\n/)
127-
@out << "# rababa directive: #{rest.chomp}\n"
128124
elsif @scanner.scan(/\bsub\b/)
129125
@out << "sub"
130126
convert_sub_rule

lib/interscript/isc/document_builder.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,23 @@ def ident(fragment)
133133
@transform.apply(fragment).to_s
134134
end
135135

136+
# Extract `name: "value"` pairs from a parslet kwarg tree into a
137+
# string-keyed Hash. The tree is `{kwarg: [{kwarg_name:, kwarg_value:}, ...]}`
138+
# or a single `{kwarg_name:, kwarg_value:}` for one kwarg.
139+
def extract_kwargs(fragment)
140+
return {} if fragment.nil?
141+
raw = fragment.is_a?(Hash) ? fragment[:kwarg] : fragment
142+
kwargs = case raw
143+
when Hash then [raw]
144+
when Array then raw.select { |k| k.is_a?(Hash) }
145+
else []
146+
end
147+
kwargs.each_with_object({}) do |kw, h|
148+
next unless kw.is_a?(Hash)
149+
h[ident(kw[:kwarg_name])] = unquote(kw[:kwarg_value])
150+
end
151+
end
152+
136153
def derive_urn(code)
137154
"urn:iso:24229:system:#{code.downcase}"
138155
end
@@ -240,6 +257,7 @@ def extract_stage_items(n)
240257
when n[:separate] then [{ kind: :separate, separator: n[:separator] ? materialize(n[:separator]) : nil }]
241258
when n[:compose] then [{ kind: :compose }]
242259
when n[:case] then [{ kind: :string_case, op: n[:case].to_s }]
260+
when n[:funcall_name] then [{ kind: :funcall, name: n[:funcall_name].to_s, kwargs: extract_kwargs(n[:funcall_kwargs]) }]
243261
when n[:dep] then [{ kind: :run, dependency: ident(n[:dep]), stage: ident(n[:stage]) }]
244262
when n[:run_stage_only] then [{ kind: :run, dependency: nil, stage: ident(n[:run_stage_only][:stage]) }]
245263
when n[:bare_rule] then [{ kind: :bare_rule, rule: extract_rule(n[:bare_rule]) }]

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ module Stages
2020
rule(:stage_item) do
2121
whitespace? >>
2222
(sequence_block | parallel_block | run_rule | separate_directive |
23-
string_case_directive | compose_directive | bare_rule |
24-
comment_item) >>
23+
string_case_directive | compose_directive | rababa_directive |
24+
bare_rule | comment_item) >>
2525
whitespace?
2626
end
2727

@@ -58,9 +58,29 @@ module Stages
5858
(str("downcase") | str("upcase") | str("title_case")).as(:case)
5959
end
6060

61-
# `compose` — compose decomposed characters (NFC-ish).
61+
# `compose` / `decompose` — Unicode normalization directives.
6262
rule(:compose_directive) do
63-
(str("compose") | str("decompose")).as(:compose)
63+
str("compose").as(:compose) | str("decompose").as(:compose)
64+
end
65+
66+
# `rababa config: "key"` — invoke the rababa diacritization service.
67+
# The keyword arguments are passed through to the runtime funcall.
68+
rule(:rababa_directive) do
69+
str("rababa").as(:funcall_name) >>
70+
(whitespace >> kwarg_list.as(:funcall_kwargs)).maybe
71+
end
72+
73+
# `name: "value"` (`,`-separated). Used by rababa and other
74+
# function-call directives. Each kwarg is captured as a
75+
# subtree so multiple kwargs collect into a list.
76+
rule(:kwarg_list) do
77+
kwarg.as(:kwarg) >> (str(",") >> whitespace? >> kwarg.as(:kwarg)).repeat
78+
end
79+
80+
rule(:kwarg) do
81+
identifier.as(:kwarg_name) >> whitespace? >>
82+
str(":") >> whitespace? >>
83+
quoted_string.as(:kwarg_value)
6484
end
6585

6686
rule(:rule_line) do

lib/interscript/isc/node_adapter.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ def build_stage(stage_def)
8888
stage.children << sym
8989
when :compose
9090
stage.children << :compose
91+
when :funcall
92+
stage.children << Interscript::Node::Rule::Funcall.new(
93+
item[:name].to_sym,
94+
**item[:kwargs].transform_keys(&:to_sym),
95+
)
9196
end
9297
end
9398
stage

0 commit comments

Comments
 (0)