From cce21232cc83060a53ecb3a7c30d7f6fbfd7a529 Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Tue, 25 Apr 2023 09:56:00 +0100 Subject: Now uses a buffered output for writing to improve performance --- main/main.go | 3 ++- walk/walk.go | 41 ++++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/main/main.go b/main/main.go index e6730de..0c7324b 100644 --- a/main/main.go +++ b/main/main.go @@ -40,10 +40,11 @@ func main() { program := Parse(tokens) stdin := bufio.NewReader(os.Stdin) + stdout := bufio.NewWriter(os.Stdout) state := ProgramState { in: walk.NewJSONIn(stdin), - out: walk.NewJSONOut(), + out: walk.NewJSONOut(stdout), program: program, } diff --git a/walk/walk.go b/walk/walk.go index 0719d1c..f9bac2a 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -511,10 +511,11 @@ const ( type JSONOut struct { structure []JSONOutStructure + writer *bufio.Writer } func (out *JSONOut) indent(adjust int) { - fmt.Print(strings.Repeat("\t", len(out.structure) - 1 + adjust)) + fmt.Fprint(out.writer, strings.Repeat("\t", len(out.structure) - 1 + adjust)) } func (out *JSONOut) atomOut(key string, atom Atom) { @@ -525,46 +526,46 @@ func (out *JSONOut) atomOut(key string, atom Atom) { case AtomNull, AtomBool, AtomNumber: out.indent(0) if state == JSONOutMap { - fmt.Printf("%q: ", key) + fmt.Fprintf(out.writer, "%q: ", key) } - fmt.Print(atom.String()) + fmt.Fprint(out.writer, atom.String()) out.structure = append(out.structure, JSONOutValueEnd) case AtomStringTerminal: out.indent(0) if state == JSONOutMap { - fmt.Printf("%q: ", key) + fmt.Fprintf(out.writer, "%q: ", key) } - fmt.Print("\"") + fmt.Fprint(out.writer, "\"") out.structure = append(out.structure, JSONOutString) case AtomTerminal: switch TerminalValue(atom.data) { case MapBegin: out.indent(0) if state == JSONOutMap { - fmt.Printf("%q: ", key) + fmt.Fprintf(out.writer, "%q: ", key) } - fmt.Print("{\n") + fmt.Fprint(out.writer, "{\n") out.structure = append(out.structure, JSONOutMap) case ArrayBegin: out.indent(0) if state == JSONOutMap { - fmt.Printf("%q: ", key) + fmt.Fprintf(out.writer, "%q: ", key) } - fmt.Print("[\n") + fmt.Fprint(out.writer, "[\n") out.structure = append(out.structure, JSONOutArray) case MapEnd: out.indent(-1) if state != JSONOutMap { panic("Map ended while not inside a map") } - fmt.Print("}") + fmt.Fprint(out.writer, "}") out.structure[len(out.structure) - 1] = JSONOutValueEnd case ArrayEnd: out.indent(-1) if state != JSONOutArray { panic("Array ended while not inside a array") } - fmt.Print("]") + fmt.Fprint(out.writer, "]") out.structure[len(out.structure) - 1] = JSONOutValueEnd default: panic("Invalid TerminalValue") @@ -576,27 +577,27 @@ func (out *JSONOut) atomOut(key string, atom Atom) { out.structure = out.structure[:len(out.structure) - 1] underState := out.structure[len(out.structure) - 1] if underState == JSONOutMap && atom.Typ == AtomTerminal && TerminalValue(atom.data) == MapEnd { - fmt.Print("\n") + fmt.Fprint(out.writer, "\n") out.indent(-1) - fmt.Print("}") + fmt.Fprint(out.writer, "}") out.structure[len(out.structure) - 1] = JSONOutValueEnd } else if underState == JSONOutArray && atom.Typ == AtomTerminal && TerminalValue(atom.data) == ArrayEnd { - fmt.Print("\n") + fmt.Fprint(out.writer, "\n") out.indent(-1) - fmt.Print("]") + fmt.Fprint(out.writer, "]") out.structure[len(out.structure) - 1] = JSONOutValueEnd } else if underState == JSONOutRoot { panic("Tried to output JSON after root value has concluded") } else { - fmt.Print(",\n") + fmt.Fprint(out.writer, ",\n") out.atomOut(key, atom) } case JSONOutString: if atom.Typ == AtomStringTerminal { - fmt.Print("\"") + fmt.Fprint(out.writer, "\"") out.structure[len(out.structure) - 1] = JSONOutValueEnd } else { - fmt.Print(atom.String()) + fmt.Fprint(out.writer, atom.String()) } default: panic("Invalid JSONOutState") @@ -615,14 +616,16 @@ func (out *JSONOut) Print(path Path, values []Atom) { } func (out *JSONOut) AssertDone() { + out.writer.Flush() if len(out.structure) != 2 || out.structure[0] != JSONOutRoot || out.structure[1] != JSONOutValueEnd { panic("Program ended with incomplete JSON output") } } -func NewJSONOut() JSONOut { +func NewJSONOut(writer *bufio.Writer) JSONOut { return JSONOut { structure: []JSONOutStructure{JSONOutRoot}, + writer: writer, } } -- cgit v1.2.3