Module: Kumi::Dev::PrettyPrinter

Defined in:
lib/kumi/dev/pretty_printer.rb

Class Method Summary collapse

Class Method Details

.analyze_schema(path, stop_after: nil, **opts) ⇒ Object



192
193
194
195
196
197
198
199
200
201
# File 'lib/kumi/dev/pretty_printer.rb', line 192

def analyze_schema(path, stop_after: nil, **opts)
  schema, = Kumi::Frontends.load(path: path)
  if stop_after
    with_stop_after(stop_after) do
      Kumi::Analyzer.analyze!(schema, **opts)
    end
  else
    Kumi::Analyzer.analyze!(schema, **opts)
  end
end

.format_node(name, node, indent) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/kumi/dev/pretty_printer.rb', line 58

def format_node(name, node, indent)
  prefix = "  " * indent
  result = []

  # Node header with type and container
  header = "#{prefix}#{name}: #{node.type}"
  header += " (#{node.container})" if node.container != :scalar
  header += " access_mode=#{node.access_mode}" if node.access_mode
  result << header

  # Child steps if any
  if node.child_steps && !node.child_steps.empty?
    node.child_steps.each do |child_name, steps|
      steps_str = steps.map { |s| s[:kind] }.join("")
      result << "#{prefix}  └─> #{child_name}: #{steps_str}"
    end
  end

  # Recursively print children
  if node.children && !node.children.empty?
    node.children.each do |child_name, child_node|
      result << format_node(child_name, child_node, indent + 1)
    end
  end

  result.join("\n")
end

.generate_ast(path) ⇒ Object



38
39
40
41
# File 'lib/kumi/dev/pretty_printer.rb', line 38

def generate_ast(path)
  schema, = Kumi::Frontends.load(path: path)
  Kumi::Support::SExpressionPrinter.print(schema)
end

.generate_binding_manifest(path) ⇒ Object



144
145
146
147
148
149
150
# File 'lib/kumi/dev/pretty_printer.rb', line 144

def generate_binding_manifest(path)
  schema, = Kumi::Frontends.load(path: path)
  res = Kumi::Analyzer.analyze!(schema, side_tables: true)
  return nil unless res.state[:binding_manifest]

  Printer::WidthAwareJson.dump(res.state[:binding_manifest])
end

.generate_dfir(path) ⇒ Object



112
113
114
115
116
# File 'lib/kumi/dev/pretty_printer.rb', line 112

def generate_dfir(path)
  res = analyze_schema(path, stop_after: "DFValidatePass", side_tables: true)
  graph = res.state[:df_module_unoptimized] or raise "Missing DFIR for #{path}"
  print_ir_graph(graph)
end

.generate_dfir_optimized(path) ⇒ Object



118
119
120
121
122
# File 'lib/kumi/dev/pretty_printer.rb', line 118

def generate_dfir_optimized(path)
  res = analyze_schema(path, stop_after: "DFValidatePass", side_tables: true)
  graph = res.state[:df_module] or raise "Missing optimized DFIR for #{path}"
  print_ir_graph(graph)
end

.generate_input_plan(path) ⇒ Object



43
44
45
46
47
48
# File 'lib/kumi/dev/pretty_printer.rb', line 43

def generate_input_plan(path)
  res = analyze_schema(path, stop_after: "InputAccessPlannerPass")
  return nil unless res.state[:input_metadata]

  print_input_plan(res.state[:input_metadata])
end

.generate_ir(path) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/kumi/dev/pretty_printer.rb', line 86

def generate_ir(path)
  schema, = Kumi::Frontends.load(path: path)
  res = Kumi::Analyzer.analyze!(schema)
  return nil unless res.state[:ir_module]

  Kumi::Support::IRRender.to_text(res.state[:ir_module], analysis_state: res.state)
end

.generate_irv2(path) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/kumi/dev/pretty_printer.rb', line 136

def generate_irv2(path)
  schema, = Kumi::Frontends.load(path: path)
  res = Kumi::Analyzer.analyze!(schema, side_tables: true)
  return nil unless res.state[:irv2]

  Printer::WidthAwareJson.dump(res.state[:irv2])
end

.generate_loopir(path) ⇒ Object



130
131
132
133
134
# File 'lib/kumi/dev/pretty_printer.rb', line 130

def generate_loopir(path)
  res = analyze_schema(path, stop_after: "LoopValidatePass", side_tables: true)
  graph = res.state[:loop_module] or raise "Missing LoopIR for #{path}"
  print_ir_graph(graph)
end

.generate_nast(path) ⇒ Object



94
95
96
97
98
99
100
101
# File 'lib/kumi/dev/pretty_printer.rb', line 94

def generate_nast(path)
  with_stop_after("NormalizeToNASTPass") do
    res = analyze_schema(path)
    return nil unless res.state[:nast_module]

    Kumi::Support::NASTPrinter.print(res.state[:nast_module])
  end
end

.generate_pack(path) ⇒ Object



180
181
182
183
184
# File 'lib/kumi/dev/pretty_printer.rb', line 180

def generate_pack(path)
  require_relative "../pack"

  Kumi::Pack.print(schema: path, targets: %w[ruby])
end

.generate_planning(path) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
# File 'lib/kumi/dev/pretty_printer.rb', line 168

def generate_planning(path)
  require_relative "../codegen/planning"

  schema, = Kumi::Frontends.load(path: path)
  res = Kumi::Analyzer.analyze!(schema, side_tables: true)
  return nil unless res.state[:irv2]

  bundle = Kumi::Codegen::Planning.from_ir(res.state[:irv2])
  planning_data = Kumi::Codegen::Planning.to_json(bundle)
  Printer::WidthAwareJson.dump(planning_data)
end

.generate_schema_javascript(path) ⇒ Object



160
161
162
163
164
165
166
# File 'lib/kumi/dev/pretty_printer.rb', line 160

def generate_schema_javascript(path)
  schema, = Kumi::Frontends.load(path: path)
  res = Kumi::Analyzer.analyze!(schema, side_tables: true)
  return nil unless res.state[:javascript_codegen_files]

  res.state[:javascript_codegen_files]["codegen.mjs"]
end

.generate_schema_ruby(path) ⇒ Object



152
153
154
155
156
157
158
# File 'lib/kumi/dev/pretty_printer.rb', line 152

def generate_schema_ruby(path)
  schema, = Kumi::Frontends.load(path: path)
  res = Kumi::Analyzer.analyze!(schema, side_tables: true)
  return nil unless res.state[:ruby_codegen_files]

  res.state[:ruby_codegen_files]["codegen.rb"]
end

.generate_snast(path) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/kumi/dev/pretty_printer.rb', line 103

def generate_snast(path)
  with_stop_after("SNASTPass") do
    res = analyze_schema(path)
    raise "Error Generating #{path}" unless res.state[:snast_module]

    Kumi::Support::SNASTPrinter.print(res.state[:snast_module])
  end
end

.generate_vecir(path) ⇒ Object



124
125
126
127
128
# File 'lib/kumi/dev/pretty_printer.rb', line 124

def generate_vecir(path)
  res = analyze_schema(path, stop_after: "VecValidatePass", side_tables: true)
  graph = res.state[:vec_module] or raise "Missing VecIR for #{path}"
  print_ir_graph(graph)
end


50
51
52
53
54
55
56
# File 'lib/kumi/dev/pretty_printer.rb', line 50

def print_input_plan(, indent = 0)
  lines = []
  .each do |name, node|
    lines << format_node(name, node, indent)
  end
  lines.join("\n")
end


186
187
188
189
190
# File 'lib/kumi/dev/pretty_printer.rb', line 186

def print_ir_graph(graph)
  io = StringIO.new
  Kumi::IR::Printer.print(graph, io: io)
  io.string
end

.run(kind, path) ⇒ Object



12
13
14
15
16
17
18
# File 'lib/kumi/dev/pretty_printer.rb', line 12

def run(kind, path)
  method_name = "generate_#{kind}"
  raise "Unknown pretty print kind: #{kind}" unless respond_to?(method_name)

  output = send(method_name, path)
  puts output if output
end

.with_stop_after(pass_name) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/kumi/dev/pretty_printer.rb', line 20

def with_stop_after(pass_name)
  saved = {
    "KUMI_STOP_AFTER" => ENV.fetch("KUMI_STOP_AFTER", nil),
    "KUMI_CHECKPOINT" => ENV.fetch("KUMI_CHECKPOINT", nil),
    "KUMI_RESUME_FROM" => ENV.fetch("KUMI_RESUME_FROM", nil),
    "KUMI_RESUME_AT" => ENV.fetch("KUMI_RESUME_AT", nil)
  }

  ENV["KUMI_STOP_AFTER"] = pass_name
  ENV["KUMI_CHECKPOINT"] = "0"
  ENV.delete("KUMI_RESUME_FROM")
  ENV.delete("KUMI_RESUME_AT")

  yield
ensure
  saved.each { |k, v| v ? ENV[k] = v : ENV.delete(k) }
end