stred

Stred: Streaming Tree Editor. Like sed but for JSON
git clone http://shtanton.xyz/git/repo/stred
Log | Files | Refs

commit 9ba3b1d97e8fd2a2e3c4bb08fe350c8dd5f9733e
parent a2636b27fdadb2b7951fa35fe301e8e6b41fc28a
Author: Charlie Stanton <charlie@shtanton.xyz>
Date:   Sun, 26 Feb 2023 08:57:32 +0000

Converts subex output back into WalkValues and prints for easier debugging

Diffstat:
Msubex/main.go | 63++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mwalk/walk.go | 32++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/subex/main.go b/subex/main.go @@ -5,6 +5,7 @@ import ( "fmt" "bufio" "main/walk" + "strings" ) // A part of an insertion, either a datum or a slot from which to load @@ -136,10 +137,66 @@ func Main() { close(out) }(pieces, tokens) output, err := RunTransducer(transducer, pieces) - // TODO recombine data into values and then convert into items with empty paths if !err { - fmt.Print(output) + dataIn := make(chan walk.Datum) + go func(out chan<- walk.Datum, in []walk.Datum) { + for _, datum := range in { + out<-datum + } + close(out) + }(dataIn, output) + valueOut := make(chan walk.WalkValue) + go func(out chan<- walk.WalkValue, in <-chan walk.Datum) { + for { + datum, hasDatum := <-in + if !hasDatum { + break + } + switch v := datum.(type) { + case walk.TerminalValue: + out<-v + continue + case walk.ValueNull: + out<-v + continue + case walk.ValueBool: + out<-v + continue + case walk.ValueNumber: + out<-v + continue + case rune: + panic("Error! Rune output by subex but not in a string") + case walk.EndString: + panic("Error! subex output an EndString before BeginString") + case walk.StartString: + default: + panic("Unknown datum type") + } + // Handle string start + var builder strings.Builder + loop: for { + datum, hasDatum := <-in + if !hasDatum { + panic("Missing EndString") + } + switch v := datum.(type) { + case walk.EndString: + break loop + case rune: + builder.WriteRune(v) + default: + panic("Invalid datum in string") + } + } + out<-walk.ValueString(builder.String()) + } + close(out) + }(valueOut, dataIn) + for value := range valueOut { + fmt.Println(value) + } } else { - fmt.Print("Error") + fmt.Println("Error") } } diff --git a/walk/walk.go b/walk/walk.go @@ -19,19 +19,47 @@ const ( func (value TerminalValue) Pieces(out chan<- Datum) { out<-value } +func (value TerminalValue) String() string { + switch value { + case ArrayBegin: + return "[" + case ArrayEnd: + return "]" + case MapBegin: + return "{" + case MapEnd: + return "}" + default: + panic("Unknown TerminalValue") + } +} type ValueNull struct {} func (value ValueNull) Pieces(out chan<- Datum) { out<-value } +func (value ValueNull) String() string { + return "null" +} type ValueBool bool func (value ValueBool) Pieces(out chan<- Datum) { out<-value } +func (value ValueBool) String() string { + if value { + return "true" + } else { + return "false" + } +} type ValueNumber float64 func (value ValueNumber) Pieces(out chan<- Datum) { out<-value } +func (value ValueNumber) String() string { + v := float64(value) + return fmt.Sprintf("%f", v) +} type StartString struct {} type EndString struct {} @@ -43,11 +71,15 @@ func (value ValueString) Pieces(out chan<- Datum) { } out<-EndString{} } +func (value ValueString) String() string { + return fmt.Sprintf("\"%s\"", string(value)) +} type Datum interface {} type WalkValue interface { Pieces(out chan<- Datum) + String() string } type WalkItem struct {