Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 4 additions & 31 deletions lib/interscript/compiler/json_ir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,37 +38,9 @@ def serialise_document(doc)
# without re-implementing the Ruby dep_aliases indirection.
all_aliases = {}

# Walk dependencies and merge their alias definitions.
# posix defines :upper, :lower; unicode defines :combining marks; etc.
doc.dependencies.each do |dep|
next unless dep.document
dep.document.aliases.each do |aname, defn|
all_aliases[aname.to_s] ||= serialise_item(defn.data)
end
end

# Also walk dep_aliases (for run-rule dependency resolution paths).
doc.dep_aliases.each_value do |dep|
next unless dep.document
dep.document.aliases.each do |aname, defn|
all_aliases[aname.to_s] ||= serialise_item(defn.data)
end
end

# Also merge ALL library aliases unconditionally. Libraries (posix,
# unicode, var-Cyrl, var-kor) define character classes that maps
# reference via alias() without listing the library as an explicit
# dependency in the dependency list.
Interscript.maps(libraries: true).each do |lib|
libdoc = Interscript.parse(lib)
libdoc.aliases.each do |aname, defn|
all_aliases[aname.to_s] ||= serialise_item(defn.data)
end
rescue
# skip unparseable libraries
end

# Document's own aliases override everything.
# Only the document's own aliases are serialised. Library and
# dependency aliases resolve at runtime via the alias `map:` qualifier,
# matching the production corpus shape.
doc.aliases.each do |name, defn|
all_aliases[name.to_s] = serialise_item(defn.data)
end
Expand Down Expand Up @@ -180,6 +152,7 @@ def serialise_to(to)
end

def serialise_item(item)
return {kind: "any", of: item.map { |i| i.is_a?(String) ? {kind: "string", value: i} : serialise_item(i) }} if item.is_a?(::Array)
case item
when Interscript::Node::Item::String
{kind: "string", value: item.data}
Expand Down
7 changes: 4 additions & 3 deletions lib/interscript/isc/node_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ def build_stage(stage_def)
Interscript::Node::Item::String.new(item[:separator]&.value || "-")
)
when :string_case
sym = (item[:op] == "title_case") ? :title_case : item[:op].to_sym
stage.children << sym
stage.children << Interscript::Node::Rule::Funcall.new(item[:op].to_sym)
when :compose
stage.children << :compose
stage.children << Interscript::Node::Rule::Funcall.new(:compose)
when :decompose
stage.children << Interscript::Node::Rule::Funcall.new(:decompose)
when :funcall
stage.children << Interscript::Node::Rule::Funcall.new(
item[:name].to_sym,
Expand Down
37 changes: 37 additions & 0 deletions spec/json_ir_serialisation_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

# JsonIR must serialise to the production corpus shape: a document
# carries only its own aliases (dependency and library aliases resolve
# at runtime via the alias `map:` qualifier), and any()-sets serialise
# as {kind: "any", of: [...]} — never as merged library dumps or
# char-class rewrites.
require "interscript"
require "json"

MAPS = ENV.fetch("INTERSCRIPT_MAPS_PATH", "../maps/maps")

RSpec.describe "Interscript::Compiler::JsonIR serialisation form" do
before(:all) do
Interscript.load_path.unshift(MAPS) unless Interscript.load_path.first == MAPS
end

it "serialises only the document's own aliases" do
skip "maps checkout not present" unless File.file?(File.expand_path("un-tam-Taml-Latn-1972.isc", MAPS))

doc = Interscript::Compiler.parse_isc(File.expand_path("un-tam-Taml-Latn-1972.isc", MAPS))
ir = JSON.parse(Interscript::Compiler::JsonIR.new.compile(doc).code)

expect(ir["aliases"].keys).to eq(["taml_chars_1"])
end

it "serialises any()-sets as any/of string alternatives" do
skip "maps checkout not present" unless File.file?(File.expand_path("un-tam-Taml-Latn-1972.isc", MAPS))

doc = Interscript::Compiler.parse_isc(File.expand_path("un-tam-Taml-Latn-1972.isc", MAPS))
ir = JSON.parse(Interscript::Compiler::JsonIR.new.compile(doc).code)
alias_def = ir["aliases"]["taml_chars_1"]

expect(alias_def["kind"]).to eq("any")
expect(alias_def["of"]).to all(include("kind" => "string"))
end
end
Loading