54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
|
package tss
|
||
|
|
||
|
import "fmt"
|
||
|
import "errors"
|
||
|
|
||
|
// Flatten evaluates all variables recursively, thereby eliminating all
|
||
|
// instances of ValueVariable.
|
||
|
func (this *Sheet) Flatten () error {
|
||
|
if this.flat { return nil }
|
||
|
this.flat = true
|
||
|
|
||
|
for name, variable := range this.Variables {
|
||
|
variable, err := this.eval(variable)
|
||
|
if err != nil { return err }
|
||
|
this.Variables[name] = variable
|
||
|
}
|
||
|
|
||
|
for index, rule := range this.Rules {
|
||
|
for name, attr := range rule.Attrs {
|
||
|
for index, list := range attr {
|
||
|
list, err := this.eval(list)
|
||
|
if err != nil { return err }
|
||
|
attr[index] = list
|
||
|
}
|
||
|
rule.Attrs[name] = attr
|
||
|
}
|
||
|
this.Rules[index] = rule
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (this *Sheet) eval (source ValueList) (ValueList, error) {
|
||
|
destination := make(ValueList, 0, len(source))
|
||
|
for _, value := range source {
|
||
|
if name, ok := value.(ValueVariable); ok {
|
||
|
variable, ok := this.Variables[string(name)]
|
||
|
if !ok {
|
||
|
return nil, errors.New(fmt.Sprintf(
|
||
|
"variable $%s does not exist",
|
||
|
value))
|
||
|
}
|
||
|
variable, err := this.eval(variable)
|
||
|
if err != nil { return nil, err }
|
||
|
destination = append(destination, variable...)
|
||
|
continue
|
||
|
} else {
|
||
|
destination = append(destination, value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return destination, nil
|
||
|
}
|