internal/rosa/azalea: simplified delimiter insertion function

This commit is contained in:
2026-08-08 11:58:30 -05:00
parent aaabe8851c
commit a81e2f251c
+33 -67
View File
@@ -303,7 +303,7 @@ func (ScanError) Error() string {
// Parse parses expressions from r. // Parse parses expressions from r.
func Parse(r io.Reader) (e []any, err error) { func Parse(r io.Reader) (e []any, err error) {
r, err = insertSemicolons(r) r, err = insertDelimiters(r)
var p parser var p parser
p.s.Init(r) p.s.Init(r)
@@ -349,7 +349,7 @@ func isIdentRune(ch rune, i int) bool {
} }
return ch > 0 && ch < rune(len(idents)) && idents[ch] return ch > 0 && ch < rune(len(idents)) && idents[ch]
} }
func insertSemicolons(r io.Reader) (io.Reader, error) { func insertDelimiters(r io.Reader) (io.Reader, error) {
var s scanner.Scanner var s scanner.Scanner
s.Init(r) s.Init(r)
s.Mode = scanner.ScanIdents | s.Mode = scanner.ScanIdents |
@@ -362,94 +362,60 @@ func insertSemicolons(r io.Reader) (io.Reader, error) {
s.IsIdentRune = isIdentRune s.IsIdentRune = isIdentRune
var buf strings.Builder var buf strings.Builder
nlsemi := false nldelim := false
nlcomma := false b := new(runeStack)
b := new(RuneStack)
tok := s.Scan() for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
for tok != scanner.EOF {
switch tok { switch tok {
case '\n':
if b.Peek() == '{' && nlsemi {
buf.WriteRune(';')
nlsemi = false
}
if b.Peek() == '[' && nlcomma {
buf.WriteRune(',')
nlcomma = false
}
case ';':
buf.WriteRune(tok)
nlsemi = false
case ',':
buf.WriteRune(tok)
nlcomma = false
case '{', '[': case '{', '[':
nlsemi = false nldelim = false
nlcomma = false if tok == '{' {
buf.WriteRune(tok) b.Push(';')
b.Push(tok) } else {
case '}', ']': b.Push(',')
r := b.Pop()
if r == '{' {
if nlsemi {
buf.WriteRune(';')
}
nlcomma = true
nlsemi = true
}
if r == '[' {
if nlcomma {
buf.WriteRune(',')
}
nlsemi = true
} }
buf.WriteRune(tok) buf.WriteRune(tok)
case '+', ':', '=':
buf.WriteRune(tok)
nlsemi = false
nlcomma = false
case scanner.String, scanner.RawString, scanner.Int, scanner.Ident: case scanner.String, scanner.RawString, scanner.Int, scanner.Ident:
buf.WriteString(s.TokenText()) buf.WriteString(s.TokenText())
if b.Peek() == '{' { nldelim = true
nlsemi = true case '+', ':', '=', ',', ';':
} else if b.Peek() == '[' { nldelim = false
nlcomma = true buf.WriteRune(tok)
case '\n':
if nldelim {
buf.WriteRune(b.Peek())
nldelim = false
} }
buf.WriteRune(tok)
case '}', ']':
if nldelim {
buf.WriteRune(b.Peek())
}
b.Pop()
nldelim = true
buf.WriteRune(tok)
default: default:
buf.WriteString(s.TokenText()) buf.WriteRune(tok)
} }
tok = s.Scan()
} }
return strings.NewReader(buf.String()), nil return strings.NewReader(buf.String()), nil
} }
type Stack[T any] interface { type runeStack struct {
Push(T)
Pop() T
Peek() T
Length() int
}
type RuneStack struct {
arr []rune arr []rune
Stack[rune]
} }
func (s *RuneStack) Push(r rune) { func (s *runeStack) Push(r rune) {
s.arr = append(s.arr, r) s.arr = append(s.arr, r)
} }
func (s *RuneStack) String() string { func (s *runeStack) Peek() rune {
return string(s.arr)
}
func (s *RuneStack) Peek() rune {
if s.Length() > 0 { if s.Length() > 0 {
return s.arr[s.Length()-1] return s.arr[s.Length()-1]
} }
return 0 return '\n'
} }
func (s *RuneStack) Pop() rune { func (s *runeStack) Pop() rune {
v := s.Peek() v := s.Peek()
if s.Length() > 1 { if s.Length() > 1 {
s.arr = s.arr[:s.Length()-1] s.arr = s.arr[:s.Length()-1]
@@ -458,6 +424,6 @@ func (s *RuneStack) Pop() rune {
} }
return v return v
} }
func (s *RuneStack) Length() int { func (s *runeStack) Length() int {
return len(s.arr) return len(s.arr)
} }