From 77e9fefdbd70ad9bb351bf4b230d84c181d93156 Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Sun, 26 Feb 2023 10:04:53 +0000 Subject: Adds syntax to recognise and deal with starting and ending arrays, maps and strings --- subex/parse.go | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/subex/parse.go b/subex/parse.go index 0c79dc3..db07567 100644 --- a/subex/parse.go +++ b/subex/parse.go @@ -5,6 +5,8 @@ import ( ) func parseReplacement(l *RuneReader) (output []TransducerOutput) { + // TODO escaping + // TODO refactor all the terminator stuff @, #, ~ loop: for { r := l.next() switch r { @@ -18,6 +20,33 @@ func parseReplacement(l *RuneReader) (output []TransducerOutput) { panic("Missing slot character") } output = append(output, TransducerReplacementLoad{datum: slot}) + case '@': + terminal := l.next() + if terminal == '(' { + output = append(output, TransducerReplacementRune{datum: walk.ArrayBegin}) + } else if terminal == ')' { + output = append(output, TransducerReplacementRune{datum: walk.ArrayEnd}) + } else { + panic("Expected ( or ) after @") + } + case '~': + terminal := l.next() + if terminal == '(' { + output = append(output, TransducerReplacementRune{datum: walk.StartString{}}) + } else if terminal == ')' { + output = append(output, TransducerReplacementRune{datum: walk.EndString{}}) + } else { + panic("Expected ( or ) after ~") + } + case '#': + terminal := l.next() + if terminal == '(' { + output = append(output, TransducerReplacementRune{datum: walk.MapBegin}) + } else if terminal == ')' { + output = append(output, TransducerReplacementRune{datum: walk.MapEnd}) + } else { + panic("Expected ( or ) after #") + } default: output = append(output, TransducerReplacementRune{datum: r}) } @@ -27,6 +56,7 @@ func parseReplacement(l *RuneReader) (output []TransducerOutput) { // Parse the contents of a range subex [] into a map func parseRangeSubex(l *RuneReader) map[walk.Datum]walk.Datum { + // TODO escaping parts := make(map[walk.Datum]walk.Datum) var froms []walk.Datum var hasTo bool @@ -38,6 +68,39 @@ func parseRangeSubex(l *RuneReader) map[walk.Datum]walk.Datum { } else if fromsStart == '=' { hasTo = true break + } else if fromsStart == '@' { + terminal := l.next() + if terminal == '(' { + froms = append(froms, walk.ArrayBegin) + continue + } else if terminal == ')' { + froms = append(froms, walk.ArrayEnd) + continue + } else { + panic("Expected ( or ) after @") + } + } else if fromsStart == '#' { + terminal := l.next() + if terminal == '(' { + froms = append(froms, walk.MapBegin) + continue + } else if terminal == ')' { + froms = append(froms, walk.MapEnd) + continue + } else { + panic("Expected ( or ) after #") + } + } else if fromsStart == '~' { + terminal := l.next() + if terminal == '(' { + froms = append(froms, walk.StartString{}) + continue + } else if terminal == ')' { + froms = append(froms, walk.EndString{}) + continue + } else { + panic("Expected ( or ) after ~") + } } if l.accept("-") { fromsEnd := l.next() @@ -62,6 +125,39 @@ func parseRangeSubex(l *RuneReader) map[walk.Datum]walk.Datum { tosStart := l.next() if tosStart == ']' { break + } else if tosStart == '@' { + terminal := l.next() + if terminal == '(' { + tos = append(tos, walk.ArrayBegin) + continue + } else if terminal == ')' { + tos = append(tos, walk.ArrayEnd) + continue + } else { + panic("Expected ( or ) after @") + } + } else if tosStart == '#' { + terminal := l.next() + if terminal == '(' { + tos = append(tos, walk.MapBegin) + continue + } else if terminal == ')' { + tos = append(tos, walk.MapEnd) + continue + } else { + panic("Expected ( or ) after #") + } + } else if tosStart == '~' { + terminal := l.next() + if terminal == '(' { + tos = append(tos, walk.StartString{}) + continue + } else if terminal == ')' { + tos = append(tos, walk.EndString{}) + continue + } else { + panic("Expected ( or ) after ~") + } } if l.accept("-") { tosEnd := l.next() @@ -124,6 +220,33 @@ func parseSubex(l *RuneReader, minPower int) SubexAST { lhs = SubexASTOutput{replacement} case '.': lhs = SubexASTCopyAny{} + case '@': + terminal := l.next() + if terminal == '(' { + lhs = SubexASTCopyRune{datum: walk.ArrayBegin} + } else if terminal == ')' { + lhs = SubexASTCopyRune{datum: walk.ArrayEnd} + } else { + panic("Expected ( or ) after @") + } + case '~': + terminal := l.next() + if terminal == '(' { + lhs = SubexASTCopyRune{datum: walk.StartString{}} + } else if terminal == ')' { + lhs = SubexASTCopyRune{datum: walk.EndString{}} + } else { + panic("Expected ( or ) after ~") + } + case '#': + terminal := l.next() + if terminal == '(' { + lhs = SubexASTCopyRune{datum: walk.MapBegin} + } else if terminal == ')' { + lhs = SubexASTCopyRune{datum: walk.MapEnd} + } else { + panic("Expected ( or ) after #") + } default: lhs = SubexASTCopyRune{datum: r} } -- cgit v1.2.3