diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-25 13:55:26 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-25 13:55:26 +0100 | 
| commit | 6a4e25b1c691846185e9dd698c1558981089738c (patch) | |
| tree | 7a5031ae4a8d21b48836f98f7fe7629d276df0ac | |
| parent | a28312895aecd8643c1705c0a316d1b99107dc0d (diff) | |
| download | stred-go-6a4e25b1c691846185e9dd698c1558981089738c.tar | |
Refactor Atom and Value code out of walk.go and into separate files
| -rw-r--r-- | walk/atom.go | 95 | ||||
| -rw-r--r-- | walk/value.go | 78 | ||||
| -rw-r--r-- | walk/walk.go | 186 | 
3 files changed, 185 insertions, 174 deletions
| diff --git a/walk/atom.go b/walk/atom.go new file mode 100644 index 0000000..13ad2ff --- /dev/null +++ b/walk/atom.go @@ -0,0 +1,95 @@ +package walk + +import ( +	"math" +	"fmt" +) + +type AtomType int64 +const ( +	AtomNull AtomType = iota +	AtomBool +	AtomNumber +	AtomTerminal +	AtomStringTerminal +	AtomStringRune +) +type Atom struct { +	Typ AtomType +	data uint64 +} +func NewAtomNull() Atom { +	return Atom { +		Typ: AtomNull, +		data: 0, +	} +} +func NewAtomBool(v bool) Atom { +	if v { +		return Atom { +			Typ: AtomBool, +			data: 1, +		} +	} else { +		return Atom { +			Typ: AtomBool, +			data: 0, +		} +	} +} +func NewAtomNumber(v float64) Atom { +	return Atom { +		Typ: AtomNumber, +		data: math.Float64bits(v), +	} +} +func NewAtomTerminal(v ValueTerminal) Atom { +	return Atom { +		Typ: AtomTerminal, +		data: uint64(v), +	} +} +func NewAtomStringTerminal() Atom { +	return Atom { +		Typ: AtomStringTerminal, +		data: 0, +	} +} +func NewAtomStringRune(v rune) Atom { +	return Atom { +		Typ: AtomStringRune, +		data: uint64(v), +	} +} +func (v Atom) String() string { +	switch v.Typ { +		case AtomNull: +			return "null" +		case AtomBool: +			if v.data == 0 { +				return "false" +			} +			return "true" +		case AtomNumber: +			return fmt.Sprintf("%v", math.Float64frombits(v.data)) +		case AtomTerminal: +			switch ValueTerminal(v.data) { +				case MapBegin: +					return "{" +				case MapEnd: +					return "}" +				case ArrayBegin: +					return "[" +				case ArrayEnd: +					return "]" +				default: +					panic("Invalid terminal atom") +			} +		case AtomStringTerminal: +			return "\"" +		case AtomStringRune: +			return string(rune(v.data)) +		default: +			panic("Invalid atom type") +	} +} diff --git a/walk/value.go b/walk/value.go new file mode 100644 index 0000000..2e2c3c9 --- /dev/null +++ b/walk/value.go @@ -0,0 +1,78 @@ +package walk + +import ( +	"fmt" +) + +type ValueTerminal int +const ( +	ArrayBegin ValueTerminal = iota +	ArrayEnd +	MapBegin +	MapEnd +) +func (value ValueTerminal) Atomise(in []Atom) []Atom { +	return append(in, NewAtomTerminal(value)) +} +func (value ValueTerminal) String() string { +	switch value { +		case ArrayBegin: +			return "[" +		case ArrayEnd: +			return "]" +		case MapBegin: +			return "{" +		case MapEnd: +			return "}" +		default: +			panic("Unknown TerminalValue") +	} +} + +type ValueNull struct {} +func (value ValueNull) Atomise(in []Atom) []Atom { +	return append(in, NewAtomNull()) +} +func (value ValueNull) String() string { +	return "null" +} + +type ValueBool bool +func (value ValueBool) Atomise(in []Atom) []Atom { +	return append(in, NewAtomBool(bool(value))) +} +func (value ValueBool) String() string { +	if value { +		return "true" +	} else { +		return "false" +	} +} + +type ValueNumber float64 +func (value ValueNumber) Atomise(in []Atom) []Atom { +	return append(in, NewAtomNumber(float64(value))) +} +func (value ValueNumber) String() string { +	v := float64(value) +	return fmt.Sprintf("%f", v) +} + +type ValueString string +func (value ValueString) Atomise(in []Atom) []Atom { +	in = append(in, NewAtomStringTerminal()) +	for _, char := range value { +		in = append(in, NewAtomStringRune(char)) +	} +	in = append(in, NewAtomStringTerminal()) +	return in +} +func (value ValueString) String() string { +	return fmt.Sprintf("\"%s\"", string(value)) +} + +type Value interface { +	// Append this values atoms to the input +	Atomise(in []Atom) []Atom +	String() string +} diff --git a/walk/walk.go b/walk/walk.go index 493bc46..20eac38 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -15,8 +15,8 @@ func stringPathSegment(segment PathSegment) string {  	return fmt.Sprintf("%v", segment)  }  type Path []PathSegment -func (path Path) ToWalkValues() []WalkValue { -	var values []WalkValue +func (path Path) ToWalkValues() []Value { +	var values []Value  	for _, segment := range path {  		switch s := segment.(type) {  			case int: @@ -30,7 +30,7 @@ func (path Path) ToWalkValues() []WalkValue {  	return values  } -func PathFromWalkValues(values []WalkValue) Path { +func PathFromWalkValues(values []Value) Path {  	var segments []PathSegment  	for _, value := range values {  		switch v := value.(type) { @@ -45,168 +45,6 @@ func PathFromWalkValues(values []WalkValue) Path {  	return segments  } -type TerminalValue int -const ( -	ArrayBegin TerminalValue = iota -	ArrayEnd -	MapBegin -	MapEnd -) -func (value TerminalValue) Atomise(in []Atom) []Atom { -	return append(in, NewAtomTerminal(value)) -} -func (value TerminalValue) String() string { -	switch value { -		case ArrayBegin: -			return "[" -		case ArrayEnd: -			return "]" -		case MapBegin: -			return "{" -		case MapEnd: -			return "}" -		default: -			panic("Unknown TerminalValue") -	} -} - -type ValueNull struct {} -func (value ValueNull) Atomise(in []Atom) []Atom { -	return append(in, NewAtomNull()) -} -func (value ValueNull) String() string { -	return "null" -} - -type ValueBool bool -func (value ValueBool) Atomise(in []Atom) []Atom { -	return append(in, NewAtomBool(bool(value))) -} -func (value ValueBool) String() string { -	if value { -		return "true" -	} else { -		return "false" -	} -} - -type ValueNumber float64 -func (value ValueNumber) Atomise(in []Atom) []Atom { -	return append(in, NewAtomNumber(float64(value))) -} -func (value ValueNumber) String() string { -	v := float64(value) -	return fmt.Sprintf("%f", v) -} - -type ValueString string -func (value ValueString) Atomise(in []Atom) []Atom { -	in = append(in, NewAtomStringTerminal()) -	for _, char := range value { -		in = append(in, NewAtomStringRune(char)) -	} -	in = append(in, NewAtomStringTerminal()) -	return in -} -func (value ValueString) String() string { -	return fmt.Sprintf("\"%s\"", string(value)) -} - -type AtomType int64 -const ( -	AtomNull AtomType = iota -	AtomBool -	AtomNumber -	AtomTerminal -	AtomStringTerminal -	AtomStringRune -) -type Atom struct { -	Typ AtomType -	data uint64 -} -func NewAtomNull() Atom { -	return Atom { -		Typ: AtomNull, -		data: 0, -	} -} -func NewAtomBool(v bool) Atom { -	if v { -		return Atom { -			Typ: AtomBool, -			data: 1, -		} -	} else { -		return Atom { -			Typ: AtomBool, -			data: 0, -		} -	} -} -func NewAtomNumber(v float64) Atom { -	return Atom { -		Typ: AtomNumber, -		data: math.Float64bits(v), -	} -} -func NewAtomTerminal(v TerminalValue) Atom { -	return Atom { -		Typ: AtomTerminal, -		data: uint64(v), -	} -} -func NewAtomStringTerminal() Atom { -	return Atom { -		Typ: AtomStringTerminal, -		data: 0, -	} -} -func NewAtomStringRune(v rune) Atom { -	return Atom { -		Typ: AtomStringRune, -		data: uint64(v), -	} -} -func (v Atom) String() string { -	switch v.Typ { -		case AtomNull: -			return "null" -		case AtomBool: -			if v.data == 0 { -				return "false" -			} -			return "true" -		case AtomNumber: -			return fmt.Sprintf("%v", math.Float64frombits(v.data)) -		case AtomTerminal: -			switch TerminalValue(v.data) { -				case MapBegin: -					return "{" -				case MapEnd: -					return "}" -				case ArrayBegin: -					return "[" -				case ArrayEnd: -					return "]" -				default: -					panic("Invalid terminal atom") -			} -		case AtomStringTerminal: -			return "\"" -		case AtomStringRune: -			return string(rune(v.data)) -		default: -			panic("Invalid atom type") -	} -} - -type WalkValue interface { -	// Append this values atoms to the input -	Atomise(in []Atom) []Atom -	String() string -} -  type WalkItem struct {  	Value []Atom  	Path []Atom @@ -527,7 +365,7 @@ func (out *JSONOut) atomOut(key string, atom Atom) {  					fmt.Fprint(out.writer, "\"")  					out.structure = append(out.structure, JSONOutString)  				case AtomTerminal: -					switch TerminalValue(atom.data) { +					switch ValueTerminal(atom.data) {  						case MapBegin:  							out.indent(0)  							if state == JSONOutMap { @@ -565,12 +403,12 @@ func (out *JSONOut) atomOut(key string, atom Atom) {  		case JSONOutValueEnd:  			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 { +			if underState == JSONOutMap && atom.Typ == AtomTerminal && ValueTerminal(atom.data) == MapEnd {  				fmt.Fprint(out.writer, "\n")  				out.indent(-1)  				fmt.Fprint(out.writer, "}")  				out.structure[len(out.structure) - 1] = JSONOutValueEnd -			} else if underState == JSONOutArray && atom.Typ == AtomTerminal && TerminalValue(atom.data) == ArrayEnd { +			} else if underState == JSONOutArray && atom.Typ == AtomTerminal && ValueTerminal(atom.data) == ArrayEnd {  				fmt.Fprint(out.writer, "\n")  				out.indent(-1)  				fmt.Fprint(out.writer, "]") @@ -625,11 +463,11 @@ func ConcatData(first []Atom, second []Atom) []Atom {  	return res  } -func Atomise(in []WalkValue) (out []Atom) { +func Atomise(in []Value) (out []Atom) {  	numAtoms := 0  	for _, value := range in {  		switch v := value.(type) { -			case TerminalValue, ValueNull, ValueBool, ValueNumber: +			case ValueTerminal, ValueNull, ValueBool, ValueNumber:  				numAtoms++  			case ValueString:  				numAtoms += utf8.RuneCountInString(string(v)) + 2 @@ -669,11 +507,11 @@ func (err CompoundError) Error() string {  }  type CompoundResult struct { -	value WalkValue +	value Value  	error error  } -func Compound(in []Atom) (out []WalkValue, error error) { +func Compound(in []Atom) (out []Value, error error) {  	numValues := 0  	i := 0  	inString := false @@ -691,7 +529,7 @@ func Compound(in []Atom) (out []WalkValue, error error) {  		}  	}  	i = 0 -	out = make([]WalkValue, 0, numValues) +	out = make([]Value, 0, numValues)  	for {  		if i >= len(in) {  			break @@ -709,7 +547,7 @@ func Compound(in []Atom) (out []WalkValue, error error) {  				out = append(out, ValueNumber(math.Float64frombits(atom.data)))  				continue  			case AtomTerminal: -				out = append(out, TerminalValue(atom.data)) +				out = append(out, ValueTerminal(atom.data))  				continue  			case AtomStringRune:  				return nil, CompoundRuneOutsideString | 
