Skip to content

Commit 76a6a4f

Browse files
committed
feat(isc): ISC ↔ YAML round-trip via lutaml-model
Adds three new components: 1. Model layer (lib/interscript/isc/model/) — 9 lutaml-model classes mirroring the ISC document hash: Document, Metadata (open hash), Test, Alias, Stage, StageItem, Rule, Constraint, Item (polymorphic with 12 discriminated types) 2. YamlBridge (lib/interscript/isc/yaml_bridge.rb) — converts between document hash and lutaml-model objects in both directions 3. Serializer (lib/interscript/isc/serializer.rb) — converts document hash back to ISC source text, handling all item types including Set (any()), Concat (+), CaptureGroup (capture()), constraints, parallel/sequence blocks, run directives, compose, string_case API: yaml = Isc::YamlBridge.to_yaml(doc_hash) doc = Isc::YamlBridge.from_yaml(yaml) isc = Isc::Serializer.serialize(doc_hash) Round-trip verified: ISC → YAML → ISC → parse produces equivalent document hash for alalc-amh-Ethi-Latn-1997.
1 parent b210634 commit 76a6a4f

13 files changed

Lines changed: 732 additions & 0 deletions

File tree

lib/interscript/isc.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ module Isc
1111
autoload :Items, "interscript/isc/items"
1212
autoload :Codemod, "interscript/isc/codemod"
1313
autoload :NodeAdapter, "interscript/isc/node_adapter"
14+
autoload :Model, "interscript/isc/model"
15+
autoload :YamlBridge, "interscript/isc/yaml_bridge"
16+
autoload :Serializer, "interscript/isc/serializer"
1417

1518
SCHEMA_VERSION = 1
1619

lib/interscript/isc/model.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
5+
module Interscript
6+
module Isc
7+
module Model
8+
autoload :Item, "interscript/isc/model/item"
9+
autoload :Constraint, "interscript/isc/model/constraint"
10+
autoload :Rule, "interscript/isc/model/rule"
11+
autoload :StageItem, "interscript/isc/model/stage_item"
12+
autoload :Stage, "interscript/isc/model/stage"
13+
autoload :Alias, "interscript/isc/model/alias"
14+
autoload :Test, "interscript/isc/model/test"
15+
autoload :Dependency, "interscript/isc/model/dependency"
16+
autoload :Document, "interscript/isc/model/document"
17+
end
18+
end
19+
end

lib/interscript/isc/model/alias.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model/item"
5+
6+
module Interscript
7+
module Isc
8+
module Model
9+
class Alias < Lutaml::Model::Serializable
10+
attribute :name, :string
11+
attribute :value, Item
12+
13+
yaml do
14+
map "name", to: :name
15+
map "value", to: :value
16+
end
17+
end
18+
end
19+
end
20+
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model/item"
5+
6+
module Interscript
7+
module Isc
8+
module Model
9+
class Constraint < Lutaml::Model::Serializable
10+
attribute :kind, :string
11+
attribute :item, Item
12+
13+
yaml do
14+
map "kind", to: :kind
15+
map "item", to: :item
16+
end
17+
end
18+
end
19+
end
20+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
5+
module Interscript
6+
module Isc
7+
module Model
8+
class Dependency < Lutaml::Model::Serializable
9+
attribute :target, :string
10+
attribute :alias_name, :string
11+
12+
yaml do
13+
map "target", to: :target
14+
map "alias", to: :alias_name
15+
end
16+
end
17+
end
18+
end
19+
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model/test"
5+
require "interscript/isc/model/alias"
6+
require "interscript/isc/model/stage"
7+
require "interscript/isc/model/dependency"
8+
9+
module Interscript
10+
module Isc
11+
module Model
12+
class Document < Lutaml::Model::Serializable
13+
attribute :system_code, :string
14+
attribute :metadata, :hash
15+
attribute :tests, Test, collection: true
16+
attribute :aliases, Alias, collection: true
17+
attribute :stages, Stage, collection: true
18+
attribute :dependencies, Dependency, collection: true
19+
20+
yaml do
21+
map "system_code", to: :system_code
22+
map "metadata", to: :metadata
23+
map "tests", to: :tests
24+
map "aliases", to: :aliases
25+
map "stages", to: :stages
26+
map "dependencies", to: :dependencies
27+
end
28+
end
29+
end
30+
end
31+
end

lib/interscript/isc/model/item.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model"
5+
6+
module Interscript
7+
module Isc
8+
module Model
9+
# Polymorphic representation of an ISC item (StringValue, AliasRef, etc.)
10+
# Serialized as a discriminated union keyed by the `type` field.
11+
#
12+
# YAML shape:
13+
# type: string
14+
# value: "hello"
15+
# ---
16+
# type: alias_ref
17+
# name: my_alias
18+
# ---
19+
# type: concat
20+
# parts:
21+
# - type: string
22+
# value: "a"
23+
# - type: alias_ref
24+
# name: consonants
25+
class Item < Lutaml::Model::Serializable
26+
attribute :type, :string
27+
attribute :value, :string
28+
attribute :name, :string
29+
attribute :index, :integer
30+
attribute :lo, :string
31+
attribute :hi, :string
32+
attribute :chars, :string, collection: true
33+
attribute :parts, Item, collection: true
34+
attribute :inner, Item
35+
36+
yaml do
37+
map "type", to: :type
38+
map "value", to: :value
39+
map "name", to: :name
40+
map "index", to: :index
41+
map "lo", to: :lo
42+
map "hi", to: :hi
43+
map "chars", to: :chars
44+
map "parts", to: :parts
45+
map "inner", to: :inner
46+
end
47+
end
48+
end
49+
end
50+
end

lib/interscript/isc/model/rule.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model/item"
5+
require "interscript/isc/model/constraint"
6+
7+
module Interscript
8+
module Isc
9+
module Model
10+
class Rule < Lutaml::Model::Serializable
11+
attribute :from, Item
12+
attribute :to, Item
13+
attribute :constraints, Constraint, collection: true
14+
15+
yaml do
16+
map "from", to: :from
17+
map "to", to: :to
18+
map "constraints", to: :constraints
19+
end
20+
end
21+
end
22+
end
23+
end

lib/interscript/isc/model/stage.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model/stage_item"
5+
6+
module Interscript
7+
module Isc
8+
module Model
9+
class Stage < Lutaml::Model::Serializable
10+
attribute :name, :string
11+
attribute :body, StageItem, collection: true
12+
13+
yaml do
14+
map "name", to: :name
15+
map "body", to: :body
16+
end
17+
end
18+
end
19+
end
20+
end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
require "lutaml/model"
4+
require "interscript/isc/model/rule"
5+
require "interscript/isc/model/item"
6+
7+
module Interscript
8+
module Isc
9+
module Model
10+
# A single item in a stage body. Discriminated by `kind`:
11+
# parallel, sequence, bare_rule, run, separate, compose, string_case
12+
class StageItem < Lutaml::Model::Serializable
13+
attribute :kind, :string
14+
attribute :rules, Rule, collection: true
15+
attribute :rule, Rule
16+
attribute :dependency, :string
17+
attribute :stage, :string
18+
attribute :separator, Item
19+
attribute :op, :string
20+
21+
yaml do
22+
map "kind", to: :kind
23+
map "rules", to: :rules
24+
map "rule", to: :rule
25+
map "dependency", to: :dependency
26+
map "stage", to: :stage
27+
map "separator", to: :separator
28+
map "op", to: :op
29+
end
30+
end
31+
end
32+
end
33+
end

0 commit comments

Comments
 (0)