Skip to content

Commit bfa6b80

Browse files
committed
Add savi-lang-plumber binary, capable of printing cache files as YAML.
This tool will be used to inspect and test the intermediate data structures in between compiler micro-passes, as seen in the compact binary files emitted to the savi-cache directory.
1 parent c31725b commit bfa6b80

File tree

4 files changed

+106
-5
lines changed

4 files changed

+106
-5
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,14 @@ gen.capnp.check: gen.capnp
129129
# Update deps for the Self-hosted Savi compiler subprograms.
130130
self-hosted.deps: PHONY SAVI
131131
echo && $(SAVI) deps update --cd self-hosted --for savi-lang-broker
132+
echo && $(SAVI) deps update --cd self-hosted --for savi-lang-plumber
132133
echo && $(SAVI) deps update --cd self-hosted --for savi-lang-parse
133134

134135
# Create the self-hosted Savi compiler subprograms.
135136
self-hosted/bin/savi-lang-broker: $(SAVI) $(shell find self-hosted/src/savi-lang-broker self-hosted/src/SaviWorker self-hosted/src/SaviProto -name '*.savi')
136137
echo && $(SAVI) build --cd self-hosted savi-lang-broker --print-perf --backtrace
138+
self-hosted/bin/savi-lang-plumber: $(SAVI) $(shell find self-hosted/src/savi-lang-plumber self-hosted/src/SaviWorker self-hosted/src/SaviProto -name '*.savi')
139+
echo && $(SAVI) build --cd self-hosted savi-lang-plumber --print-perf --backtrace
137140
self-hosted/bin/savi-lang-parse: $(SAVI) $(shell find self-hosted/src/savi-lang-parse self-hosted/src/SaviWorker self-hosted/src/SaviProto -name '*.savi')
138141
echo && $(SAVI) build --cd self-hosted savi-lang-parse --print-perf --backtrace
139142

self-hosted/manifest.savi

+8-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
:from "github:savi-lang/Logger"
2727
:depends on Time
2828

29+
:dependency ByteStream v0
30+
:from "github:savi-lang/ByteStream"
31+
2932
:dependency IO v0
3033
:from "github:savi-lang/IO"
3134
:depends on ByteStream
@@ -47,9 +50,6 @@
4750
:transitive dependency Time v0
4851
:from "github:savi-lang/Time"
4952

50-
:transitive dependency ByteStream v0
51-
:from "github:savi-lang/ByteStream"
52-
5353
:transitive dependency OSError v0
5454
:from "github:savi-lang/OSError"
5555

@@ -68,6 +68,11 @@
6868
:sources "src/savi-lang-broker/*.savi"
6969
:copies SaviWorker
7070

71+
:manifest bin "savi-lang-plumber"
72+
:sources "src/savi-lang-plumber/*.savi"
73+
:sources "src/SaviProto/SaviProto.AST.capnp.savi"
74+
:copies SaviWorker
75+
7176
:manifest bin "savi-lang-parse"
7277
:sources "src/savi-lang-parse/*.savi"
7378
:sources "src/SaviProto/SaviProto.AST.capnp.savi"

self-hosted/src/savi-lang-parse/Main.TestMode.savi

+15-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,24 @@
99

1010
:fun ref io_react(action IO.Action)
1111
case action == (
12-
| IO.Action.Closed |
13-
@handle_code(@io.read_stream.extract_all.as_string)
12+
| IO.Action.Read |
13+
try (
14+
if @_reader.read!(@io.read_stream) @_handle_segments
15+
|
16+
@env.err.print("Maximum total capnpc segments size exceeded")
17+
)
1418
)
1519
@
1620

21+
:fun ref _handle_segments
22+
try (
23+
message = CapnProto.Message(CapnProto.Meta.CodeGeneratorRequest)
24+
.from_segments!(@_reader.take_segments)
25+
@_generate(message.root)
26+
|
27+
@env.err.print("Failed to parse the root of the capnpc data")
28+
)
29+
1730
:fun handle_code(code String)
1831
nanos = Time.Measure.nanoseconds -> (
1932
printer = PEG.Parser(_Token, String).new(_Grammar.new, _TreePrinter.new)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
:class _CLI
2+
:var to_yaml: ""
3+
4+
:is CLI.Option.Data
5+
:fun non define_cli_options(defs CLI.Option.Defs) None
6+
defs.string("to-yaml")
7+
8+
:fun ref trace_data_mutable(trace TraceData.Mutator) None
9+
trace.object(identity_digest_of @) -> (key |
10+
case key == (
11+
| "to-yaml" | trace.replace_string(@to_yaml) -> (v | @to_yaml = v)
12+
)
13+
)
14+
15+
:actor Main
16+
:let env Env
17+
:new (@env)
18+
cli = try (
19+
CLI.Parser(_CLI).parse!(_CLI.new, @env.args)
20+
| error |
21+
@env.err.print(error.message)
22+
@env.exit_code = 1
23+
return
24+
)
25+
log = _Log.new(@env.err, Logger.Level.Debug)
26+
27+
case (
28+
| cli.options.to_yaml != "" |
29+
path = File.Path.ReadOnly.new(@env.root, cli.options.to_yaml)
30+
ToYAML.new(log, path, @env.out)
31+
)
32+
33+
:actor ToYAML
34+
:let log _Log
35+
:let path File.Path.Readable
36+
:let out Env.OutStream
37+
:new (@log, @path, @out)
38+
File.Loader.new.load_from_file(@path, @)
39+
40+
:is File.Loader.ResultActor
41+
:be result_of_load_from_file(
42+
path File.Path.Readable
43+
result File.Result
44+
content Bytes'iso
45+
)
46+
if (result != File.Result.Success) (
47+
@log.error -> ("Failed to load file \(path.string): \(result)")
48+
return
49+
)
50+
51+
stream = ByteStream.Pair.new
52+
stream.write << --content
53+
try stream.write.flush!
54+
55+
reader = CapnProto.Segments.Reader.new
56+
try (
57+
res = reader.read!(stream.read)
58+
if !res (
59+
@log.error -> ("Incomplete data at \(path.string)")
60+
return
61+
)
62+
|
63+
@log.error -> ("Failed to read the data at \(path.string)")
64+
return
65+
)
66+
67+
try (
68+
case @path.ext_name == (
69+
| "savi-parse" |
70+
message = CapnProto.Message(SaviProto.AST.Document)
71+
.from_segments!(reader.take_segments)
72+
@out.print(Inspect.TraceData.Printer.Deterministic.print(message.root))
73+
|
74+
@log.error -> ("Unsupported file extension \(path.ext_name)")
75+
return
76+
)
77+
|
78+
@log.error -> ("Error reading segments from \(path.string)")
79+
)
80+

0 commit comments

Comments
 (0)