diff --git a/internal/rosa/azalea/azalea.go b/internal/rosa/azalea/azalea.go index bd24ef4e..bb7bc8e1 100644 --- a/internal/rosa/azalea/azalea.go +++ b/internal/rosa/azalea/azalea.go @@ -4,8 +4,11 @@ package azalea import ( "errors" + "fmt" "io" + "os" "strconv" + "strings" "text/scanner" ) @@ -302,6 +305,7 @@ func (ScanError) Error() string { // Parse parses expressions from r. func Parse(r io.Reader) (e []any, err error) { + r, err = insertSemicolons(r) var p parser p.s.Init(r) @@ -311,12 +315,7 @@ func Parse(r io.Reader) (e []any, err error) { scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments - p.s.IsIdentRune = func(ch rune, i int) bool { - if i == 0 && ch >= '0' && ch <= '9' { - return false - } - return ch > 0 && ch < rune(len(idents)) && idents[ch] - } + p.s.IsIdentRune = isIdentRune defer func() { v := recover() @@ -346,3 +345,89 @@ func Parse(r io.Reader) (e []any, err error) { } return } +func isIdentRune(ch rune, i int) bool { + if i == 0 && ch >= '0' && ch <= '9' { + return false + } + return ch > 0 && ch < rune(len(idents)) && idents[ch] +} +func insertSemicolons(r io.Reader) (io.Reader, error) { + var s scanner.Scanner + s.Init(r) + s.Mode = scanner.ScanIdents | + scanner.ScanInts | + scanner.ScanStrings | + scanner.ScanRawStrings | + scanner.ScanComments | + scanner.SkipComments + s.Whitespace = 0 + s.IsIdentRune = isIdentRune + + var buf strings.Builder + nlsemi := false + nlcomma := false + b := "" + + tok := s.Scan() + for tok != scanner.EOF { + switch tok { + case '\n': + if b[len(b)-1] == '{' && nlsemi { + buf.WriteRune(';') + nlsemi = false + } + if b[len(b)-1] == '[' && nlcomma { + buf.WriteRune(',') + nlcomma = false + } + case ';': + buf.WriteRune(tok) + nlsemi = false + case ',': + buf.WriteRune(tok) + nlcomma = false + case '{', '[': + nlsemi = false + buf.WriteRune(tok) + b += string(tok) + case '}', ']': + if len(b) > 0 && b[len(b)-1] == '{' && nlsemi { + buf.WriteRune(';') + nlsemi = false + } + if len(b) > 0 && b[len(b)-1] == '[' && nlcomma { + buf.WriteRune(',') + nlcomma = false + } + if len(b) > 1 && b[len(b)-1] == '{' { + nlsemi = true + } + if len(b) > 1 && b[len(b)-1] == '[' { + nlcomma = true + nlsemi = true + } + + if len(b) > 1 { + b = b[:len(b)-1] + } + buf.WriteRune(tok) + case '+', ':', '=': + buf.WriteRune(tok) + nlsemi = false + nlcomma = false + case scanner.String, scanner.RawString, scanner.Int, scanner.Ident: + buf.WriteString(s.TokenText()) + if len(b) > 0 && b[len(b)-1] == '{' { + nlsemi = true + } else if len(b) > 0 && b[len(b)-1] == '[' { + nlcomma = true + } + default: + buf.WriteString(s.TokenText()) + } + + tok = s.Scan() + } + fmt.Fprintln(os.Stderr, buf.String()) + return strings.NewReader(buf.String()), nil +} diff --git a/internal/rosa/azalea/testdata/gcc.az b/internal/rosa/azalea/testdata/gcc.az index c1dc8f2b..65c2452d 100644 --- a/internal/rosa/azalea/testdata/gcc.az +++ b/internal/rosa/azalea/testdata/gcc.az @@ -1,19 +1,19 @@ package gcc { - description = "The GNU Compiler Collection"; - website = "https://www.gnu.org/software/gcc"; - anitya = 6502; + description = "The GNU Compiler Collection" + website = "https://www.gnu.org/software/gcc" + anitya = 6502 - version# = "16.1.0"; + version# = "16.1.0" source = remoteTar { url = "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+ - "gcc-"+version+"/gcc-"+version+".tar.gz"; - checksum = "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K"; - compress = gzip; - }; + "gcc-"+version+"/gcc-"+version+".tar.gz" + checksum = "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K" + compress = gzip + } patches = [ - "musl-off64_t-loff_t.patch", - "musl-legacy-lfs.patch", - ]; + "musl-off64_t-loff_t.patch" + "musl-legacy-lfs.patch" + ] // GCC spends most of its time in its many configure scripts, however // it also saturates the CPU for a consequential amount of time. @@ -21,37 +21,37 @@ package gcc { exec = make { configure = { - "disable-multilib"; - "enable-default-pie"; - "disable-nls"; - "with-gnu-as"; - "with-gnu-ld"; - "with-system-zlib"; - "enable-languages": "c,c++,go"; - "with-native-system-header-dir": "/system/include"; + "disable-multilib" + "enable-default-pie" + "disable-nls" + "with-gnu-as" + "with-gnu-ld" + "with-system-zlib" + "enable-languages": "c,c++,go" + "with-native-system-header-dir": "/system/include" "with-multilib-list": arch { - amd64, arm64 = "''"; - default = unset; - }; - }; + amd64, arm64 = "''" + default = unset + } + } make = [ - "BOOT_CFLAGS='-O2 -g'", - noop { key = value; } + "\x00", - "bootstrap", - ]; + "BOOT_CFLAGS='-O2 -g'" + noop { key = value } + "\x00" + "bootstrap" + ] // This toolchain is hacked to pieces, it is not expected to ever work // well in its current state. That does not matter as long as the // toolchain it produces passes its own test suite. - skip-check = true; - }; + skip-check = true + } inputs = [ - binutils, + binutils - mpc, - zlib, - libucontext, - kernel-headers, - ]; + mpc + zlib + libucontext + kernel-headers + ] }