mirror of
https://codeberg.org/scip/golsky.git
synced 2025-12-16 20:20:57 +01:00
Added RLE parser by N.Hoffmann and incorporated it onto my gol.
This commit is contained in:
100
rle/rle.go
Normal file
100
rle/rle.go
Normal file
@@ -0,0 +1,100 @@
|
||||
// source: https://github.com/nhoffmann/life by N.Hoffmann 2020.
|
||||
package rle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RLE struct {
|
||||
Rule string // rule
|
||||
Width int // x
|
||||
Height int // y
|
||||
Pattern [][]int // The actual pattern
|
||||
|
||||
inputLines []string
|
||||
headerLineIndex int
|
||||
patternLineIndex int
|
||||
}
|
||||
|
||||
func Parse(input string) (RLE, error) {
|
||||
rle := RLE{
|
||||
inputLines: strings.Split(input, "\n"),
|
||||
}
|
||||
|
||||
rle.partitionFile()
|
||||
|
||||
err := rle.parseComments()
|
||||
if err != nil {
|
||||
return RLE{}, err
|
||||
}
|
||||
err = rle.parseHeader()
|
||||
if err != nil {
|
||||
return RLE{}, err
|
||||
}
|
||||
err = rle.parsePattern()
|
||||
if err != nil {
|
||||
return RLE{}, err
|
||||
}
|
||||
|
||||
return rle, nil
|
||||
}
|
||||
|
||||
func (rle *RLE) partitionFile() error {
|
||||
for index, line := range rle.inputLines {
|
||||
cleanLine := removeWhitespace(line)
|
||||
if strings.HasPrefix(cleanLine, "x=") {
|
||||
rle.headerLineIndex = index
|
||||
rle.patternLineIndex = index + 1
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Invlaid input: Header is missing")
|
||||
}
|
||||
|
||||
func (rle *RLE) parseComments() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rle *RLE) parseHeader() (err error) {
|
||||
headerLine := removeWhitespace(rle.inputLines[rle.headerLineIndex])
|
||||
|
||||
headerElements := strings.SplitN(headerLine, ",", 3)
|
||||
|
||||
rle.Width, err = strconv.Atoi(strings.TrimPrefix(headerElements[0], "x="))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rle.Height, err = strconv.Atoi(strings.TrimPrefix(headerElements[1], "y="))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rle.Pattern = make([][]int, rle.Width)
|
||||
|
||||
// check wehter a rule is present, since it's optional
|
||||
if len(headerElements) == 3 {
|
||||
rle.Rule = strings.TrimPrefix(headerElements[2], "rule=")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rle *RLE) parsePattern() error {
|
||||
patternString := strings.Join(rle.inputLines[rle.patternLineIndex:], "")
|
||||
|
||||
l := NewLexer(patternString)
|
||||
pp := NewParser(l)
|
||||
|
||||
rle.Pattern = pp.ParsePattern(rle.Width, rle.Height)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeWhitespace(input string) string {
|
||||
re := regexp.MustCompile(` *\t*\r*\n*`)
|
||||
return re.ReplaceAllString(input, "")
|
||||
}
|
||||
Reference in New Issue
Block a user